Spring Security

[Security] Success/Failure Handler Custom (인증성공, 인증실패 핸들러 커스텀)

cornarong 2021. 12. 28. 22:43

: Security에서 지원하는 인증성공, 인증실패 핸들러를 상속한 클래스를 직접 커스텀하여 사용해보자.

 

1. 인증성공 핸들러 커스텀

2. 인증실패 핸들러 커스텀

3. config 설정

4. 익명클래스로 처리하는 방법

 

 


1. 인증성공 핸들러 커스텀

1. SimpleUrlAuthenticationSuccessHandler를 상속한 커스텀 클래스 CustomAuthenticationSuccessHandler를 만듭니다.

2. requestCacheRedirectStragey를 사용하여 사용자가 인증 요청 성공시 이전에 접근하려 했던 자원(리소스)의 경로로 바로 보내기 위해서 설정해줍니다. 이전의 접근하려 했던 자원(리소스)가 없는 경우 null을 반환하도록 하여 setDefaultTargetUrl에 설정해준 url로 보내줍니다.

// 인증 성공 핸들러 : CustomAuthenticationSuccessHandler
@Component
public class CustomAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {

    private RequestCache requestCache = new HttpSessionRequestCache();

    private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {

        //기본 url 설정, savedRequest가 null일 경우 설정한 페이지로 보내기 위함이다.
        setDefaultTargetUrl("/");

        // 사용자가 인증을 시도하기 이전에 접근을 시도했던 자원이 없을경우 savedRequest는 null로 반환된다.
        SavedRequest savedRequest = requestCache.getRequest(request, response);
        if(savedRequest != null) {
            String targetUrl = savedRequest.getRedirectUrl();
            redirectStrategy.sendRedirect(request, response, targetUrl);
        }else{
            redirectStrategy.sendRedirect(request, response, getDefaultTargetUrl());
        }
    }
}

 

2. 인증실패 핸들러 커스텀

1. SimpleUrlAuthenticationFailureHandler를 상속한 커스텀 클래스 CustomAuthenticationFailureHandler를 만듭니다.

// 인증 실패 핸들러 : CustomAuthenticationFailureHandler
@Component
public class CustomAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {

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

        String errorMessage = "Invalid Username or Password"; // 기본 예외 메시지
        
        // exceprion 처리
        if(exception instanceof BadCredentialsException) { 
            errorMessage = "Invalid Username or Password";
        }else if(exception instanceof InsufficientAuthenticationException) {
            errorMessage = "Invalid Secret Key";
        }
        // 파라미터로 error와 exception을 보내서 controller에서 처리하기 위함.
        setDefaultFailureUrl("/login?error=true&exception=" + errorMessage);

        // 부모클래스의 onAuthenticationFailure로 처리를 위임하자.
        super.onAuthenticationFailure(request, response, exception);
    }
}

 

successHandler와 다르게 failureHandler에서 super클래스를 선언해준 이유 

-> 실패와 관련된 여러가지 후속처리를 부모에게 위임하기 위함이다.

-> 모두 super 클래스를 호출하지 않아도 상관은 없다.

 

3. SecurityConfig 설정

 

  @Autowired
  private final AuthenticationSuccessHandler customAuthenticationSuccessHandler;
  @Autowired
  private final AuthenticationFailureHandler customAuthenticationFailureHandler;

  http
  .formLogin()
    . // ~생략
    .successHandler(customAuthenticationSuccessHandler) // 1. 성공시 custom success 핸들러를 호출한다.
    .failureHandler(customAuthenticationFailureHandler) // 1. 실패시 custom failure 핸들러를 호출한다.

 

4. 익명클래스로 SecurityConfig내에서 처리하기.

  http
    .formLogin()
    . // ~생략
    .successHandler(new AuthenticationSuccessHandler() { // 2. 성공시 success 핸들러를 호출한다. 추가로 사용해보자
      // 로그인 성공시 authentication 정보를 매개변수로 -
      @Override
        public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        RequestCache requestCache = new HttpSessionRequestCache();
        SavedRequest savedRequest = requestCache.getRequest(request, response); // savedRequest 안에 사용자가 가고자 했던 정보가 들어 있다.
        String redirectUrl = savedRequest.getRedirectUrl();
        // 인증에 성공하면 세션에 저장되어 있던 이전 정보(가고자 했던 경로)를 꺼내와서 이동 시킨다.
        response.sendRedirect(redirectUrl);
      }
    })
    .failureHandler(new AuthenticationFailureHandler() { // 2. 실패시 fail 핸들러를 호출한다. 추가로 사용해보자
      // 로그인 실패시 exception 정보를 매개변수로 -
      @Override
        public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
        response.sendRedirect("/loginPage");
      }
    });

 

 


 

 

 

스프링 시큐리티 - Spring Boot 기반으로 개발하는 Spring Security - 인프런 | 강의

초급에서 중.고급에 이르기까지 스프링 시큐리티의 기본 개념부터 API 사용법과 내부 아키텍처를 학습하게 되고 이를 바탕으로 실전 프로젝트를 완성해 나감으로써 스프링 시큐리티의 인증과

www.inflearn.com