본문 바로가기

Java/Spring

Spring Security 로그인 성공 혹은 실패 후 부가 작업 하기.

요구사항.


로그인을 5번 이상 실패하면 계정 잠금 처리.



먼저 사용자 테이블에 로그인 실패 건수를 업데이트할 컬럼을 생성한다.


로그인이 실패하면, 해당 컬럼에 +1 건을 추가하고,


로그인을 성공하면, 0으로 초기화 해주는 로직을 넣어보려고 한다.



스프링 시큐리티를 사용하며, 로그인 성공시 부가 작업을 하려면, org.springframework.security.web.authentication.AuthenticationSuccessHandler를 구현해야 한다.


별도로 authenticationSuccessHandler를 지정하지 않으면 기본적으로 org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler를 사용하게 된다.


일반적은 로직은 동일하게 사용하고, 그 전에 로그인 성공에 따른 로그인 실패건수만 0으로 업데이트 해주면 되기 때문에, SimpleUrlAuthenticationSuccessHandler를 상속 받아 구현하기로 한다.


사용자의 정보를 업데이트 해주는 서비스를 UserService 라고 가정하고, CustomAuthenticationSuccessHandler를 구현해보자.


/** * @author jason, Moon (jason.moon.kr@gmail.com) * @since 2018-03-21 */ public class CustomAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler { private final UserService userService; public CustomAuthenticationSuccessHandler (UserService userService) { this.userService = userService; } @Override public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException { // 로그인 성공시 실패 카운트 초기화 userService.clearFailureCount(authentication.getPrincipal().getLoginId()); super.onAuthenticationSuccess(httpServletRequest, httpServletResponse, authentication); } }

SimpleUrlAuthenticationSuccessHandler의 onAuthenticationSuccess 메서드를 오버라이딩 한다.


로그인 성공시 실패 카운트를 초기화하는 로직을 넣고, SimpleUrlAuthenticationSuccessHandler의 onAuthenticationSuccess 메서드를 호출해준다.


굉장히 간단하다.


이렇게 생성한 CustomAuthenticationSuccessHandler를 설정해준다.


<form-login login-page="/login" login-processing-url="/login/login-proc" username-parameter="username" password-parameter="password" authentication-success-handler-ref="customLoginSuccessHandler"/>


<b:bean name="customAuthenticationSuccessHandler" class=".........CustomLoginSuccessHandler"> <b:constructor-arg ref="userService"/> </b:bean>

CustomAuthenticationSuccessHandler에서 userService를 사용할 수 있게 constuctor-arg에 userService를 넘겨준다.


CustomAuthenticationSuccessHandler를 bean으로 설정하고, authentication-success-handler로 CustomAuthenticationSuccessHandler를 설정하면 된다.


다만, 이때 form-login 태그에 default-target-url 속성이 정상 작동 하지 않는걸 확인할 수 있다.


SimpleUrlAuthenticationHandler의 defalultTargetUrl의 값을 넘겨줘야 하는데, CustomAuthenticationSuccessHandler의 생성자에 default-target-url 값을 넘기고, SimpleUrlAuthenticationHandler에 설정해줘야 한다.


먼저 customAuthenticationSuccessHandler의 생성자에 dafaultTarget 값을 추가한다.


<b:bean name="customLoginSuccessHandler" class="....CustomLoginSuccessHandler"> <b:constructor-arg value="/main.do"/> <b:constructor-arg ref="userService"/> </b:bean>

그리고 두개의 값을 받은 CustomLoginSuccessHanlder의 생성자를 변경해 준다.


생성자에서 주입받은 첫번째 파라메터 문자열 값 defaultTargetUrl을 SimpleUrlAuthenticationSuccessHandler의 defaultTargetUrl 값으로 설정해주면, 끝난다.


/**
 * @author jason, Moon (jason.moon.kr@gmail.com)
 * @since 2018-03-21
 */
public class CustomAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {
    private final UserService userService;

    public CustomAuthenticationSuccessHandler(String defaultTargetUrl, UserService userSerivce) {
        super.setDefaultTargetUrl(defaultTargetUrl);
        this.userSerivce = userSerivce;
    }

    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
        // 로그인 성공시 실패 카운트 초기화
        userService.clearFailureCount(((LoginUserVO)authentication.getPrincipal()).getLoginId());

        super.onAuthenticationSuccess(httpServletRequest, httpServletResponse, authentication);
    }
}


위와 같은 동일한 방식으로 AuthenticationFailureHandler도 구현할수 있다.


동일하게 SimpleUrlAuthenticationFailureHandler를 상속받아 추가하면 된다.


SimpleUrlAuthenticationFailureHandler에서는 onAuthenticationFailure 메서드를 오버라이드 해야하는데, 이때 파라메터로 전달 받는 AuthenticationException이 BadCredentialException의 인스터인 경우에만 실패 건수를 올려주면 된다.