Spring Security는 기본적으로 DefaultLogoutPageGeneratingFilter를 통해 로그아웃 페이지를 제공하며 GET /logout으로 접근이 가능하다.
로그아웃 실행은 기본적으로 `POST` /logout으로만 가능하며 csrf 기능을 비활성화 할 경우 또는 RequestMatcher 를 사용할 경우 GET, PUT, DELETE 모두 가능하다.
로그아웃 필터를 거치지 않고 MVC에서 커스텀으로 구현할 수 있으며, 로그인 페이지를 커스텀으로 구현했을 경우 로그아웃 또한 커스텀으로 구현해야 한다.
아래는 logout config 설정들이다.
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(auth -> auth
.requestMatchers("/logoutSuccess").permitAll()
.anyRequest().authenticated());
http.formLogin(Customizer.withDefaults());
http.logout(logout -> logout
.logoutUrl("/logout") // 로그아웃이 발생하는 URL지정 (default : /logout)
.logoutRequestMatcher(new AntPathRequestMatcher("/logout", "POST")) // logoutUrl과 logoutRequestMatcher가 둘다 설정되어있을경우 RequestMatcher가 우선적으로 실행된다.
.logoutSuccessUrl("/logoutSuccess") // 로그아웃이 된 후 리다이렉트가 될 URL지정 (default: /login?logout)
.logoutSuccessHandler(new LogoutSuccessHandler() { // 사용할 logout handler를 설정한다. handler는 위에서 한 설정보다 우선적으로 실행된다.
@Override
public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
response.sendRedirect("/logoutSuccess"); // 이렇게 되면 위에서 설정한 logoutSuccessUrl은 적용되지 않는다.
}
})
.deleteCookies("JSESSIONID", "remember-me") // 로그아웃 시 삭제할 쿠키를 지정할 수 있다.
.invalidateHttpSession(true) // HttpSession을 무효화 한다. (default : true)
.clearAuthentication(true) // 로그아웃 시 SecurityContextLogoutHandler가 인증객체(Authentication)을 삭제한다.
.addLogoutHandler(new LogoutHandler() {
@Override
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
HttpSession session = request.getSession();
session.invalidate();
SecurityContextHolder.getContextHolderStrategy().getContext().setAuthentication(null); // security context에 저장된 authentication 객체를 없앤다.
SecurityContextHolder.getContextHolderStrategy().clearContext(); // security context 초기화를 한다.
}
})
.permitAll()); // logoutUrl(), RequestMatcher()의 URL에 대한 모든 접근을 허용한다.
return http.build();
}
Java
복사
로그아웃 할 때 별 다른 커스텀 기능이 없다면 따로 설정을 할 필요는 거의 없다.
만약 필요하다면 위와 같은 설정들을 해주면 된다.
logoutSuccessHandler
이 핸들러는 이름에서도 알 수 있듯이 logout을 성공하게 되면 실행되는 핸들러이다. 위에서는 로그아웃 시 /logoutSuccess로 리다이렉트 하도록 설정이 했다.
(주의할점은 로그아웃을 할 경우 인증 상태가 사라지기 때문에 http.anyRequest().authenticaiton() 설정으로 인해 페이지 이동이 정상적으로 안될 수 있다. 그래서 http.requestMatcher("logoutSuccess").permitAll() 설정을 따로 해주었다.)
addLogoutHandler
설정 중 addLogoutHandler 설정이 있는데, 로그아웃을 할 때 Spring Security 내부적으로 동작하는 핸들러가 몇가지 있다. 그 핸들러들이 실행될 때 추가적으로 커스텀하여 실행시킬 수 있는 설정이다.
위의 코드에서는 로그아웃을 하게 되면 security context에서 authentication 객체를 삭제하고 security context를 초기화하는 코드를 넣었는데 이 작업은 원래 동작하는 핸들러중 SecurityContextLogoutHandler라는 핸들러에서 실행되는 코드임으로 따로 작성은 불필요하다. (위에서는 그냥 예시를 위해 작성한 코드이다.)