The new Certification Class of Learn Spring Security is out:

>> CHECK OUT THE COURSE

1. Overview

In this article, we’re going to illustrate how Spring Security allows us to control our HTTP Sessions.

This control ranges from a session timeout to enabling concurrent sessions and other advanced security configs.

Further reading:

Retrieve User Information in Spring Security

How to get the currently logged in user with Spring Security.

Read more

Spring Security Remember Me

Cookie Remember Me example with Spring Security.

Read more

Spring Security Logout

Spring Logout Example - how to configure the logout url, the logout-succcess-url and how to use a custom bean to handle advanced logout scenarios.

Read more

2. When Is The Session Created?

We can control exactly when our session gets created and how Spring Security will interact with it:

  • always – a session will always be created if one doesn’t already exist
  • ifRequired – a session will be created only if required (default)
  • never – the framework will never create a session itself but it will use one if it already exists
  • stateless – no session will be created or used by Spring Security
<http create-session="ifRequired">...</http>

Java configuration:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
}

It’s very important to understand that this configuration only controls what Spring Security does – not the entire application. Spring Security may not create the session if we instruct it not to, but our app may!

By default, Spring Security will create a session when it needs one – this is “ifRequired“.

For a more stateless application, the “never” option will ensure that Spring Security itself will not create any session; however, if the application creates one, then Spring Security will make use of it.

Finally, the strictest session creation option – “stateless” – is a guarantee that the application will not create any session at all.

This was introduced in Spring 3.1 and will effectively skip parts of the Spring Security filter chain – mainly the session related parts such as HttpSessionSecurityContextRepository, SessionManagementFilter, RequestCacheFilter.

These more strict control mechanisms have the direct implication that cookies are not used and so each and every request needs to be re-authenticated. This stateless architecture plays well with REST APIs and their Statelessness constraint. They also work well with authentication mechanisms such as Basic and Digest Authentication.

3. Under The Hood

Before executing the Authentication process, Spring Security will run a filter responsible with storing the Security Context between requests – the SecurityContextPersistenceFilter. The context will be stored according to a strategy – HttpSessionSecurityContextRepository by default – which uses the HTTP Session as storage.

For the strict create-session=”stateless” attribute, this strategy will be replaced with another – NullSecurityContextRepository – and no session will be created or used to keep the context.

4. Concurrent Session Control

When a user that is already authenticated tries to authenticate again, the application can deal with that event in one of a few ways. It can either invalidate the active session of the user and authenticate the user again with a new session, or allow both sessions to exist concurrently.

The first step in enabling the concurrent session-control support is to add the following listener in the web.xml:

<listener>
    <listener-class>
      org.springframework.security.web.session.HttpSessionEventPublisher
    </listener-class>
</listener>

Or define it as a Bean – as follows:

@Bean
public HttpSessionEventPublisher httpSessionEventPublisher() {
    return new HttpSessionEventPublisher();
}

This is essential to make sure that the Spring Security session registry is notified when the session is destroyed.

To enable the scenario which allows multiple concurrent sessions for the same user the <session-management> element should be used in the XML configuration:

<http ...>
    <session-management>
        <concurrency-control max-sessions="2" />
    </session-management>
</http>

Or, via Java configuration:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.sessionManagement().maximumSessions(2)
}

5. Session Timeout

After the session has timed out, if the user sends a request with an expired session id, they will be redirected to a URL configurable via the namespace:

<session-management>
    <concurrency-control expired-url="/sessionExpired.html" ... />
</session-management>

Similarly, if the user sends a request with a session id which is not expired, but entirely invalid, they will also be redirected to a configurable URL:

<session-management invalid-session-url="/invalidSession.html">
    ...
</session-management>

The corresponding Java configuration:

http.sessionManagement()
  .expiredUrl("/sessionExpired.html")
  .invalidSessionUrl("/invalidSession.html");

6. Prevent using URL Parameters for Session Tracking

Exposing session information in the URL is a growing security risk (from place 7 in 2007 to place 2 in 2013 on the OWASP Top 10 List).

Starting with Spring 3.0, the URL rewriting logic that would append the jsessionid to the URL can now be disabled by setting the disable-url-rewriting=”true” in the <http> namespace.

Alternatively, starting with Servlet 3.0, the session tracking mechanism can also be configured in the web.xml:

<session-config>
     <tracking-mode>COOKIE</tracking-mode>
</session-config>

And programmatically:

servletContext.setSessionTrackingModes(EnumSet.of(SessionTrackingMode.COOKIE));

This chooses where to store the JSESSIONID – in the cookie or in a URL parameter.

7. Session Fixation Protection with Spring Security

The framework offers protection against typical Session Fixation attacks by configuring what happens to an existing session when the user tries to authenticate again:

<session-management session-fixation-protection="migrateSession"> ...

The corresponding Java configuration:

http.sessionManagement()
  .sessionFixation().migrateSession()

