본문으로 바로가기

웹 시큐리티(Web Security)-5Day

category 웹/Spring 2019. 5. 28. 13:59

깃 허브:https://github.com/leejeongchan/springSecurity.git

로그인 성공(AuthenticationSuccessHandler)

로그인 성공 시에 특별한 것을 처리할 필요가 있습니다. 

 

즉 쿠키를 처리하거나 특정 페이지로 이동시키거나... 

 

이때는 AuthenticationSuccessHandler를 구현합니다.

 

package org.zerock.security;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import lombok.extern.log4j.Log4j;

@Log4j
public class CustomLoginSuccessHandler implements AuthenticationSuccessHandler {
	
	
	@Override
	public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
			Authentication authentication) throws IOException, ServletException {
		// TODO Auto-generated method stub
		
		log.warn("Login Success");
		
		List<String> roleNames = new ArrayList<>();
		
		
		authentication.getAuthorities().forEach(authority->{
			roleNames.add(authority.getAuthority());
		});
		
		log.warn("ROLE NAMES: "+roleNames);
		
		if(roleNames.contains("ROLE_ADMIN")) {
			response.sendRedirect("/sample/admin");
			return;
		}
		
		if(roleNames.contains("ROLE_MEMBER")) {
			response.sendRedirect("/sample/member");
			return;
		}
		response.sendRedirect("/");
	}

}

우선 AuthenticationSuccessHandler를 구현하고 작성합니다. (CustomLoginSuccessHandler.java)

 

앞서 security-context.xml에서 각 롤을 부여한 것을 기억하실 겁니다.

 

그것에 따라서 로그인 성공 시 리다이렉트를 해줄겁니다.

 

우선 파라미터에 authentication을 통해 권한을 얻어서 이것이 contains를 통해 포함된다면 

 

각각에 맞게 리다이렉트를 진행합니다. 

 

마찬가지로 security-context.xml에서는 위 클래스를 빈으로 등록해주고 

 

로그인 성공 시 적용되게 끔 설정해줍니다. 아래 코드를 추가 수정해줍니다.

 

<bean id="customLoginSuccess" class="org.zerock.security.CustomLoginSuccessHandler">
</bean>
<!-- Controller에서 GetMapping("customLogin")으로 처리 -->
<!-- 로그인 성공시 customLoginSuccess를 통해 리다이렉트 처리 -->
<security:form-login login-page="/customLogin" authentication-success-handler-ref="customLoginSuccess"/>

로그인 성공시에 각각 리다이렉트로 된 곳으로 이동함을 알 수 있습니다.

 

이제는 로그아웃을 봅시다.

 

로그인 처럼 security-context.xml에 로그아웃 URI를 지정하고 등록합니다. 

 

<security:logout logout-url="/customLogout" invalidate-session="true"/>

logout-url은 /custoLogout으로 하고 세션 쿠키를 지워주게 합니다.

 

그 다음 CommonController에서 Get방식으로 로그아웃 페이지를 결정하게 합니다.

 

@GetMapping("/customLogout")
public void logoutGet() {
	log.info("custom Logout");
}

그 다음 customLogout.jsp를 작성합니다.

 

로그인과 마찬가지로 form을 이용해서 post로 작성 하고 토큰을 넘겨줍니다.

 

action은 /customLogout 입니다. 이는 컨트롤러에서 PostMapping으로 처리해줄겁니다. 

 

로그인은 자체적으로 /login을 통해 post로 처리가 되지만 logout은 따로 지정해줍니다.

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>Custom Logout Page</h1>
	
	
	<form method="post" action="/customLogout">
	
		<input type='hidden' name="${_csrf.parameterName}" value="${_csrf.token}">
		<button>로그아웃</button>
	</form>
</body>
</html>
@PostMapping("/customLogout")
public void logoutPost() {
	log.info("post custom logout");
}

이렇게 작성해줍니다. 그 다음 로그인 후인 admin.jsp에서 로그아웃 버튼을 만들어줍니다.

 

이때 Get방식으로 url을 줍니다.

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>/sample/admin page</h1>
<a href="/customLogout">Logout</a>
</body>
</html>

즉 시나리오는

 

사용자가 /sample/admin으로 이동하여 로그인 하고 나면 admin.jsp로 이동하게 됩니다.

 

여기서 로그아웃 버튼을 누르게 되면 Get방식으로 /customLogout으로 처리가 됩니다.

 

컨트롤러에서 customLogout.jsp 를 보여주게 되고 여기서 로그아웃을 누르면 POST 방식으로

 

/customLogout이 처리가 됩니다. 이에 따라 security-context.xml에서 설정해줬듯이 쿠키와 세션이 삭제가 된 상태로 로그아웃이 됩니다.