2016-12-22 18 views
1

私はカスタム 'AuthenticationProvider'を実装しています。認証されていない場合は、以下のように 'authenticate'関数内で例外をスローします。AuthenticationProviderでスローされたキャッチ例外

public class DelegatingLdapAuthenticationProvider implements AuthenticationProvider { 

    private ActiveDirectoryLdapAuthenticationProvider primaryProvider; 
    private List<ActiveDirectoryLdapAuthenticationProvider> secondaryProviders = new ArrayList<>(); 

    public DelegatingLdapAuthenticationProvider() { 

    } 

    @Override 
    public Authentication authenticate(Authentication authentication) throws AuthenticationException { 
     Authentication result = null; 
     AuthenticationException exception = null; 
     try { 
      result = primaryProvider.authenticate(authentication); 
     } catch (AuthenticationException e) { 
      exception = e; 
      for (ActiveDirectoryLdapAuthenticationProvider secondaryProvider : secondaryProviders) { 
       try { 
        result = secondaryProvider.authenticate(authentication); 
        if (result.isAuthenticated()) { 
          break; 
        } 
       } catch (AuthenticationException e1) { 
          exception = e; 
       } 
      } 
     } 
     if (result == null || !result.isAuthenticated()) { 
      throw exception; 
    } 

    return result; 
} 

以下に示すようなグローバル例外ハンドラがあります。

@ControllerAdvice 
public class GlobalExceptionHandler { 

    @ExceptionHandler({NoPermissionException.class}) 
    @ResponseBody 
    @ResponseStatus(value = HttpStatus.FORBIDDEN) 
    public Map<String, String> noPermission(NoPermissionException e) { 
     return createErrorResponse(e, "Don't have permissions"); 
    } 

    @ExceptionHandler({Exception.class}) 
    @ResponseBody 
    @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) 
    public Map<String, String> exceptionInProcessing(Exception e) { 
     return createErrorResponse(e, "Unable to process. Unknown error occurred: " + e.getMessage()); 
    } 

    private Map<String, String> createErrorResponse(Exception e, String errorMessage) { 
     Map<String, String> errorResponse = new HashMap<>(); 
     errorResponse.put("message", errorMessage); 
     errorResponse.put("reason", e.toString()); 
     return errorResponse; 
    } 
} 

'authenticate'関数内で例外がスローされると、グローバル例外ハンドラは呼び出されません。他のすべての例外については、呼び出されています。グローバル例外ハンドラ内で例外をキャッチし、カスタムエラーメッセージを返したいどうやってやるの?どんな助けもありがたい。前もって感謝します。

+1

あなたが実際に例外がスローされているか、あなたのプロバイダが最初の場所で呼び出されていますか? – pvg

答えて

1

GlobalExceptionHandlerは、コントローラの例外ハンドラのためですが、AuthenticationProviderはあなたがAuthenticationExceptionをハンドラにしたい場合は、あなたがAuthenticationEntryPointを実装し、commenceメソッドをオーバーライドするためにそれを処理する必要があり、フィルタにまだあります。

public void commence(HttpServletRequest request, HttpServletResponse response, 
     AuthenticationException authException) throws IOException, ServletException 

AuthenticationExceptionAccessDeniedExceptionはすでにExceptionTranslationFilterによって処理されています。あなただけの

AccessDeniedExceptionを扱う)AuthenticationEntryPointAccessDeniedHandlerを注入する必要があるまたはあなたはフィルターでこれらの例外をキャッチして、コントローラの例外ハンドラが持って前に認証プロバイダが呼び出されAuthenticationFailureHandler

0

AbstractAuthenticationProcessingFilterでのように、ファイラーでそれを処理することができます例外をキャッチするチャンス。

あなたはdocumentationで説明したようにexamples

行動を見て、セキュリティフィルターチェーンレベルでの例外を処理するためにAuthenticationFailureHandlerを上書きすることができます。

フィルタは、各認証要求を処理するように構成さAuthenticationManager呼び出します。成功した認証または認証失敗に続く宛先は、それぞれAuthenticationSuccessHandlerおよびAuthenticationFailureHandler戦略インターフェースによって制御されます。フィルタは@chaoluoがすでにAuthenticationEntryPointを実装し、commenceメソッドをオーバーライドする必要が言ったように、あなたが完全に

0

動作をカスタマイズできるように、これらを設定できるようにする特性を有しています。エラーJSONオブジェクトを返すようにしたい場合は、次の操作を行うことができます検証

@Override 
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) 
      throws IOException, ServletException { 

    response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); 
    response.setContentType(MediaType.APPLICATION_JSON_VALUE); 
    //create errorObj 
    PrintWriter writer = response.getWriter(); 
    mapper.writeValue(writer, errorObj); 
    writer.flush(); 
} 
関連する問題