/**
* 사용자 로그인 성공 시 동작하는 핸들러 클래스
* AuthenticationSuccessHandler 인터페이스를 구현하여 로그인 성공 후 로직을 처리함
*/
@Log4j
public class CustomLoginSuccessHandler implements AuthenticationSuccessHandler {
/**
* 인증 성공 시 호출되는 메소드
* 사용자의 권한(Role)에 따라 다른 페이지로 리다이렉트함
*
* @param request 클라이언트의 HTTP 요청 객체
* @param response 서버의 HTTP 응답 객체
* @param auth 인증 정보가 담긴 객체
* @throws IOException 입출력 예외 발생 시
* @throws ServletException 서블릿 예외 발생 시
*/
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication auth)
throws IOException, ServletException {
log.warn("Login Success"); // 로그인 성공 메시지 로깅
// 사용자의 권한 목록을 저장할 리스트 생성
List<String> roleNames = new ArrayList<>();
// 사용자의 모든 권한을 리스트에 추가
auth.getAuthorities().forEach(authority -> {
roleNames.add(authority.getAuthority());
});
log.warn("ROLE NAMES: " + roleNames); // 사용자의 권한 목록 로깅
// 관리자(ADMIN) 권한이 있는 경우
if (roleNames.contains("ROLE_ADMIN")) {
response.sendRedirect("/sample/admin"); // 관리자 페이지로 리다이렉트
return;
}
// 일반 회원(MEMBER) 권한이 있는 경우
if (roleNames.contains("ROLE_MEMBER")) {
response.sendRedirect("/sample/member"); // 회원 페이지로 리다이렉트
return;
}
// 위 권한이 없는 경우 메인 페이지로 리다이렉트
response.sendRedirect("/");
}
}
<bean id = "customLoginSuccess"
class="org.zerock.security.CustomLoginSuccessHandler"></bean>
<security:http>
...
<security:form-login login-page="/customLogin"
authentication-success-handler-ref="customLoginSuccess"/>
<security:logout logout-url="/customLogout" invalidate-session="true"/>
...
</security:http>
<%@ 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>
<h3>Admin page</h3>
<br>
<a href="/customLogout">Logout</a>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1> Logout Page</h1>
<form action="/customLogout" method='post'>
<input type="hidden"name="${_csrf.parameterName}"value="${_csrf.token}"/>
<button>로그아웃</button>
</form>
</body>
</html>
로그아웃 버튼 클릭시 컨트롤러에서 customLogout.jsp로 이동시킴 (GET)
customLogout.jsp에서 POST방식으로 form action!
AuthenticationSuccessHandler 인터페이스 구현onAuthenticationSuccess() 메서드 호출ROLE_ADMIN → /sample/adminROLE_MEMBER → /sample/member/<security:form-login
login-page="/customLogin"
authentication-success-handler-ref="customLoginSuccess"/>
/customLogin: 사용자 정의 로그인 페이지authentication-success-handler-ref: 로그인 성공 시 커스텀 핸들러 지정<security:logout
logout-url="/customLogout"
invalidate-session="true"/>
/customLogout: 로그아웃 URLinvalidate-session="true": 세션 무효화/sample/admin으로 리다이렉트된 관리자 페이지 예시/customLogout 링크 제공 (로그아웃 페이지 이동용)GET 방식으로 이동한 후, 실제 로그아웃은 POST 폼 제출을 통해 수행<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
/customLogout 링크 클릭customLogout.jsp 로 이동 (GET)<form>을 통해 /customLogout POST 요청[로그인 성공] → CustomLoginSuccessHandler
└ 역할별 리다이렉트 (/admin or /member or /)
[Logout 클릭]
→ GET /customLogout → customLogout.jsp
└ POST /customLogout (form 제출) → Spring Security 로그아웃 처리