본문 바로가기
Spring Framework/project

Spring Security - LoginSucessHandler

by bloodFinger 2020. 1. 6.

loginSuccessHandler에 접근하면 몇가지 일을 해줘야한다!

 

1. 로그인에 성공 후 이동할 URL을 지정하여 지정한 URL로 이동해야 한다.

 

2. 로그인에 성공했을 때 이동할 곳은 다 다르다.

로그인 버튼을 눌러 직접 로그인화면으로 갔다면 성공 후엔 메인 화면으로 가야 할 것이고,

권한이 필요한 곳에 접근하여 강제로 로그인 화면으로 이동했다면 성공 후엔 그 권한이 필요했던 곳으로 가야한다.

 

예를 들어서, 게시판에 접근하려고 하는데 접근권한이 없어서 로그인페이지로 이동을 하게되고 로그인후에는 내가

클릭했었던 게시물을 기억하고 있다가 로그인을 성공하는 순간 그 게시물로 이동하게 된다.

여러 홈페이지를 유심히 봤던 사람이라면 이러한 동작을 하는걸 본적 있을 것 이다!

 

3.로그인 실패 에러 세션 지우기 -  혹시나 있을 에러 세션을 지우는 작업도 해줘야 한다

 

이러한 기능을을 아래에서 살펴보자

 

 

security.xml

<form-login
			username-parameter="member_email"
			password-parameter="member_pwd"
			login-page="/member/loginForm"
			login-processing-url="/member/login"
			default-target-url="/main/index" 
			authentication-failure-handler-ref="loginFailureHandler"
			authentication-success-handler-ref="loginSuccessHandler" />
        
        
        
        <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>

	<beans:bean id="loginSuccessHandler" class="member.handler.LoginSuccessHandler">
		<beans:property name="defaultUrl" value="/main/index"/>
	</beans:bean>

 

  • login-page : 로그인 전에 인증 권한이 필요한 페이지를 요청했을 시 자동으로 이동시킬 url 
  • login-processing-url : 로그인 페이지 form action에 입력할 주소 지정
  • authentication-failure-handler-ref : 인증 실패 시 이동하는 url
  • authentication-sucess-handler-ref : 인증 성공 시 이동하는 url 
  • default-target-url: 인증 성공 후 이동하는 url 

 

Spring Security에서 제공하는 AuthenticationSuccessHandler 인터페이스를 구현한다!

 

LoginSucessHandler.java

@Data
public class LoginSuccessHandler implements AuthenticationSuccessHandler {
	@Autowired
	private MemberDAO memberDAO;

	private static int TIME = 60 * 60 * 24; // 하루
	private String defaultUrl;

	private RequestCache reqCache = new HttpSessionRequestCache();
	private RedirectStrategy redirectStratgy = new DefaultRedirectStrategy();

	@Override
	public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
			Authentication authentication) throws IOException, ServletException {
		MemberDTO memberDTO = memberDAO.getMemberByEmail(authentication.getName());

		// System.out.println("로그인 된 유저DTO : " + memberDTO);
		HttpSession session = request.getSession();
		session.setAttribute("memDTO", memberDTO);
		session.setMaxInactiveInterval(TIME);

		// 에러 세션 지우기
		clearAuthenticationAttributes(request);

		if (memberDTO.getMember_nickname().equals("admin")) {
			redirectStratgy.sendRedirect(request, response, "/admin/adminMain");
		} else {
			resultRedirectStrategy(request, response, authentication);
		}
	}

	protected void resultRedirectStrategy(HttpServletRequest request, HttpServletResponse response,
			Authentication authentication) throws IOException, ServletException {
		SavedRequest savedRequest = reqCache.getRequest(request, response);
		if (savedRequest != null) {
			String targetUrl = savedRequest.getRedirectUrl();
			redirectStratgy.sendRedirect(request, response, targetUrl);
		} else {
			redirectStratgy.sendRedirect(request, response, defaultUrl);
		}
	}

	protected void clearAuthenticationAttributes(HttpServletRequest request) {
		HttpSession session = request.getSession(false);
		if (session == null)
			return;
		session.removeAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
	}

}

 

 

 

onAuthenticationSuceess( ... )의 3개의 인자에 대해서 알아보자

  • HttpServletRequest 객체: 웹에서 넘어온 Request 값을 가지고 있는 객체
  • HttpServletResponse 객체: 출력을 정의할 수 있는 객체
  • Authentication 객체: 인증에 성공한 사용자의 정보를 가지고 있는 객체

 

34줄 - spring security에서 제공하는 사용자의 요청을 저장하고 꺼낼 수 있는 RequestCache 객체를 통해

사용자 요청 정보들이 들어 있는 SavedRequest 객체를 세션에 저장하게 된다.

우리는 SavedRequest 객체를 가져와서 로그인 화면을 보기 잔에 방문했던 URL정보를 가져오면 된다!

 

39줄 -security.xml 에서 defalut-target-url 을 설정한 적이 있다. 로그인 성공시 이동할 url을 설정했는데, 이 url로 이동하게 해주면 된다.

 

 

로그인을 하는 과정에서 한번만에 로그인에 성공할 수도 있지만, 실패를 한 후 로그인에 성공하는 경우도 있다. 이처럼 로그인에 실패하는 상황이 한번이라도 발생한다면, 에러가 세션에 저장되어 남아있게 된다.

로그인에 성공했다고 하지만 이렇게 세션에 에러가 남겨진 채로 넘어갈 수는 없다. 

따라서 로그인 성공 핸들러에서 에러 세션을 지우는 작업을 해줘야 한다.

그 역할을 clearAuthenticationAttributes(..) 수행한다!!

 

 

-----------------------------------------------------------------------------------------------------

 

여기에 추가적으로 나는 프로젝트에 로그인 수행 횟수를 넣지 않았지만 spring security에서 카운터를 해줄수 있다!

이 기능을 넣었으면 좋았을텐데!!!

만약에 이런기능이 존재했다고 가정하면 로그인이 성공했을때 실패 카운터를 초기화 해줘야 한다!

만약에 초기화를 하지 않고  로그인에 성공하게 된다면 다음번에 로그인할 때는 더 적은 실패 횟수를 가지게 될 것이다.

따라서 로그인을 시도할 때마다 같은 시도 횟수를 주려고 한다면 실패 카운터를 초기화해야 한다!!!!

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

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