Published 2023. 4. 11. 22:07
Logout
스프링 시큐리티는 아래와 같은 설정으로 세션, 인증토큰, 쿠키정보를 삭제해 로그아웃시킬 수 있다
//region logout
http
.logout() //Post Method
.logoutUrl("/logout") // 로그아웃 처리 url
.logoutSuccessUrl("/login") // 로그아웃 성공 후 이동페이지
.addLogoutHandler(new LogoutHandler() { // 로그아웃 핸들러
@Override
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
HttpSession session = request.getSession();
session.invalidate();
}
})
.logoutSuccessHandler(new LogoutSuccessHandler() { // 로그아웃 성공 후 핸들러
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
response.sendRedirect("/login");
}
})
.deleteCookies("JSESSIONID", "remember-me"); // 로그아웃 후 쿠키 삭제
// endregion
동작 플로우
LogoutFilter.class의 doFilter() 를 보면 config에서 addLogoutHandler, logoutSuccessHandler 에 오버라이딩한 메소드인 logout과 onLogoutSuccess를 호출하는 것을 확인 할 수 있다.
private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
if (requiresLogout(request, response)) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (this.logger.isDebugEnabled()) {
this.logger.debug(LogMessage.format("Logging out [%s]", auth));
}
this.handler.logout(request, response, auth);
this.logoutSuccessHandler.onLogoutSuccess(request, response, auth);
return;
}
chain.doFilter(request, response);
}
addLogoutHandler에서 세션을 제거 해주고 있지만 이 행위를 해주지 않아도 내가 만들어준 핸들러를 빠져나온 뒤 기본으로 존재하는 핸들러에서 세션을 제거해주고 있다. 아래 코드의 this.logoutHandlers 는 핸들러 목록이다.
@Override
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
for (LogoutHandler handler : this.logoutHandlers) {
handler.logout(request, response, authentication);
}
}
그 중에 첫번째 인덱스가 내가 만들어준 클래스명인 것을 확인할 수 있다.
4번째 인덱스의 SecurityContextHandler.class 의 logout() 를 보면 session이 null아니라면 제거하는 로직이 존재한다.
@Override
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
Assert.notNull(request, "HttpServletRequest required");
if (this.invalidateHttpSession) {
HttpSession session = request.getSession(false);
if (session != null) {
session.invalidate();
if (this.logger.isDebugEnabled()) {
this.logger.debug(LogMessage.format("Invalidated session %s", session.getId()));
}
}
}
SecurityContext context = SecurityContextHolder.getContext();
SecurityContextHolder.clearContext();
if (this.clearAuthentication) {
context.setAuthentication(null);
}
}
'무조건 따라하기 > Spring Boot 기반 Security' 카테고리의 다른 글
Spring Boot 기반으로 개발하는 Spring Security : RememberMeAuthenticationFilter (0) | 2023.04.13 |
---|---|
Spring Boot 기반으로 개발하는 Spring Security : Remember Me 인증 (0) | 2023.04.13 |
Spring Boot 기반으로 개발하는 Spring Security : UsernamePasswordAuthenticationFilter (0) | 2023.04.10 |
Spring Boot 기반으로 개발하는 Spring Security : Form Login 인증 (0) | 2023.04.09 |
Spring Boot 기반으로 개발하는 Spring Security : 보안 기능 구현 (0) | 2023.04.09 |