Lars
Lars

Reputation: 61

Is it possilble to add a response body using a customized ServerAuthenticationEntryPoint?

I have seen that with version 5.2.0.M1 it is not possible to customize the ServerAuthenticationEntryPoint when using the OAuth2 Resource Server from Spring Security on the Reactive Stack (Webflux).

(See also https://github.com/spring-projects/spring-security/issues/6052)

However, when I was now trying to write my own ServerAuthenticationEntryPoint I was asking myself how to add a body to the http response? The commence(...) method returns a Mono and I have not found a way yet to specify the body somewhere.

Can somebody give me a hint how to do this (if it is possible)?

Upvotes: 2

Views: 1800

Answers (2)

HarryH
HarryH

Reputation: 13

Yes it is possible

(Spring v2.7.7) I've referenced the FormHttpMessageWriter.java class from the Webflux Framework and found the following solution that successfully writes to the response body without having to create additional exceptions to wrap the AuthenticationException.

public class CustomServerEntryPoint implements ServerAuthenticationEntryPoint {

    //References write() in FormHttpMessageWriter.java from Spring Webflux.
    @Override
    public Mono<Void> commence(ServerWebExchange exchange, AuthenticationException ex) {
        //You can customized/parse your message here.
        String message = ex.getMessage();

        byte[] bytes = message.getBytes(StandardCharsets.UTF_8);
        DataBuffer buffer = exchange.getResponse().bufferFactory().wrap(bytes);
        return Mono.just(message)
                .flatMap( s -> {
                    ServerHttpResponse response = exchange.getResponse();
                    response.setStatusCode(HttpStatus.UNAUTHORIZED);
                    response.getHeaders().setContentType(MediaType.TEXT_PLAIN);
                    response.getHeaders().setContentLength(buffer.asByteBuffer().remaining());
                    return response.writeWith(Mono.just(buffer));
                }).doOnSuccess( empty -> DataBufferUtils.release(buffer));
    }
}

Upvotes: 0

Lars
Lars

Reputation: 61

Meanwhile I found a way to solve this problem. When adding just a lambda to the ServerHttpSecurity configuration in the WebSecurityConfiguration class like this

http
  . ...
  .oauth2ResourceServer()
  .authenticationEntryPoint((exchange, exception) -> Mono.error(exception));

i can handle the error in my custom implementation of AbstractErrorWebExceptionHandler where I handle all non spring security related exceptions anyway. This works. I had to copy a bit of the logic from BearerTokenServerAuthenticationEntryPoint to get a proper WWW-Authenticate header in the response but it works fine now with a custom body in case of any exception coming from spring security.

Upvotes: 2

Related Questions