【问题标题】:Spring Boot REST API/Spring Security: Return custom message when authentication failsSpring Boot REST API/Spring Security:身份验证失败时返回自定义消息
【发布时间】:2017-04-09 00:22:10
【问题描述】:

我有一个使用 Jersey 作为 JAX-RS 实现的 Spring Boot 应用程序。这是我的安全配置:

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired TokenAuthenticationProvider tokenAuthenticationProvider;

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(tokenAuthenticationProvider);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.addFilterBefore(new AuthenticationTokenFilter(), BasicAuthenticationFilter.class)
                .csrf().disable()
                .authorizeRequests()
                .antMatchers("/dataHub/**")
                .authenticated();
    }
}

我想要做的是有一种方法来捕获我的 TokenAuthenticationProvider 抛出的异常,并将它们转换为我们同意的标准化 JSON 格式。有没有办法做到这一点?我尝试添加自定义的 AuthenticationFailureHandler,但无法使其正常工作。

【问题讨论】:

    标签: spring rest spring-security spring-boot jersey


    【解决方案1】:

    WebSecurityConfigurerAdapter 方法

    HttpSecurity 类有一个名为exceptionHandling 的方法,可用于覆盖默认行为。以下示例展示了如何自定义响应消息。

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            // your custom configuration goes here
            .exceptionHandling()
            .authenticationEntryPoint((request, response, e) -> {
                String json = String.format("{\"message\": \"%s\"}", e.getMessage());
                response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
                response.setContentType("application/json");
                response.setCharacterEncoding("UTF-8");
                response.getWriter().write(json);                
            });
    }
    

    @ControllerAdvice appraoch - 为什么它在这种情况下不起作用

    一开始我想到了@ControllerAdvice,它可以捕获整个应用程序的身份验证异常。

    import org.springframework.http.HttpStatus;
    import org.springframework.security.core.AuthenticationException;
    
    @ControllerAdvice
    public class AuthExceptionHandler {
    
        @ResponseStatus(HttpStatus.UNAUTHORIZED)
        @ExceptionHandler(AuthenticationException.class)
        @ResponseBody
        public String handleAuthenticationException(AuthenticationException e) {
            return String.format("{\"message\": \"%s\"}", e.getMessage());
        }
    
    }
    

    在上面的示例中,JSON 是手动构建的,但您可以简单地返回一个 POJO,该 POJO 将像从常规 REST 控制器一样映射到 JSON。从 Spring 4.3 开始,您还可以使用@RestControllerAdvice,它是@ControllerAdvice@ResponseBody 的组合。

    但是,这种方法不起作用,因为在到达任何控制器之前,AbstractSecurityInterceptor 会引发异常并由ExceptionTranslationFilter 处理。

    【讨论】:

      猜你喜欢
      • 2017-03-17
      • 2019-02-07
      • 2020-12-05
      • 2019-09-22
      • 2022-08-16
      • 2015-05-13
      • 2021-04-21
      • 2012-08-15
      • 2015-12-18
      相关资源
      最近更新 更多