Imagine we have a customized way of authentication for the below URLs.
Path1: http://www.example.com/company1/home
Path2: http://www.example.com/company2/home
Path3: http://www.example.com/company3/home
.
.
.
PathX: http://www.example.com/companyX/home
And companies have different sets of data.
Now, I want spring security to create separate sessions for each of the above urls based on http://www.example.com/{company}/
. So, when I login into different URLs in separate browser tabs, I can work with all of them. I want to keep all sessions alive and avoid session termination after the authentication with the other URLs.
How to achieve this?
You can achieve this behavior by overriding the behavior of DefaultCookieSerializer#getCookiePath method, and set your own cookiePath strategy
Duplicate the DefaultCookieSerializer class and name it as MyCookieSerializer. (You can't override getCookiePath method in your child class because that method is private)
public class MyCookieSerializer implements CookieSerializer {
//..codes above
private String getCookiePath(HttpServletRequest request) {
if (this.cookiePath == null) {
//SecurityUtils#getSiteName: this method just extract the company name from the path. You may have your own strategy
String siteName = SecurityUtils.getSiteName(request.getServletPath());
return siteName != null ? "/" + siteName + "/" : "/";
}
return this.cookiePath;
}
//..codes below
}
Create a bean of your MyCookieSerializer
@EnableWebSecurity(debug = true)
@Configuration
@ComponentScan(basePackages = {
"com.something"
})
@PropertySource( { "classpath:application.properties" } )
public class WebSecurityConfig {
@Value("${cookie.max.age}")
private int cookieMaxAge;
@Bean
public CookieSerializer cookieSerializer() {
MyCookieSerializer marlin = new MyCookieSerializer();
marlin.setCookieMaxAge(cookieMaxAge);
return marlin;
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http, MvcRequestMatcher.Builder mvc) throws Exception {
return http
.sessionManagement(httpSecuritySessionManagementConfigurer -> {
httpSecuritySessionManagementConfigurer.sessionFixation().none();
httpSecuritySessionManagementConfigurer.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
httpSecuritySessionManagementConfigurer.maximumSessions(-1);
})
.authorizeHttpRequests(auth -> auth
.requestMatchers(
antMatcher("/"),
antMatcher("/css/**"),
antMatcher("/fonts/**"),
antMatcher("/js/**"),
antMatcher("/images/**"),
antMatcher("/*/")
).permitAll()
.requestMatchers(antMatcher("/{id}/**")).authenticated())
//Your Authentication method codes (e.g formLogin, basic, etc)
.build();
That's it.
I explain here how this works:
This works in all scenarios. For example if we logout company1 which is on tab1, company2 will still works and its session will remain active.
I hope I explain the process properly for you.