복붙노트

[SPRING] AuthenticationProvider에서 발생하는 잡기 예외

SPRING

AuthenticationProvider에서 발생하는 잡기 예외

나는 사용자 정의 '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'함수 내에서 예외가 발생하면 전역 예외 처리기가 호출되지 않습니다. 다른 모든 예외에 대해서는 호출되고 있습니다. 전역 예외 처리기 내에서 예외를 catch하고 사용자 지정 오류 메시지를 반환하고 싶습니다. 어떻게해야합니까? 어떤 도움을 주셔서 감사합니다. 미리 감사드립니다.

해결법

  1. ==============================

    1.GlobalExceptionHandler는 컨트롤러 예외 핸들러에 대한 것이지만 AuthenticationProvider가 여전히 필터에 있으므로 AuthenticationException을 처리하려면 AuthenticationEntryPoint를 구현하고 시작 메서드를 재정의해야합니다.

    GlobalExceptionHandler는 컨트롤러 예외 핸들러에 대한 것이지만 AuthenticationProvider가 여전히 필터에 있으므로 AuthenticationException을 처리하려면 AuthenticationEntryPoint를 구현하고 시작 메서드를 재정의해야합니다.

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

    AuthenticationException 및 AccessDeniedException은 ExceptionTranslationFilter에 의해 이미 처리되었습니다. AuthenticationEntryPoint와 AccessDeniedHandler (AccessDeniedException을 처리하는)를 삽입하면된다.

    또는 필터에서 이러한 예외를 catch 한 다음 Filer에서 처리 할 수 ​​있습니다 (예 : AbstractAuthenticationProcessingFilter의 AuthenticationFailureHandler).

  2. ==============================

    2.컨트롤러 예외 처리기가 예외를 잡을 수 있기 전에 인증 공급자가 호출됩니다.

    컨트롤러 예외 처리기가 예외를 잡을 수 있기 전에 인증 공급자가 호출됩니다.

    AuthenticationFailureHandler를 재정 의하여 보안 필터 체인 수준에서 예외를 처리하고 예제를 살펴볼 수 있습니다.

    문서에 설명 된대로 동작 :

  3. ==============================

    3.@ chaoluo는 이미 AuthenticationEntryPoint를 구현하고 시작 메서드를 재정의해야한다고 말했습니다. 오류 JSON 객체를 반환하려면 다음을 수행 할 수 있습니다.

    @ chaoluo는 이미 AuthenticationEntryPoint를 구현하고 시작 메서드를 재정의해야한다고 말했습니다. 오류 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();
    }
    
  4. from https://stackoverflow.com/questions/41274160/catching-exception-thrown-in-authenticationprovider by cc-by-sa and MIT license