【问题标题】:Handling JWT Exception in Spring MVC在 Spring MVC 中处理 JWT 异常
【发布时间】:2016-12-30 23:21:10
【问题描述】:

我正在尝试在我们的 REST Api 上实现令牌身份验证,目前我指的是 article。在文章中,它讨论了在创建令牌时使用了 JWT,但我目前的问题是,每次将无效令牌传递给我的应用程序时,都会创建一个异常,即 JwtException.class,我想捕获该异常使用我的全局异常处理程序类。我还尝试将 JwtException 包装在我的应用程序的异常类上,但无济于事,异常没有被捕获。

@ControllerAdvice
public class GlobalExceptionHandler {

@ExceptionHandler(value={JwtException.class})
public ResponseEntity<?> handleTokenException(JwtException e){
    return new ResponseEntity<Object>(HttpStatus.UNAUTHORIZED);
}

@ExceptionHandler(value={InvalidAuthTokenException.class})
public ResponseEntity<?> handleTokenException(InvalidAuthTokenException e){
    return new ResponseEntity<Object>(HttpStatus.UNAUTHORIZED);
    }
}

【问题讨论】:

    标签: java spring spring-mvc jwt


    【解决方案1】:

    您的 GlobalExceptionHandler 并不是真正的全局性,它只会捕获您的控制器中发生的异常(因此 ControllerAdvice),您遇到的异常发生在 servlet 过滤器中,这就是 Spring Security几乎完成了所有的工作。这个小图表可能有助于解释我在说什么:

    PreFilters

    Controller

    PostFilters

    幸运的是,Spring Security 已经有适当的机制来处理在过滤器中解密 JWT 等操作时发生的异常。你会想要像这样更新你的 SpringSecurityConfig 。请注意,ExceptionTranslationFilter 您的 StatelessAuthenticationFilter(或您命名的 JWT 解密发生的过滤器)之后是很重要的。

        @Configuration
        @EnableWebSecurity
        @Order(2)
        public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
    
            @Override
            protected void configure(HttpSecurity http) throws Exception {
                ExceptionTranslationFilter = new ExceptionTranslationFilter(new AuthenticationExceptionHandler());
    
                http.addFilterAfter(new StatelessAuthenticationFilter(tokenAuthenticationService),
                                ExceptionTranslationFilter.class);
            }
    
    
        }
    
        public class AuthenticationExceptionHandler implements AuthenticationEntryPoint {
            public void commence(HttpServletRequest request, HttpServletResponse, AuthenticationException e) throws IOException, ServletException {
                //Logic on how to handle JWT exception goes here
            }
        }
    
        public class StatelessAuthenticationFilter extends GenericFilterBean {
            @Override
            public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
                try {
                    //DECRYPT YOUR JWT
                } catch (Exception e) {
                     throw new AuthenticationException();//If you get an exception wrap it in a AuthenticationException (or a class that extends it)
                }
            }
        }
    

    【讨论】:

    • 我尝试添加 ExceptionTranslationFilter 但仍然遇到同样的问题。
    • @anathema,抱歉我忘记在解密 JWT 时添加,如果您遇到异常,您需要将该异常作为 AuthenticationException 重新抛出(因为这是 ExceptionTranslationFilter 正在寻找的)。我更新了我的答案以显示这一点。
    • 我应用了您在编辑中声明的更改,但我的 REST API 没有返回 401 状态,而是由于抛出身份验证异常而收到错误 500。我为此提出了一个新问题。请参阅stackoverflow.com/questions/39207743/…。谢谢
    • AuthenticationException 是抽象的,无法实例化。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-20
    • 2011-10-08
    • 2013-03-09
    • 1970-01-01
    相关资源
    最近更新 更多