Spring Security 是否可以使用自定义的ServerAuthenticationEntryPoint添加响应正文?

mqxuamgl  于 2023-05-22  发布在  Spring
关注(0)|答案(2)|浏览(311)

我已经看到,在版本5.2.0.M1中,当在Reactive Stack(Webflux)上使用Spring Security的OAuth2 Resource Server时,无法自定义ServerAuthenticationEntryPoint。
(See https://github.com/spring-projects/spring-security/issues/6052
然而,当我现在试图编写自己的ServerAuthenticationEntryPoint时,我问自己如何向http响应添加主体?commence(...)方法返回一个Mono,我还没有找到一种方法在某处指定body。
有人能给予我一个提示如何做到这一点(如果可能的话)?

6tdlim6h

6tdlim6h1#

同时我找到了解决这个问题的方法。在 WebSecurityConfiguration 类中仅向 ServerHttpSecurity 配置添加lambda时,如下所示

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

我可以处理 AbstractErrorWebExceptionHandler 的自定义实现中的错误,其中我处理所有非spring安全相关的异常。这个管用我不得不从 BearerTokenServerAuthenticationEntryPoint 中复制一点逻辑,以在响应中获得适当的WWW-Authenticate头,但它现在可以很好地使用自定义主体,以防任何来自spring security的异常。

6mw9ycah

6mw9ycah2#

是的有可能
(Spring v2.7.7)我已经引用了Webflux Framework中的FormHttpMessageWriter.java类,并找到了以下解决方案,该解决方案成功地写入响应主体,而无需创建额外的异常来 Package 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));
    }
}

相关问题