1. Introduction
Spring Security is the standard for securing Spring-based applications. It has several features to manage user's authentication, including login and logout.
In this tutorial, we'll focus on manual logout with Spring Security.
We'll assume that readers already understand the standard Spring Security logout process.
2. Basic Logout
When a user attempts a logout, it has several consequences on its current session state. We need to destroy the session with two steps:
- Invalidate HTTP session information.
- Clear SecurityContext as it contains authentication information.
Those two actions are performed by the SecurityContextLogoutHandler. Let's see that in action:
@Configuration public class DefaultLogoutConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .logout(logout -> logout .logoutUrl("/basic/basiclogout") .addLogoutHandler(new SecurityContextLogoutHandler()) ); } }
Note that SecurityContextLogoutHandler is added by Spring Security by default – we just show it here for clarity.
3. Cookie Clearing Logout
Often, a logout also requires us to clear some or all of a user's cookies. We can create our own LogoutHandler that loops through all cookies and expires them on logout:
@Configuration public class AllCookieClearingLogoutConfiguration extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .logout(logout -> logout .logoutUrl("/cookies/cookielogout") .addLogoutHandler((request, response, auth) -> { for (Cookie cookie : request.getCookies()) { String cookieName = cookie.getName(); Cookie cookieToDelete = new Cookie(cookieName, null); cookieToDelete.setMaxAge(0); response.addCookie(cookieToDelete); } }) ); } }
On the other hand, Spring Security provides CookieClearingLogoutHandler which is a ready-to-use logout handler for cookie removal.
4. Clear-Site-Data Header Logout
Alternatively, we can use a special HTTP response header to achieve the same thing; this is where the Clear-Site-Data header comes into play. The Clear-Data-Site header clears browsing data (cookies, storage, cache) associated with the requesting website.
@Configuration public class ClearSiteDataHeaderLogoutConfiguration extends WebSecurityConfigurerAdapter { private static final ClearSiteDataHeaderWriter.Directive[] SOURCE = {CACHE, COOKIES, STORAGE, EXECUTION_CONTEXTS}; @Override protected void configure(HttpSecurity http) throws Exception { http .logout(logout -> logout .logoutUrl("/csd/csdlogout") .addLogoutHandler(new HeaderWriterLogoutHandler(new ClearSiteDataHeaderWriter(SOURCE))) ); } }
Note that storage cleansing might corrupt the application state when we clear only one type of storage. Therefore, due to Incomplete Clearing, the header is only applied if the request is secure.
5. Conclusion
Spring Security has many built-in features to handle authentication scenarios. It always comes in handy to master how to use those features programmatically.
As always, the code for these examples is available over on GitHub.