본문 바로가기

SPRING/SpringSecurity

[스프링 시큐리티 완전 정복| 실전 프로젝트 | 회원 인증 시스템] AuthenticationSuccess(Failure)Handler, AccessDeniedHandler

AuthenticationSuccessHandler

 

 



AuthenticationSuccessHandler는 Spring Security에서 인증(로그인)이 성공했을 때 호출되는 인터페이스다. 이 인터페이스는 인증이 성공한 후에 어떤 작업을 수행할지 정의하는 데 사용된다. 일반적으로 사용자에게 적절한 응답을 보내거나 특정 페이지로 리다이렉트하는 등의 작업을 처리할 수 있다.

주요 역할

  1. 로그인 성공 후 동작 정의: 사용자가 성공적으로 인증되면, AuthenticationSuccessHandler가 호출되어 추가 작업을 수행할 수 있다. 예를 들어, 특정 페이지로 리다이렉트하거나, 사용자 정보를 로깅하거나, 세션에 값을 저장하는 등의 작업을 할 수 있다.
  2. 세션 관리: 로그인 성공 시 세션 정보를 초기화하거나 추가적인 정보를 저장할 수 있다. 예를 들어, 사용자 ID나 역할 정보를 세션에 저장해 이후 요청에서 사용할 수 있다.
  3. 리다이렉션: 일반적으로 로그인 성공 후 사용자를 특정 페이지로 리다이렉트하는 데 많이 사용된다. 로그인 페이지에서 로그인한 후, 사용자를 메인 페이지로 이동시키거나, 사용자가 원래 가고자 했던 페이지로 리다이렉트하는 로직을 작성할 수 있다.
 

 

@Component
public class FormAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
    // @Component: Spring의 Bean으로 등록하여 이 클래스가 인증 성공 시 자동으로 호출되도록 한다.
    // SimpleUrlAuthenticationSuccessHandler를 상속받아 기본적인 리다이렉트 처리 로직을 재사용한다.

    private final RequestCache requestCache = new HttpSessionRequestCache();
    // RequestCache: 사용자가 인증하기 전 요청했던 URL을 저장하는 객체이다.
    // HttpSessionRequestCache는 사용자의 세션에 원래 요청을 저장하고, 인증이 완료되면 원래 요청한 URL로 리다이렉트할 수 있다.

    private final RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
    // RedirectStrategy: 리다이렉트 전략을 설정하는 객체로, 인증 성공 후 특정 URL로 사용자를 이동시킨다.
    // DefaultRedirectStrategy는 가장 기본적인 리다이렉트 전략을 제공하는 클래스다.

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        // onAuthenticationSuccess: 인증이 성공한 후 호출되는 메서드이다. 인증 성공 후 어떤 행동을 할지를 정의한다.

        setDefaultTargetUrl("/");
        // setDefaultTargetUrl: 인증 후 기본적으로 리다이렉트할 URL을 설정한다. 여기서는 "/"로 설정되어 있다.
        // 사용자가 로그인 전에 요청했던 URL이 없으면 이 기본 URL로 리다이렉트된다.

        SavedRequest savedRequest = requestCache.getRequest(request, response);
        // requestCache.getRequest: 사용자가 인증하기 전에 요청한 URL을 가져온다.
        // SavedRequest는 인증 전에 사용자가 방문하고자 했던 URL과 관련된 정보를 담고 있는 객체다.

        if (savedRequest != null) {
            String targetUrl = savedRequest.getRedirectUrl();
            // savedRequest가 null이 아닌 경우, 사용자가 로그인 전에 접근하려던 URL을 가져온다.
            // targetUrl은 사용자가 원래 접근하려던 페이지의 URL이다.

            redirectStrategy.sendRedirect(request, response, targetUrl);
            // redirectStrategy를 사용하여 사용자가 원래 접근하려던 URL로 리다이렉트한다.
        } else {
            redirectStrategy.sendRedirect(request, response, getDefaultTargetUrl());
            // savedRequest가 null인 경우, 즉 로그인 전 요청한 URL이 없을 때는 기본 URL로 리다이렉트한다.
            // 기본 URL은 "/"로 설정되어 있으므로 메인 페이지로 이동시킨다.
        }
    }
}

 


AuthenticationFailureHandler

 

 



AuthenticationFailureHandler는 Spring Security에서 사용자가 인증(로그인)에 실패했을 때 호출되는 인터페이스다. 이 인터페이스는 인증 실패 시 후속 작업을 처리하는 역할을 한다. 인증 실패가 발생하면, 해당 핸들러를 통해 실패에 대한 응답을 사용자에게 제공하거나, 특정 동작을 수행할 수 있다.

주요 역할

  1. 로그인 실패 처리: 로그인 실패 시 어떤 동작을 할지 정의한다. 예를 들어, 사용자가 로그인 실패 시 다시 로그인 페이지로 이동시키거나, 실패 메시지를 보여줄 수 있다.
  2. 에러 메시지 제공: 로그인 실패 원인에 따라 사용자에게 적절한 에러 메시지를 전달할 수 있다. 예를 들어, 비밀번호 오류, 계정 잠김 등의 다양한 실패 이유에 맞는 피드백을 제공할 수 있다.
  3. 로그 기록: 인증 실패 시 보안적인 이유로 로그를 기록하여 누가, 언제, 어디서 실패했는지 추적할 수 있다.
  4. 리다이렉트: 인증 실패 후 사용자를 로그인 페이지로 리다이렉트하거나 다른 특정 페이지로 이동시킬 수 있다.
 
 @Component
