The Master 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.

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.

The implementation of this Spring Security Session Management Tutorial can be downloaded as a working sample project.

This is an Eclipse based project, so it should be easy to import and run as it is.

The Master Class "Learn Spring Security" is out:

>> CHECK OUT THE COURSE

  • Science vine

    Thank you for your great explanations.

    • Joe Eugene

      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?

      • 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

          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?

          • 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 and not worry about adherence to REST so much. That has the advantage of being a well-known path and leverages the browser support for cookies. So – at the end of the day, it’s a choice, like everything else.
            Best of luck with your app. Cheers,
            Eugen.

  • crime_master_gogo

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

    • 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

    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”.

  • AKS

    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 ??

  • Mohsen

    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?

    • 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 reading about all of these concepts – it will definitely set you on the right track for your implementation. Cheers,
      Eugen.

  • Anant Navagale

    Hi,
    I am using spring 4 and spring security 3.2… I want to validate session on every request coming on tomcat server. I wan to check
    1) current request is coming from same IP address from where authentication happened
    2) When authentication happened, I stored some values like user id, some keys (in encrypted format). I want to validate these values in every request.
    3) I also want to use server side cookies and validate them on every request.
    4) If session is expired I want user be prompted to enter authentication to continue the work
    5) If any of above condition is failed, I want user show that message.

    How can I do this using spring session management.

    Previously I was doing this using interceptor of struts 2.0 I have now removed struts and using purely spring only.

    • Hey Anant,

      1. You can write security expressions to check IP addresses, but for dynamic checking like that, there’s nothing out of the box. You’ll need to:
      – keep track of the IP address of the first authentication – a simple cache would make sense, or the DB of you need to re-use that later on
      – write your custom check logic, probably in a custom auth provider

      2. Same – once you do one custom check, it’s easy to add more

      3. not sure what you mean by server side cookie – cookies will implicitly be sent to the client; if you’re just thinking of validating them on the server side, that’s fine, but they won’t stay on the server side

      4. Again – that’s a mechanism that you’ll have to handle on your own on the client side; on the server side you should listen for a SessionDestroyedEvent

      5. If any of the conditions fail, you’ll presumably want to sent back the 401 back to the client; you can of course provide the detailed message in that response as well; then the client side should simply use that to display it to the client

      Hope that helps. It’s a fair bit of custom logic, but it’s definitely doable. Cheers,
      Eugen.

  • Bill

    Eugen – again great blog! I’d like to see a more in depth discussion on session scoped beans, particularly when using them with beans that are not session scoped, especially singletons. You show a session scoped bean @Autowired in another bean, which is fine, as long as its also session scoped. If they aren’t you would have to do something like using a scoped proxy. The reason I’m bringing this up is that I’ll bet I’ve been hacking this for years and I’d love to see a best practices implementation.

    Thanks,
    Bill

    • Hey Bill – glad you like the blog. On the session scoped beans – you’re right, it can get tricky. The reason I didn’t have that in my article TODO list is that it can also be tricky finding a good usecase – one that’s general enough that more than a few people would care about, but still practical and specific. Do you have anything in mind? What are hou trying to do with session scoped beans in particular? I mostly used them in ecommerce projects – that might be a good way to go.
      Thanks for the interesting feedback. Cheers,
      Eugen.

      • Bill

        Eugen you’re right, the use of scopes other than singleton can be pretty esoteric. In my latest requirement for a session scoped bean I needed to remember that a particular session had been authorized using Ldap as opposed to siteminder and the particulars of the Ldap server (as authorization would also need to be done using Ldap). How about s shopping cart? Maybe a larger discussion on bean scopes would be more interesting. Why wouldn’t I use a prototype scoped bean as the user’s ticket to a ballgame? The spring folks added a new scope for their webflow (I think its flow scoped), what problem did that solve? I have never seen a complete discussion of this topic even in the Spring in Action and I would love to see it all laid out by someone who really knows it. Then I could stop hacking and do it right.

        Bill

        • A shopping cart is what I had in mind as well when I mentioned ecommerce – adding it to the TODO list. As for a discussion on the broader usage of scopes (probably not going all the way into Spring Web Flow though) is also a good idea. I’ll start with the shopping cart first and then think about coming at the problem from a higher level. Cheers,
          Eugen.

  • n99

    Hi – even though this great post is about security I also have a question about sessions for holding data. How would you recommend getting around this problem – something I have always thought spring mvc should support out of the box…http://duckranger.com/2012/11/add-conversation-support-to-spring-mvc/.

    Would u write own session handling implementation, use DTOs with their extra work, or would session scoped beans and direct controller interaction with the HttpSession be the way to go? cheers

    • I would go for DTOs and lean towards granular persistence rather than session based conversations. But – that’s definitely not the only way to do it, just my own preference.
      Hope that helps. Cheers,
      Eugen.

      • n99

        Thanks for that. One quick question – does that mean if you are using JSR-303 bean validation you must have your annotations on your DTO or Entity…..?

        • DTO – fail fast is the way to go here – so – wherever possible, go for DTO.

  • yathirigan

    If i have to develop a ‘Distributed Session Management’ feature (just like Distributed Cache) for my application, can Spring Security component alone help me implement it ? or should i use ‘Spring Session’ for it ? assuming that i will not need ‘Spring Security to implement my security features.

    • Yes, you should definitely use Spring Session for it – that’s exactly what it was implemented.

  • Hey Sandeep – first, about the session. The session you’re going to see once a user authenticates is different then the when they have anonymous access to the public pages on your site. So you could just ignore the original session – if you don’t have any strong reason to stop it from being created.
    Next – on what gets served in your root, you can control that from your web.xml (or Java equivalent), or – yes, you could map a controller on that path as well. To go into specifics, a StackOverflow question with some additional details would be better (and just follow up with the question here or over email with me).
    Hope that helps. Cheers,
    Eugen.

    • sandeep pandey

      Thanks Eugen, Yes It helped but not yet crystal clear. Let me describe specific scenario. I’v configured filter which performs session checking & redirects to GET /login and then GET /login delivers login.jsp, here while rendering jsp it creates session. So from here onwards my session checking fails in Filter because session already exists, so filter allows to access resources. My problem can be solved if spring doesn’t create session while rendering JSP page. As you said to “ignore original session”, but how can filter differentiate whether it’s default session or session created post authentication?. The solution which i see is to bypass the session created by spring and put some special token on session post authentication and application shall consider special token as session authenticator, but i’m afraid that might make app unstable at some stage if i mix these 2 approach or session. Please let me know what is your thought on this ASAP as i’m stuck on project. Would appreciate if you could write an article on it. I’m using spring 4.

      Thanks

      • Hey Sandeep – that’s quite a scenario 🙂
        Let’s do this – let’s move it off here and over to StackOverflow.
        Let’s also make it a bit easier to parse, so maybe more list-oriented. Then, shoot me a quick email with the link and I’d be happy to have a look. Cheers,
        Eugen.

  • Daniel Herráez

    Hi Eugen, great post. I have a problem in my app with the use of sessions. I have an app that have multiple login forms because there are multiple user roles. The problem is that I access with a user with the role X, then, in the same browser (in another tab), I try to log in when another user in a login form of role Y, and the login fails intentionally (typing a wrong password). Then, when I go to the tab of the authenticated user, if I click in a menu option, the app throw the user to the login page.
    I think that the j_spring_security_check, when the authentication fails, invalidate the session, so the other user share the session. Any solution for that?

    Thanks

    • Hey Daniel – sounds like an interesting scenario, but unfortunately it’s a bit to complex to debug it without code. My suggestion is have a simple project ready where you can reproduce the problem and post it over on StackOverflow. Then, email me the link – I’d be happy to have a look. Cheers,
      Eugen.

  • Well, Daniel – a link to the StackOverflow question is the first thing I’d need. Cheers,
    Eugen.

  • Sridhar

    Hi,

    I am using the Spring Security SAML with spring boot app.

    I see that by default it establishes a session.

    Since I am using resource based services and want to avoid the overhead of sessions, I configured as below,
    http.sessionManagement()
    .sessionCreationPolicy(SessionCreationPolicy.STATELESS);

    in the configure method of the class which extends WebSecurityConfigurerAdapter.

    With this change, I see that it redirects back to the homepage of the app asking me authenticate with the Identity Provider again and again in a loop.

    I do not get this behaviour.

    Can you please help me in this.

    • Hey Sridhar,
      Like in many other cases, a general description of the problem isn’t really enough to understand what’s going on. That’s only possible by looking at code. So, if you have a simple project where you’re able to reproduce the issue, feel free to email me (or post it to StackOverflow and email me the link) and I’d be happy to have a look.
      I do want to stress the fact that this sample project needs to be simple – as simple as it can be while still being able to reproduce the problem.
      Hope that makes sense. Cheers,
      Eugen.

      • Sridhar

        Thanks for your response.

        I have provided the sample project which highlights the issue I am facing,in the below git repo,

        https://github.com/bsridhar77/samlsecurityextndemo

        The readme.txt in project root folder should provide sufficient details on the running and testing the service.

        With current code there is no issue. But, when I comment out the line where I make the Session as Stateless is when I can reproduce the issue.

        Can you please help me on this.

        Thanks,
        Sridhar

        • I had a look at your repo. So, you’ve added a config for session control – and then you’re saying that you’re still being promoted to log in. First – that’s normal – since the system is still using form-login as the main way to authenticate.
          Second – if you’re using form-login, you will of course need the session. You can’t have a stateless system that uses form-login to authenticate – the two concepts simply aren’t compatible.
          Hope that helps point you in the right direction with this implementation.
          Cheers,
          Eugen.

          • Sridhar Balasubramanian

            Thanks for pointing me the reason is due to form-login.

            Since I need stateless services should I be sending the username/password with every request or better instead send a token in a header.

          • A security token would indeed be better suited here. Now – that may be OAuth2, or it may be a custom implementation – but the point is not to use a cookie to drive authentication.
            Cheers.

          • Abhay Thorat

            Then how can we elimanate the login page to exclude the stateless session and other request would be the stateless ?

          • Hey Abhay – I’m not sure I follow. First, “stateless session” throws me off – because in most cases, a session is by definition – state (so not stateless). Second – what do you mean by “exclude the login page”?

          • Abhay Thorat

            Hi Eugen,

            Please help me to clear the below point.

            1) Implementing the JWTdoes that mean remove session from our application i.e from Spring application & if yes how can I remove complete session from spring app.
            2) If I make will this line will not allow Spring application to create the session?
            3) So on every request I have to validate token and then allow the user to get the data. right ?
            4) I tried the above point and set the token in global varibale in UI and every request i send that token in header of request.
            But whenever I refresh the page then it goes like a new request and again going for authentication. what is your opionin on that is it right ?
            5) Last thing would like to know where can I keep token on client side so that even on refresh that token will go with header in authentication

          • Thanks for the clarifications Abhay.
            Let’s go right into answers.
            1 – it means you can yes, but not that you must
            2 – the Spring app won’t directly try to create a session, but a session might still be created from outside of Spring, so it’s not a guarantee that no session will exist
            3 – well, yes, but you won’t do that manually (since we’re talking about Spring, you’d have Spring Security set up to do that)
            4 – well, storing the token securely on the front end goes way beyond the scope of this article; but a quick note is that a global variable is not a good way to do that
            5 – again, that’s a complex question; you could store the access token in a secured cookie and make sure you only use that for storage, not to drive authentication
            One quick note I’d say here is – definitely read more about storing the tokens securely on the front end. There’s a lot more to it than just a couple of quick notes.
            Hope that helps and sets you on the right path with your implementation.
            Cheers,
            Eugen.

          • Abhay Thorat

            Thank you so much Eugen.

            That’s clear my confusion. 🙂

          • Sounds good, happy to help. Cheers,
            Eugen.

          • Abhay Thorat

            Hey Eugen,

            Have more question regarding JWT. please provide thought on this.

            1. When we authenticate the user first time lets say from DB and then generate the token and pass it to the client and when client will send that token am I going to just verify that token with jwtbuilder.verify(token) and can I say that the user is authenticate or anything apart from this I have to do?

            2. Regarding token time expiration : when I create first time token and configured expiration time of half hour then even if the user is continuesly using the application that time do user has to get the new token after half hour as the time expire.. by default ?
            (This would be very awkward if user has to get the token after every half hour and that means on server side I have to check the token expiration time on every request and will have to do sliding of time to next half an hour which would lead to token change even if user is already login to application) ?

            How we would deal with this.

          • 1. Well, no, not necessarily. If you’re using Spring, I’m assuming you’re using Spring Security for the OAuth2 support. In that case, the framework will do the actual authentication, you won’t do that manually.
            2. Yes. Token expiration is not the same as session expiration, so activity doesn’t matter.
            Have a look at the concept of a “Refresh Token” – that’s the way the user can obtain a new Access Token without having to manually authenticate again.
            Hope that helps. Cheers,
            Eugen.

          • Abhay Thorat

            Ohk.
            Thanks really nice..

      • Sridhar Balasubramanian

        Hi,

        I have shared a demo project which can reproduce the issue I am referring to.

        Please check below github,
        https://github.com/bsridhar77/springsecuritydemo

        The readme.txt in that repo has details on the problem I am facing when I run the app with my changes.

        Can you please help me on this.

        Thanks,
        Sridhar

  • Abhay Thorat

    HI Eugen, As my problem is coming once user successfully login by checking the creditial with DB again its send 401 response and the page is redirecting on login page again.

  • Nick Enchev

    How do you actually set the timeout time using java spring security configuration?

    • Hey Nick – do you mean session timeout? You don’t – not via the Spring Security configuration, you generally do that via the Servlet API.
      Cheers,
      Eugen.

      • Sujit Tripathy

        Hey Eugen
        I saw the JIRA where ticket was opened since 2013. Even though we follow Spring Java based configuration but still need to keep web.xml in the project to support the session-timeout. Am i correct?

        • Hey Sujit – you’re going to have to be more explicit than that – I’m not sure what JIRA tickets you’re talking about.

          • Sujit Tripathy

            Hey Eugen, my bad I didnt kept the JIRA ticket details but I read your above mentioned article on session timeout on web.xml and other ways (http://www.baeldung.com/servlet-session-timeout). So as far as Spring security timeout concerns we need to follow the timeout on web.xml which are basically from servlet and no explict timeout configuration provided by Spring security?

          • No worries, maybe you can find it again.
            To answer your question – there is no such thing as Spring Security session timeout. The framework does have some session control mechanism, but not timeout – yes, that comes from the Servlet level config.
            Hope that clears things up. Cheers,
            Eugen.

          • Sujit Tripathy

            Thank you:)

  • George Trandafir

    Hi Eugen,

    I have a small problem with Spring Security as described here: http://stackoverflow.com/questions/40106799/angular2-spring-boot-security . Do you have any tips please?

    Thanks,

    • Hey George – unfortunately not. The question is far to large to really go through (as you can see, there are no answers). My suggestion is – always try to isolate your problem to the smallest possible example you can get to – and only then ask.
      Hope that helps. Cheers,
      Eugen.

      • George Trandafir

        Thanks for looking into it. I have found a solution to integrate spring security with angular 2 and edited my stackoverflow post; so, for those of you who want to do this kind of thing that’s a good start.
        Cheers,
        George