By default, Spring Security has this protection enabled (“migrateSession“) – on authentication a new HTTP Session is created, the old one is invalidated and the attributes from the old session are copied over.

If this is not the desired behavior, two other options are available:

  • when “none” is set, the original session will not be invalidated
  • when “newSession” is set, a clean session will be created without any of the attributes from the old session being copied over

8. Working with the Session

8.1. Session Scoped Beans

A bean can be defined with session scope simply by using the @Scope annotation on beans declared in the web-Context:

@Component
@Scope("session")
public class Foo { .. }

Or with XML:

<bean id="foo" scope="session"/>

Then, the bean can simply be injected into another bean:

@Autowired
private Foo theFoo;

And Spring will bind the new bean to the lifecycle of the HTTP Session.

8.2. Injecting the Raw Session into a Controller

The raw HTTP Session can also be injected directly into a Controller method:

@RequestMapping(..)
public void fooMethod(HttpSession session) {
    session.addAttribute(Constants.FOO, new Foo();
    //...
    Foo foo = (Foo) session.getAttribute(Constants.Foo);
}

8.3. Obtaining the Raw Session

The current HTTP Session can also be obtained programmatically via the raw Servlet API:

ServletRequestAttributes attr = (ServletRequestAttributes) 
    RequestContextHolder.currentRequestAttributes();
HttpSession session= attr.getRequest().getSession(true); // true == allow create

9. Conclusion

In this article, we discussed managing Sessions with Spring Security. Also, the Spring Reference contains a very good FAQ on Session Management.

As always, the code presented in this article is available over on Github. This is a Maven based project, so it should be easy to import and run as it is.

Go deeper into Spring Security with the course:

>> LEARN SPRING SECURITY

Sort by:   newest | oldest | most voted
Science vine
Guest

Thank you for your great explanations.

Joe Eugene
Guest

Thanks for great blog!

How do we get spring security to share session in same domain and context path?
example.com/app/test1 (test1.war)
example.com/app/test2 (test2.war)

User logs to test1 and should not be asked to login to test2. Tried setting cookie path to “/app/” and test2 spring security receives cookie set by test1 but does not associate with previous http session and redirects to test2 login.

How can this be solved without CAS/SSO/Database session or Remember me implementation?

Eugen Paraschiv
Guest

There’s a good piece I covered in last weeks review on externalizing the session information with the new spring-session project. Hope it helps. Cheers,
Eugen.

AK
Guest

This is really a great blog. It does help me to understand session management in spring security.

I want to implement the spring security in RESTful service. A third party will validate (so we will use preauth in spring-secuirty) user and will pass the token to our app.

But we still want to store some cookie between the requests. How can we do that? I read that RESTful service should use create-session=”stateless” to be stateless?

Eugen Paraschiv
Guest
This is a complex topic, and there’s no one answer. If you’re thinking from the point of view of strict adherence to REST as architectural constraint, then the server side should be entirely stateless – so no cookies. Every request passes in credentials (if we’re talking about – for example – Digest auth). Of course that does come with complexity and potential vulnerabilities with managing these credentials on the client side. The proxy solution – discussed in this ongoing series on the Spring blog addresses that (I think it was article 4). Alternatively – you can go the cookie route… Read more »
crime_master_gogo
Guest

this is helpful. more examples on implementation will be great.

Eugen Paraschiv
Guest

Glad it’s helpful. You can find not only examples but a full working project with Spring Security and the session management configs already done on github (link at the end of the article).
Cheers,
Eugen.

Matt Krevs
Guest

Nice work again. I didnt know about the expired-url feature.

One small typo. Change “the application can deal with that even in one of a few ways” to “the application can deal with that event in one of a few ways”.

Eugen Paraschiv
Guest

Hey Matt – nice catch, thanks. Corrected.

AKS
Guest

mvn build only for spring-security-mvn-session and trying to open homepage.jsp but

HTTP Status 404 –
description The requested resource is not available.

Any suggestion how to proceed ??

Eugen Paraschiv
Guest

Hey AKS – I just tried to run that project and access the page – I was able to do that without any problems at I’m able to log in here: http://localhost:8080/spring-security-mvc-session/login.html
How exactly are you deploying? Are you doing anything from within the IDE or perhaps using a stand-alone server? Cheers,
Eugen.

Mohsen
Guest

hi
I need to use cookies instead of httpsession with spring security, that is for using cookies for stateless authentication.
Do anyone have any idea of how to do it or provide any help?

Eugen Paraschiv
Guest
Hey Mohsen – a few things to note related to your question. First – cookies and httpsession don’t have a one-or-the-other type of relation. In fact – the session usually works alongside the client side cookie. Second – if you are considering a stateless authentication mechanism – then httpsession is not the way to go, because the httpsession is state. Stateless would mean that you don’t have any kind of httpsession and that you simply send your credentials along with every request. Hope that clears up a few things – I would further recommend you do some additional, in depth… Read more »
wpDiscuz