본문 바로가기

SPRING SECURITY

[SpringSecurity] 인증성공, 실패 핸들러

로그인에 성공을 하거나 실패를 했을 때 부가작업을 해보려고 합니다.

 

1. 인증성공

- 로그인 성공시, Redirect할 URL 설정

예를 들어, 로그인을 하지 않은 경우에 권한이 있는 페이지에 접근을 하려고 하면 로그인 페이지로 넘어가는 경우가 있습니다.

이 과정에서 로그인을 성공 했을 때 Redirect할 URL이 접근 하려고 시도 했던 페이지의 URL이 되어 그 페이지로 바로 넘어가도록 해보겠습니다.

 

@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, ServletException {

        setDefaultTargetUrl("/");

        SavedRequest savedRequest = requestCache.getRequest(request, response);

        if(savedRequest != null){
            String targetUrl = savedRequest.getRedirectUrl();
            redirectStrategy.sendRedirect(request, response, targetUrl);
        }else{
            redirectStrategy.sendRedirect(request, response, getDefaultTargetUrl());
        }

    }
}

인증성공핸들러를 커스터마이징하기위해 SimpleUrlAuthenticationSuccessHandler를 상속하여 클래스를 만들어 줍니다.

 

그리고, RequestCache와 SavedRequest에 대해서 알아야 합니다.

RequestCache와 Savedrequest는 인터페이스 이며,

RequestCahce의 기본 구현체는 HttpSessionRequestCahce이고

SavedRequest의 기본 구현체는 DefaultSavedrequest입니다.


HttpSessionRequestDefaultSavedRequest 객체를 세션에 저장하는 역학을 하며,

HttpSessionRequsetCache.java


DefaultSavedRequest는 현재 클라이언트의 요청과정 중에 포함된 쿠키, 헤더, 파라미터 값들을 추출하여 보관하는 역할을 합니다. 

DefaultSavedRequest.java

즉, 현재 클라이언트의 요청 과정에서 생성되거나 참조되는 모든 정보는 DefaultSavedRequest에 저장되고 이 객체는 HttpSessionRequestCache에 의해 세션에 저장됩니다.

실행 결과

- 로그인을 하지 않은 상태입니다.

- 홈 화면에서 ROLE_USER의 권한만 들어갈 수 있는 /mypage에 접속을 시도합니다.

- 로그인 창이 떠서 로그인을 시도합니다.

savedRequest가 null이 아니기 때문에 targetUrl을 설정하고 targetUrl로 Redirect가 되는 걸 볼 수 있습니다.

 

다음은 다른 화면으로 이동하다 로그인 페이지로 가는 경우가 아닌, 홈 화면에서 로그인 버튼을 눌러 로그인을 할 때 경우입니다.

savedRequest가 null인 것을 확인할 수 있습니다. 이 경우에는 setDefaultTargetUrl에서 설정한 것과 같이 "/"경로로 Redirect 될 것 입니다.

 

2. 인증 실패

- 에러 화면 띄우기

@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";

        if(exception instanceof BadCredentialsException){
            errorMessage = "Invalid Username or Password";
        }else if(exception instanceof InsufficientAuthenticationException){
            errorMessage = "Invalid Secret Key";
        }

        setDefaultFailureUrl("/login?error=true&exception=" + exception.getMessage());

        super.onAuthenticationFailure(request, response, exception);
    }
}

BadCredentialException과 InsufficientAuthentcationException의 에러가 발생할 경우에 errorMessage를 설정하고

setDefaultFailreUrl에 error와 exception을 파라미터로 설정하여 넘깁니다.

 

    @GetMapping("/login")
    public String login(@RequestParam(value = "error", required = false) String error,
                        @RequestParam(value = "exception", required = false) String exception,
                        Model model){


        model.addAttribute("error", error);
        model.addAttribute("exception",exception);


        return "user/login/login";
    }
            <div th:if="${param.error}" class="form-group">
                <span th:text="${exception}" class="alert alert-danger">잘못된 아이디나 암호입니다</span>
            </div>

required가 false였던 error와 exception에 파라미터 값을 설정하고 model을 이용하여 화면으로 값을 넘겨줍니다.

 

실행결과

정상적으로 설정된 errorMessage가 화면에 나오는 것을 확인할 수 있습니다.

 

출처

https://www.inflearn.com/questions/35556

https://www.inflearn.com/course