public class FormAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
    // @Component: Spring의 Bean으로 등록되어, 이 클래스가 인증 실패 시 자동으로 호출될 수 있도록 한다.
    // SimpleUrlAuthenticationFailureHandler를 상속받아 인증 실패 시의 기본 동작을 확장한다.

    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
        // onAuthenticationFailure: 인증 실패 시 호출되는 메서드로, HttpServletRequest와 HttpServletResponse, 그리고 발생한 AuthenticationException을 인자로 받는다.
        // 인증 실패 후에 어떤 동작을 할지 정의하는 메서드이다.

        String errorMessage = "Invalid Username or Password";
        // 기본적인 에러 메시지를 "Invalid Username or Password"로 설정한다.
        // 이 메시지는 인증 실패 이유에 따라 변경될 수 있다.

        if(exception instanceof BadCredentialsException){
            errorMessage = "Invalid Username or Password";
            // BadCredentialsException: 잘못된 사용자 이름 또는 비밀번호로 인한 인증 실패.
            // 기본 에러 메시지를 그대로 사용한다.
        } else if(exception instanceof UsernameNotFoundException){
            errorMessage = "User not exist";
            // UsernameNotFoundException: 존재하지 않는 사용자 이름으로 로그인 시도했을 때 발생하는 예외.
            // "User not exist"라는 메시지를 설정한다.
        } else if(exception instanceof CredentialsExpiredException){
            errorMessage = "Expired password";
            // CredentialsExpiredException: 비밀번호가 만료되어 인증이 실패했을 때 발생하는 예외.
            // "Expired password"라는 메시지를 설정한다.
        } else if(exception instanceof SecretException){
            errorMessage = "Invalid Secret Key";
            // SecretException: 비밀번호 외에 별도의 "Secret Key"가 잘못되었을 때 발생하는 커스텀 예외.
            // "Invalid Secret Key"라는 메시지를 설정한다.
        }

        setDefaultFailureUrl("/login?error=true&exception=" + errorMessage);
        // setDefaultFailureUrl: 인증 실패 시 리다이렉트할 URL을 설정한다.
        // 로그인 실패 시 "/login?error=true&exception=에러 메시지" 형식으로 리다이렉트한다.
        // 사용자가 로그인 페이지에서 인증 실패에 대한 구체적인 메시지를 확인할 수 있게 한다.

        super.onAuthenticationFailure(request, response, exception);
        // 부모 클래스인 SimpleUrlAuthenticationFailureHandler의 onAuthenticationFailure 메서드를 호출하여
        // 실제로 리다이렉트 동작을 수행한다.
    }
}

 

 


AccessDeniedHandler

 



 AccessDeniedHandler는 Spring Security에서 인증된 사용자가 권한이 없거나 접근할 수 없는 자원에 접근하려고 시도할 때 호출되는 인터페이스다. 즉, 사용자가 인증에는 성공했지만, 특정 자원에 접근할 권한이 부족할 때 발생하는 예외(AccessDeniedException)를 처리한다. 이 핸들러는 주로 권한 부족에 대한 응답을 제공하거나 특정 페이지로 리다이렉트할 때 사용된다.

주요 역할

  1. 접근 제한 처리: 인증된 사용자가 특정 자원에 접근할 수 있는 권한이 없을 때 호출되어, 권한 부족 상황에 대한 적절한 응답을 제공한다.
  2. 에러 페이지 리다이렉트: 권한이 없을 때 사용자를 특정 페이지로 리다이렉트하거나, 권한 부족에 대한 맞춤형 에러 메시지를 제공할 수 있다.
  3. 보안 로그 기록: 권한이 없는 사용자가 특정 자원에 접근하려는 시도를 기록하여 보안 로그를 남길 수 있다.
 

 

public class FormAccessDeniedHandler implements AccessDeniedHandler {
    // FormAccessDeniedHandler: AccessDeniedHandler 인터페이스를 구현하여 권한이 없는 사용자에 대한 접근 거부 처리를 커스터마이징하는 클래스.

    private final RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
    // RedirectStrategy: 리다이렉트를 처리하는 전략을 정의하는 객체로, 여기서는 기본적인 DefaultRedirectStrategy를 사용한다.
    // 인증이 실패하거나 권한이 없는 경우, 특정 페이지로 리다이렉트할 때 사용된다.

    private final String errorPage;
    // errorPage: 접근 거부 시 리다이렉트할 에러 페이지의 URL을 저장하는 필드.
    // 이 필드는 생성자를 통해 설정되며, 이후 접근 거부 시 이 페이지로 이동하게 된다.

    public FormAccessDeniedHandler(String errorPage) {
        this.errorPage = errorPage;
        // 생성자: errorPage 필드를 초기화한다. 외부에서 에러 페이지 URL을 주입받아 사용할 수 있게 한다.
    }

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
        // handle 메서드: 접근 거부가 발생했을 때 호출되는 메서드.
        // HttpServletRequest, HttpServletResponse, AccessDeniedException을 인자로 받아 접근 거부 처리 로직을 구현한다.

        String deniedUrl = errorPage + "?exception=" + accessDeniedException.getMessage();
        // deniedUrl: 에러 페이지 URL에 접근 거부 원인(exception 메시지)을 파라미터로 추가한 URL을 구성한다.
        // 접근 거부 이유를 사용자가 볼 수 있도록 URL에 포함시킨다.

        redirectStrategy.sendRedirect(request, response, deniedUrl);
        // redirectStrategy를 사용하여 구성한 deniedUrl로 사용자를 리다이렉트한다.
        // 즉, 사용자는 접근 권한이 없는 경우 지정된 에러 페이지로 이동하게 된다.
    }
}