あなた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)
}
}
}
私はExceptionTranslationFilterを追加しようとしましたが、それでも同じ問題がありました。 – anathema
@anathema、申し訳ありませんが、例外が発生した場合、JWTを復号化するときに追加することを忘れました。あなたはその例外をAuthenticationExceptionとして再現する必要があります(ExceptionTranslationFilterが探しているものです)。私はこれを示すために私の答えを更新しました。 –
あなたが編集に記載した変更を適用しましたが、REST APIによって401ステータスが返される代わりに、認証例外をスローするためにエラー500が表示されます。私はこれに関して新しい質問を作成しました。 http://stackoverflow.com/questions/39207743/handling-filter-thrown-exceptions-in-springをご覧ください。ありがとう – anathema