I need to secure REST API implemented with Spring Boot, WebFlux and spring security using HMAC of the request body. Simplifying a bit, on a high level - request comes with the header that has hashed value of the request body, so I have to read the header, read the body, calculate hash of the body and compare with the header value.
I think I should implement ServerAuthenticationConverter but all examples I was able to find so far only looking at the request headers, not the body and I'm not sure if I could just read the body, or should I wrap/mutate the request with cached body so it could be consumed by the underlying component second time?
Is it ok to use something along the lines of:
public class HttpHmacAuthenticationConverter implements ServerAuthenticationConverter {
@Override
public Mono<Authentication> convert(ServerWebExchange exchange) {
exchange.getRequest().getBody()
.next()
.flatMap(dataBuffer -> {
try {
return Mono.just(StreamUtils.copyToString(dataBuffer.asInputStream(), StandardCharsets.UTF_8));
} catch (IOException e) {
return Mono.error(e);
}
})
...
I'm getting a warning from the IDE on the copyToString line: Inappropriate blocking method call
Any guidelines or examples?
Thanks!
I have also tried:
@Override
public Mono<Authentication> convert(ServerWebExchange exchange) {
return Mono.justOrEmpty(exchange.getRequest().getHeaders().toSingleValueMap())
.zipWith(exchange.getRequest().getBody().next()
.flatMap(dataBuffer -> Mono.just(dataBuffer.asByteBuffer().array()))
)
.flatMap(tuple -> create(tuple.getT1(), tuple.getT2()));
But that doesn't work - code in the create() method on the last line is never executed.