2016-08-24 251 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