[解決済み] Springのセキュリティ認証の例外を@ExceptionHandlerで処理する
質問
私はSpring MVCの
@ControllerAdvice
と
@ExceptionHandler
で、REST Api のすべての例外を処理します。web mvc のコントローラからスローされる例外については問題なく動作しますが、 Spring security のカスタムフィルタからスローされる例外については、コントローラのメソッドが呼び出される前に実行されるため、動作しません。
私はトークンベースの認証を行うカスタムSpring Securityフィルターを持っています。
public class AegisAuthenticationFilter extends GenericFilterBean {
...
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
try {
...
} catch(AuthenticationException authenticationException) {
SecurityContextHolder.clearContext();
authenticationEntryPoint.commence(request, response, authenticationException);
}
}
}
このカスタムエントリーポイントで
@Component("restAuthenticationEntryPoint")
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint{
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authenticationException) throws IOException, ServletException {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, authenticationException.getMessage());
}
}
そして、このクラスでグローバルに例外を処理する。
@ControllerAdvice
public class RestEntityResponseExceptionHandler extends ResponseEntityExceptionHandler {
@ExceptionHandler({ InvalidTokenException.class, AuthenticationException.class })
@ResponseStatus(value = HttpStatus.UNAUTHORIZED)
@ResponseBody
public RestError handleAuthenticationException(Exception ex) {
int errorCode = AegisErrorCode.GenericAuthenticationError;
if(ex instanceof AegisException) {
errorCode = ((AegisException)ex).getCode();
}
RestError re = new RestError(
HttpStatus.UNAUTHORIZED,
errorCode,
"...",
ex.getMessage());
return re;
}
}
spring securityのAuthenticationExceptionでも詳細なJSONボディを返したいのですが、どうすればいいでしょうか?spring securityのAuthenticationEntryPointとspring mvcの@ExceptionHandlerを連携させる方法はないでしょうか?
spring security 3.1.4とspring mvc 3.2.4を使っています。
どのように解決するのですか?
OK、私は提案されたようにAuthenticationEntryPointから自分でjsonを書くことを試みました、それは動作します。
テストのために、私はAutenticationEntryPointをresponse.sendErrorを削除して変更しました。
@Component("restAuthenticationEntryPoint")
public class RestAuthenticationEntryPoint implements AuthenticationEntryPoint{
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authenticationException) throws IOException, ServletException {
response.setContentType("application/json");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getOutputStream().println("{ \"error\": \"" + authenticationException.getMessage() + "\" }");
}
}
このようにすると、Spring Security AuthenticationEntryPointを使用している場合でも、401の無承認と一緒にカスタムjsonデータを送信することができます。
もちろん、テスト用に私が行ったようにjsonをビルドするのではなく、何らかのクラスインスタンスをシリアライズすることになるでしょう。
Spring Bootでは、SecurityConfigurationファイルのhttp.authenticationEntryPoint()の部分に追加する必要があります。
関連
-
[解決済み】Spring SecurityのRoleとGrantedAuthorityの違いについて
-
[解決済み] クラスを@Componentでアノテートした場合、Spring BeanとSingletonということになるのでしょうか?
-
[解決済み] Spring Data JPAでネイティブクエリ結果をNon-Entity POJOにマップする。
-
[解決済み] Spring Hibernate - 現在のスレッドでトランザクションに同期したセッションを取得できませんでした。
-
[解決済み] Spring Boot - 実行中のポートを取得する方法
-
[解決済み] Spring Dataです。"delete by "はサポートされていますか?
-
[解決済み] Spring Boot JPA - 自動再接続の設定
-
[解決済み] Spring CrudRepositoryで大文字小文字を区別しないクエリ
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] クラスを@Componentでアノテートした場合、Spring BeanとSingletonということになるのでしょうか?
-
[解決済み] Spring Data JPAでネイティブクエリ結果をNon-Entity POJOにマップする。
-
[解決済み] Spring Hibernate - 現在のスレッドでトランザクションに同期したセッションを取得できませんでした。
-
[解決済み] Spring Boot - 実行中のポートを取得する方法
-
[解決済み] Spring Dataです。"delete by "はサポートされていますか?
-
[解決済み] Spring Boot JPA - 自動再接続の設定
-
[解決済み] Spring CrudRepositoryで大文字小文字を区別しないクエリ