I have a HTML form that issues REST API calls to a Spring Boot backend. I'm using Spring Session to handle concurrent logins by the same user. If I use expiredUrl in the below code, I get redirected to the login.html page when the current session has expired. This works fine when I click on menu items that request for a HTML page.
If I'm already on a page and I click a button that issues an AJAX call to the server, I get a 302(fetch/Redirect) status followed by the login.html page with a 200 status when the session has expired. So the Ajax call is getting a response of 200, which is not correct. I replaced expiredUrl with expiredSessionStrategy in the code below, but expiredSessionStrategy is not getting invoked at all. If any of you know the reason or see a flaw in my code, please let me know. I searched the spring session documentation for expiredSessionStrategy, but was not able to find anything.
I found a couple of articles on stackoverflow that suggest using AjaxAwareAuthenticationEntryPoint to get a custom response for an Ajax call on session expiry. I will try this approach, but I would like to know why expiredSessionStrategy is not getting called in my case.
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.csrf(..)
.authorizeHttpRequests(..)
.oauth2Login(oauth2 -> {
oauth2
.userInfoEndpoint(userInfo -> userInfo
.oidcUserService(this.oidcUserService())
)
.loginPage("/login.html")
.failureUrl("/loginFailure")
.successHandler(customOauth2SuccessHandler) ;
}
)
.logout(...)
.sessionManagement((sessions) -> sessions
.maximumSessions(1)
.sessionRegistry(this.sessionRegistry())
.expiredSessionStrategy( event ->
{
String URI = event.getRequest().getRequestURI();
System.out.println("URI="+URI);
if (URI.endsWith(".html"))
event.getResponse().sendRedirect("/login.html?msgCode=4");
else
{
event.getResponse().setContentType("application/json");
event.getResponse().sendError(440, "Session has expired. Please login again !");
}
}
)
//.expiredUrl("/login.html?msgCode=4")
);
return http.build();
}