在 Spring MVC 中处理 JWT 异常
Posted
技术标签:
【中文标题】在 Spring MVC 中处理 JWT 异常【英文标题】:Handling JWT Exception in Spring MVC 【发布时间】: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);
【问题讨论】:
【参考方案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。我为此提出了一个新问题。请参阅***.com/questions/39207743/…。谢谢 AuthenticationException 是抽象的,无法实例化。以上是关于在 Spring MVC 中处理 JWT 异常的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring MVC 中针对 HTML 和 JSON 请求以不同方式处理异常
如何在 Spring MVC 中针对 HTML 和 JSON 请求以不同方式处理异常