Why is Spring Security's SessionManagementFilter running when my session creation policy is set to STATELESS?
Asked Answered
F

1

5

I have a J2EE REST-based web application that uses Spring Security 4.0.1.RELEASE. I am configuring Spring Security with a Java-based configuration and have set the session creation policy to STATELESS like so:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(secureEnabled=true, prePostEnabled=true, jsr250Enabled=true, order=1)
public class DefaultSecurityBeansConfig extends WebSecurityConfigurerAdapter {
    // ...
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and()...; // additional config omitted for brevity
        // ...
    }
    // ...
}

After reading this article about Spring Security session management, I believe that the SessionManagementFilter filter should not be running in Spring Security's filter chain. But it definitely is. I can set a breakpoint in that class's doFilter method, and it is run on every request to the server.

What is going on here? The fact that this filter is running is causing other unexpected behavior in my app that I thought had been configured away.

Thanks.

Fructification answered 12/6, 2018 at 11:54 Comment(6)
Your understanding is wrong. It still will run but it won't create a session or store stuff in the session. There will be a SessionManagementFilter with a NullSecurityContextRepository which won't store it. So basically it will always run but depending on the configuration it will do something or not.Uriia
Ok, that makes some sense. But when it runs, it's hardly a no-op. The doFilter method calls an onAuthentication method, which has registered as its only delegate strategy the ChangeSessionIdAuthenticationStrategy. This would seem to conflict with my STATELESS session creation policy. I don't have a session fixation strategy explicitly set, which if I'm not mistaken will default to migrateSession, but this behavior implies I'm somehow using changeSessionId. I may end up posting a new question with these findings.Fructification
Which shouldn't be an issue as you don't create a session (at least Spring Security doesn't create a session which doesn't mean that there isn't something else creating a session!) that should basically be a noop. As the strategy first checks if there already is a session if not, do nothing. The fact that Spring Security operates in stateless mode doesn't mean the rest of your application automatically becomes stateless!Uriia
To be sure, my appication is creating a session using an always-running servlet filter (((HttpServletRequest) request).getSession()). And this ChangeSessionIdAuthenticationStrategy that is running keeps changing my JSESSIONID. According to Spring docs, the NEVER value of SessionCreationPolicy is supposed to make use of the HttpSession if it exists, while the STATELESS value "will never create an HttpSession and will never use it to obtain the SecurityContext". To me, that sounds like it shouldn't be messing with my JSESSIONID. I'm just really confused why it's interfering.Fructification
It is interfering because operating in stateless mode and prevent session fixation attacks are 2 different things. What is happening here is that Spring Security detects the session and by default the security applied to prevent session hijacking is to change the session id. If you don't want that specify it to be none through sessionFixation().none(). However this will make your application less secure and vulnerable to session fixation attacks. I fail to see why changing the sessionid would break things, what is breaking be fixed instead of making your app less secure.Uriia
Thanks. Can you consolidate your comments into an answer that I can accept?Fructification
U
6

When using Spring Security, session management is broader than storing the authenticated user in the session (as explained in the Session Management Section of the Spring Security Guide).

HTTP session related functionality is handled by a combination of the SessionManagementFilter and the SessionAuthenticationStrategy interface, which the filter delegates to. Typical usage includes session-fixation protection attack prevention, detection of session timeouts and restrictions on how many sessions an authenticated user may have open concurrently.

Saying sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS) doesn't mean that your application is stateless, it means that Spring Security won't create a session. If there is something else in your application still creating a session, Spring Security will try to protect it from a session-fixation attack.

How a session-fixation attack is done depends on the configured strategy; the default is to change the session identifier on each request. In Servlet 3.1 and newer containers, the ChangeSessionIdAuthenticationStrategy is the default if no explicit configuration is done. In Servlet 3.0 and below, the default is migrateSession.

You can disable session-fixation protection by doing sessionFixation().none(); however, you have to question if that is what you really want as that, potentially, makes your application less safe.

Depending on what breaks/fails you might want to fix that instead of making your application less secure.

Uriia answered 13/6, 2018 at 16:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.