在 Spring MVC 中处理 JWT 异常

ana*_*ema 7 java spring spring-mvc jwt

我正在尝试在我们的 REST Api 上实现令牌身份验证,目前我指的是这篇文章。在文章中,它讨论了在创建令牌时使用了 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

Bil*_*ndo 4

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

PreFilters <- 在进入控制器之前执行,JWT 解密发生在此处

Controller <- ControllerAdvice 将捕获此处抛出的所有异常

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)
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)