본문 바로가기
Spring Framework/project

Spring Security - LoginFailureHandler

by bloodFinger 2020. 1. 6.

로그인이 실패 할 수 있는 경우는 많이 존재한다.

1. 로그인 비밀번호가 틀렸다.

2.계정이 존재하지 않는다.

3.이메일 인증을 하지 않았다.

4.누군가 내 아이디로 로그인을 하고있다. (중복로그인)

 

이러한 4가지의 경우를 모두 처리를 해줘야 한다. 로그인 성공보다 더욱 많은 부가 작업이 이루어져야한다!

이러한 부가 작업을 사람들은 커스터마이징 한다고 한다!

 

LoginFailureHandler.java

@Data
public class LoginFailureHandler implements AuthenticationFailureHandler {
	private String loginemailname;
	private String loginpwdname;
	private String errormsgname;
	private String defaultFailureUrl;

	@Override
	public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
		                                AuthenticationException exception) throws IOException, ServletException {
             
		String member_email = request.getParameter(loginemailname);
		String member_pwd = request.getParameter(loginpwdname);
		String errormsg = null;
		defaultFailureUrl = "/member/loginForm?error";

		if (exception instanceof BadCredentialsException) {
			errormsg = "1"; // 비밀번호를 잘못 입력했습니다.
		} else if (exception instanceof UsernameNotFoundException) {
			errormsg = "2"; // 계정이 존재하지 않습니다.
		} else if (exception instanceof DisabledException) {
			errormsg = "3"; // 이메일 인증을 해주세요.
		} else if (exception instanceof SessionAuthenticationException) {
			errormsg = "4"; // 중복 로그인
		}

		request.setAttribute(loginemailname, member_email);
		request.setAttribute(loginpwdname, member_pwd);
		request.setAttribute(errormsgname, errormsg);

		request.getRequestDispatcher(this.defaultFailureUrl).forward(request, response);
	}

}

 

아이디와 비밀번호를 getParameter 메서드를 이용해 가져온다.


17~25 줄

Exception 설명
BadCredentialException 비밀번호가 일치하지 않았을때 던지는 예외
UsernameNotFoundException  
DisabledException 인증 거부 - 계정 비활성화
SessionAuthenticationException  
InternalAuthenticationServiceException 존재하지 않는 아이디일때 던지는 예외
AuthenticationCredentialNotFoundException 인증 요구가 거부됐을 때 던지는 예외
LockedException 인증 거부 - 잠긴 계정
CredentialExpiredException
인증 거부 - 비밀번호 유효기간 만료
AccountExpiredException
인증 거부 - 계정 유효기간 만료

여기서 알아둬야 할 것은, 비밀번호와 아이디가 일치하지 않는 예외들의 메세지를 분리해서는 안된다고 한다.

그런데 나는 프로젝트를 진행할때 계정과 비밀번호를 분리했다... 이렇게 해도 되지만 이러면 보안성이 낮아진다고

한다. 조금이라도 보안성을 높이려면 두 개의 예외를 하나의 메세지로 처리하는게 좋다

 

31줄 - 저장된 에러 메세지 세팅

 

security.xml

	<beans:bean id="loginFailureHandler" class="member.handler.LoginFailureHandler">
	    <beans:property name="loginemailname" value="member_email"/>
	    <beans:property name="loginpwdname" value="member_pwd"/>
	    <beans:property name="errormsgname" value="ERRORMSG"/>
	    <beans:property name="defaultFailureUrl" value="/member/loginForm?error"/>
	</beans:bean>

 

 

 

 

jstl 적용

 

loginForm.java안 inline javascript

if('${ERRORMSG}' == '1') {
    document.addEventListener("DOMContentLoaded", function(event) {
       var toastTop = app.toast.create({
           text: '아이디 또는 비밀번호를 잘못 입력했습니다.',
            position: 'top',
            closeButton: true
       });
       toastTop.open();
    });
} else if('${ERRORMSG}'  == '2') {
    document.addEventListener("DOMContentLoaded", function(event) {
       var toastTop = app.toast.create({
           text: '계정이 존재하지 않습니다.',
            position: 'top',
            closeButton: true
       });
       toastTop.open();
    });
} else if('${ERRORMSG}'  == '3') {
    document.addEventListener("DOMContentLoaded", function(event) {
       var toastTop = app.toast.create({
           text: '이메일 인증을 해주세요.',
            position: 'top',
            closeButton: true
       });
       toastTop.open();
    });
} else if('${ERRORMSG}'  == '4') {
    document.addEventListener("DOMContentLoaded", function(event) {
       var toastTop = app.toast.create({
           text: '이미 로그인 중입니다.',
            position: 'top',
            closeButton: true

       });
       toastTop.open();
 	});
} else if('${status}' != 'true') {
 	document.addEventListener("DOMContentLoaded", function(event) {
    	var toastTop = app.toast.create({
        	text: '먼저 로그인 해주세요.',
         	position: 'top',
         	closeButton: true
       });
       toastTop.open();
    });
}

alert 대신에 토스트를 통해서 알림을 한다!

'Spring Framework > project' 카테고리의 다른 글

CSRF 는 무엇인가?  (0) 2020.02.12
Spring 실시간 알림(webSocket)  (15) 2020.01.26
Spring Security - LoginSucessHandler  (0) 2020.01.06
Spring Security -인증 및 권한부여  (0) 2020.01.06
spring security 환경설정  (0) 2020.01.06