Context
I'm having some trouble with my application. We're using Spring Boot 2.4.10 and Spring Security 5.4.8. We use cookies to interact with the app.
We have a frontend application stored in src/main/resources
that, among other things, connects to a websocket endpoint exposed in /api/v1/notification
.
My configuration
application.properties
file:
# cookie-related settings
server.servlet.session.cookie.name=mySessionCookie
server.servlet.session.cookie.path=/
server.servlet.session.cookie.http-only=true
server.servlet.session.cookie.secure=true
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
private final String[] authorizedWithoutAuth = {
"/",
"/index.html",
"/static/**"
};
@Override
protected void configure(HttpSecurity http) throws Exception {
http.httpBasic()
.and()
.authorizeRequests()
.antMatchers(authorizedWithoutAuth).permitAll()
.anyRequest().authenticated()
.and()
.csrf().disable()
.and()
.logout().logoutUrl("/api/v1/logout").invalidateHttpSession(true)
.deleteCookies("mySessionCookie");
}
}
The problem
While no user is logged in, the frontend tries to reach periodically the websocket endpoint to open a connection.
The first api/v1/notification
ends redirected to the /error
endpoint, which returns an HttpServletResponse
with a 'Set-Cookie' header (I think this may be an anonymous cookie set in the first request?) and a 401 status. I cannot change this behaviour.
The following requests to api/v1/notification
use this cookie in the header (while user is not logged in). These requests are also redirected to the /error
endpoint, which returns each time an HttpServletResponse
with 401 status but here, no 'Set-Cookie' header is included.
Once the user logs in with Authorization headers, a correct cookie is set by the response and used in the following requests.
The thing is, sometimes the set cookie suddenly changes again to an invalid one, and the following requests, done with this new invalid cookie, turn into a redirection to the login page.
After checking the code, it seems there is an old api/v1/notification
request (previous to the login request) taking place, with an invalid cookie (the anonymous one, present before login).
This request is redirected to the /error
endpoint: here, once again the HttpServletResponse
has 401 status and is containing a Set-Cookie header that is modifying the browser cookie (replacing the good one).
Following is a scheme of the problem, to hopefully make it easier to understand.
Expected behaviour
I would like to prevent an unauthorized request from setting the session cookie.
It's ok if a previous request responds with a 401 code, but I don't want it to change the current set cookie.
I tried...
I tried extending the
ErrorController
by returning aResponseEntity
with all the headers present in the inputHttpServletResponse
except for the 'Set-Cookie' header. This doesn't work.I also tried modifying my configuration to disable anonymous requests:
@Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { private final String[] authorizedWithoutAuth = { "/", "/index.html", "/static/**" }; @Override protected void configure(HttpSecurity http) throws Exception { http.httpBasic() .and() .anonymous().disable() .authorizeRequests() // .antMatchers(authorizedWithoutAuth).permitAll() I had to remove these from here, and include them in the method below .anyRequest().authenticated() .and() .csrf().disable() .and() .logout().logoutUrl("/api/v1/logout").invalidateHttpSession(true) .deleteCookies("mySessionCookie"); } @Override public void configure(WebSecurity web) throws Exception { web.ignoring().antMatchers(authorizedWithoutAuth); } }
but the session cookie is still set this way too, with 401 requests.
I also tried using
@ControllerAdvice
to handle the exceptions, but these are thrown by Spring Security in theAbstractSecurityInterceptor
, as learnt in this response.
Thak you all for your time. Sorry for the post length :)