2016-08-24 23 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)あなたのコントローラで発生した例外をキャッチしますかなりのすべての仕事。この小さなグラフは私が何を言っているか説明するのに役立つことがあります。

プレフィルター< - あなたのコントローラを入力する前に実行され、JWTの解読は

ここコントローラー<が起こっている - ControllerAdviceはこちら

ポストフィルタスローされるすべての例外をキャッチします< - コントローラの終了後に実行

幸運にもSpring Securityには、フィルタでJWTを復号化するときに発生する例外を処理するためのメカニズムがすでに用意されています。 SpringSecurityConfigを更新する必要があります。 StatelessAuthenticationFilter(またはJWT復号化が行われている場所にフィルタを付けた名前)の後に、ExceptionTranslationFilterがであることが重要です。

@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

関連する問題