如何在 Spring Security Webflux 中自定义默认的未授权响应正文?

问题描述 投票:0回答:2

我正在使用 Spring boot Webflux 启动一个新项目,但现在我不知道如何处理 401 响应。

我想返回带有响应代码的消息正文。响应代码正常并且按预期工作。现在,我如何注入消息正文以提供更详细和描述性的响应,如下所示。

{
    "statusCode": "401",
    "statusMessage": "Unauthorized",
    "timestamp": "Sun May 07 10:30:23 GMT 2023"
}

这是我的 spring 安全配置类的一部分:

@Bean
public SecurityWebFilterChain securityFilterChain(ServerHttpSecurity http) {
    return http
            .cors().and()
            .csrf().disable()
            //Disable Sessions
            .securityContextRepository(NoOpServerSecurityContextRepository.getInstance())
            // handlers for 401 to return a 401 status, message and timestamp

            //rest services don't have a login form
            .formLogin()
            .disable()
            .authorizeExchange()
            .pathMatchers("/api/v1/get-token").hasRole("API")
            .and()
            .httpBasic()
            .and()
            .build();
}

一切正常,我只想返回消息正文 JSON,而不仅仅是 HTTP 响应代码。有人吗?

spring-boot spring-security spring-webflux
2个回答
2
投票

提供一种使用

security
提供的入口点的解决方案。相应的代码片段如下。

1.自定义入口点

public class CustomAuthenticationEntryPoint implements ServerAuthenticationEntryPoint {

    @Override
    public Mono<Void> commence(ServerWebExchange exchange, AuthenticationException authException) {
        // Custom error message or response body
        String errorMessage = "Unauthorized. Please authenticate.";

        // Set the status code and response body
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        exchange.getResponse().getHeaders().add("Content-Type", "application/json");
        return exchange.getResponse().writeWith(Mono.just(exchange.getResponse().bufferFactory()
                .wrap(errorMessage.getBytes())));
    }
}
  1. 注册入口点
@Configuration
@EnableWebFluxSecurity
public class SecurityConfig {

    private final CustomAuthenticationEntryPoint authenticationEntryPoint;

    @Autowired
    public SecurityConfig(CustomAuthenticationEntryPoint authenticationEntryPoint) {
        this.authenticationEntryPoint = authenticationEntryPoint;
    }

    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
        return http
                .exceptionHandling()
                .authenticationEntryPoint(authenticationEntryPoint)
                .and()
                // Configure other security rules
                .build();
    }
}

2
投票

您还可以使用全局异常处理来拦截

AuthenticationException
并返回您的自定义响应:

@ControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(AuthenticationException.class)
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public CustomResponse handleAuthenticationException(AuthenticationException ex) {
        // Your custom response
        CustomResponse response = ...
        return response;
    }
}

您还可以从处理程序返回

ResponseEntity<CustomResponse>
,以便您可以根据需要自定义响应标头

© www.soinside.com 2019 - 2024. All rights reserved.