2016-08-24 73 views
3

我想在我们的REST Api上实现令牌认证,目前我指的是article。在本文中,它讨论了使用JWT创建令牌的问题,但是我目前的问题是,每次将无效令牌传递给我的应用程序时,都会创建一个异常,这是JwtException.class,我想捕获该异常使用我的全局异常处理程序类。我也尝试在我的应用程序的异常类上包装JwtException,但无法捕获异常。在Spring MVC中处理JWT异常

@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); 
    } 
} 

回答

2

你GlobalExceptionHandler并非真正全球性的,它只会赶上发生在你的控制器(因此ControllerAdvice)例外,你正在运行到Servlet过滤器是发生的例外,这是在春季安全呢几乎所有的工作。这个小图表可能有助于解释什么,我说什么:

预过滤器< - 进入控制器之前执行,智威汤逊的解密发生在这里

控制器< - ControllerAdvice会赶上这里

后过滤抛出的所有异常< - 退出控制器后执行

幸运的是,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) 
      } 
     } 
    } 
+0

我试着添加ExceptionTranslationFilter,但仍然有相同的问题。 – anathema

+0

@anathema,对不起,我忘了添加解密你的JWT时,如果你得到一个异常,你需要重新抛出异常作为AuthenticationException(因为这是ExceptionTranslationFilter正在寻找什么)。我更新了我的答案以表明这一点。 –

+0

我应用了您在编辑中声明的更改,但它不是由我的REST API返回401状态,而是由于引发了身份验证异常而导致错误500。对此我创建了一个新问题。请参阅http://stackoverflow.com/questions/39207743/handling-filter-thrown-exceptions-in-spring。谢谢 – anathema