【问题标题】:Filter or handle AuthenticationException in OAuth2在 OAuth2 中过滤或处理 AuthenticationException
【发布时间】:2019-09-27 10:19:53
【问题描述】:

我正在尝试过滤在我的应用程序中用户身份验证期间引发的 AuthenticationException。我知道这些不能用 @ControllerAdvice@ExceptionHandler 过滤。因此,试图找出任何处理程序都可以解决我的问题。

已经尝试过不同的方法,例如 AuthenticationFailureHandler,但它们不符合我的要求,因为我使用的是 ResourceServerConfigurerAdapter

请提出建议。

【问题讨论】:

    标签: java spring-security oauth oauth-2.0


    【解决方案1】:

    Spring 安全异常由ExceptionTranslationFilter 处理。您可以创建一个处理AuthenticationException 的自定义过滤器并将其添加到ExceptionTranslationFilter 之后。默认 Spring 安全 Filter Ordering.

    public class AuthenticationExceptionFilter extends GenericFilterBean {
    
        @Override
        public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
            try {
                chain.doFilter(request, response);
            } catch (final Exception exception) {
                if (exception instanceof AuthenticationException) {
                    this.logger.debug("Authentication exception occurred; redirecting to authentication entry point", exception);
                }
    
                if(exception instanceof AccessDeniedException) {
                    ....
                }
    
                // Check ExceptionTranslationFilter#handleSpringSecurityException(...)
            }
    

    您可以通过重写WebSecurityConfigurerAdapter 的配置方法以编程方式注册过滤器。

    @Configuration
    public class CustomWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.addFilterAfter(new AuthenticationExceptionFilter(), ExceptionTranslationFilter.class);
        }
    

    对于所有 @RequestMapping 的集中式异常处理: 查看ResponseEntityExceptionHandler

    @ControllerAdvice 类的方便基类 提供跨所有@RequestMapping 的集中式异常处理 方法通过@ExceptionHandler 方法。

    这个基类提供了一个@ExceptionHandler 方法来处理 内部 Spring MVC 异常。

    这里有一个示例代码 sn-p 可以帮助您入门:

    @ControllerAdvice
    public class ExceptionHandler extends ResponseEntityExceptionHandler {
    ....
    @ExceptionHandler({Exception.class})
        public ResponseEntity<Object> handleCustomException(final CustomException exception, final WebRequest request) {
    
            return handleExceptionInternal(exception,
                                           ErrorOutputDto.create(exception.getErrorIdentifier(), exception.getMessage()),
                                           new HttpHeaders(),
                                           HttpStatus.UNAUTHORIZED,
                                           request);
        }
    ....
    

    【讨论】:

    • 看起来这类似于 ControllerAdvice 不符合我在描述中提到的要求。这些处理程序仅在 RequestMapping 方法中引发异常时才起作用。但是我需要处理程序来处理在调用 RequestMapping 方法之前引发的异常,同时对用户进行身份验证,因为我将 OAuth2 用于我的应用程序安全性。
    • 你是对的。我已经编辑了我的答案。希望这会有所帮助。
    • 感谢您帮助我。但还没有运气。你确定这适用于 OAuth2 吗?因为您建议使用 Spring 安全性,我想这可能不适用于我的情况。
    • Spring Security 提供对 OAuth 2.0 的支持。调试应用程序以确定请求是否抛出您的自定义过滤器。您还可以启用这些调试标志以进行详细日志记录 logging.level.org.springframework.boot.web.servlet=DEBUG logging.level.org.springframework.security=DEBUG logging.level.org.springframework.security.oauth2=DEBUG logging.level.org.springframework.security.web=DEBUG
    • 我已经尝试了一段时间,很高兴我发现一旦身份验证失败就已经达到了这个过滤器。但是那个时候异常已经被处理了,所以它不会被 doFilter 方法中的任何 catch 块捕获。此外,我尝试使用 getOutputStream 更改响应,它抛出错误,例如 getOutputStream 已被调用此响应。
    猜你喜欢
    • 2015-01-27
    • 2018-11-08
    • 1970-01-01
    • 2021-09-13
    • 2021-06-18
    • 2023-03-22
    • 1970-01-01
    • 1970-01-01
    • 2012-06-23
    相关资源
    最近更新 更多