- 스프링 시큐리티는 기본적으로 DefaultLogoutPageGeneratingFilter 를 통해 로그아웃 페이지를 제공
→ “ GET / logout ” URL로 접근 가능- 폼 로그인 사용 시 DefaultLoginPageGeneratingFilter, DefaultLogoutPageGeneratingFilter 두 개가 자동 생성
- 로그아웃 실행은 기본적으로 “ POST / logout “으로만 가능하나 CSRF 기능을 비활성화 또는 RequestMatcher 사용 시 GET, PUT, DELETE 모두 가능
- CSRF : 누군가가 사용자의 세션을 가지고 악의적인 목적으로 사용하는 것을 막기 위한 보안 기술(?)
- 로그아웃 필터를 거치지 않고 스프링 MVC 에서 커스텀 하게 구현할 수 있으며, 로그인 페이지가 커스텀하게 생성될 경우 로그아웃 기능도 커스텀하게 구현
- 로그인과 로그아웃은 세트이기 때문에 로그인 페이지가 커스텀하게 생성될 경우 로그아웃 기능도 커스텀하게 구현 필요
logout() API
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.authorizeHttpRequests(auth -> auth
.requestMatchers("/logoutSuccess").permitAll()
.anyRequest().authenticated())
.formLogin(Customizer.withDefaults())
.logout(logout -> logout
.logoutUrl("/logoutProc")
.logoutRequestMatcher(new AntPathRequestMatcher("/logoutProc","POST"))
.logoutSuccessUrl("/logoutSuccess")
.logoutSuccessHandler((request, response, authentication) -> {
response.sendRedirect("/logoutSuccess");
})
.deleteCookies("JSESSIONID", "CUSTOM_COOKIE")
.invalidateHttpSession(true)
.clearAuthentication(true)
.addLogoutHandler((request, response, authentication) -> {})
.permitAll()
)
;
return http.build();
}
Method | Description |
.logoutUrl("/logoutProc") | 로그아웃이 발생하는 URL 지정 (기본값 /logout) → form action과 동기화 |
.logoutRequestMatcher(new AntPathRequestMatcher("/logoutProc","POST")) | 로그아웃이 발생하는 RequestMatcher 지정, logoutUrl보다 우선 → Http Method(GET,POST 등)를 지정하지 않을 경우 어떤 메소드든 로그아웃 가능 |
.logoutSuccessUrl("/logoutSuccess") | 로그아웃 성공 후 리다이렉션 될 URL 지정 (기본값 /login?logout) |
.logoutSuccessHandler(logoutSuccessHandler) | 사용할 LogoutSuccessHandler 지정 → 지정 시 logoutSuccessUrl 무시 |
.deleteCookies("JSESSIONID“, “CUSTOM_COOKIE”) | 로그아웃 성공 시 제거할 쿠키의 이름 지정 |
.invalidateHttpSession(true) | HttpSession 무효화 (기본값 true) |
.clearAuthentication(true) | 로그아웃 시 SecurityContextLogoutHandler가 인증(Authentication)을 삭제해야하는 지 여부를 명시 |
.addLogoutHandler(logoutHandler) | 기존의 로그아웃 핸들러 뒤에 새로운 LogoutHandler 추가 → 사용자 정의 핸들러를 추가할 경우 기존 LogoutHandler가 대체 되는 것이 아니라 기존 것이 수행된 후 사용자 정의 LogoutHandler 실행 |
.permitAll() | logoutUrl(), RequestMathcher()의 URL에 대한 모든 사용자 접근 허용 |
LogoutFilter
- 클라이언트가 로그아웃 버튼 클릭
- LogoutFilter 수신
- RequestMatcher → 요청 정보가 매칭 되는 지 확인(POST 방식인지, /logout인지)
- 매칭되지 않을 경우 다음 필터(chain.doFilter)
- LogoutHandler → 다음 여러 개의 핸들러 실행
- CookieClearingLogoutHandler
- SecurityConfig → 개발자가 생성한 설정 클래스
- CsrfLogoutHandler
- SecurityContextLogoutHandler
- LogoutSuccessEventPublishingLogoutHandler
- LogoutSucessHandler → 어디로 이동할 것인지 URL을 지정
- 기본값 : /login?logout
정리
- 기본 제공 로그아웃은 POST 방식으로 /logout 이지만, RequestMatcher 사용 또는 csrf 미 사용(disable) 시 GET, PUT, DELETE 방식으로도 로그아웃 가능
- 로그인과 로그아웃은 한 세트이기 때문에 사용자 정의 로그인 페이지를 사용할 경우, 로그 아웃도 구현 필요
- 로그아웃 성공 후 단순히 URL만 이동시킬 목적이라면 .logoutSuccessUrl() 메서드를 사용하고, HttpServletRequest / HttpServletResponse 등의 사용이 필요하다면 .logoutSuccessHandler() 메서드 사용
'Language > Spring Security' 카테고리의 다른 글
인증 - Authentication (0) | 2024.07.16 |
---|---|
요청 캐시 - RequestCache / SavedRequest (0) | 2024.07.16 |
익명 사용자 - anonymous() (0) | 2024.07.16 |
기억하기 인증 필터 - RememberMeAuthenticationFilter (0) | 2024.07.16 |
기억하기 인증 - rememberMe() (0) | 2024.07.16 |