Question

I've created my own UserDetailsService and UserDetails implementations and hooked it up. I can create users, and login as users. However, if I login, logout, and then login again, I'm getting a redirect to a timeout error page. This is because I'm preventing concurrent logins, but it's not working - it used to with the "hello world" auth examples, but now with my own implementations that piece has stopped working correctly for some reason. Spring basically thinks there are 2 sessions when I login, logout, and login again.

Now - I thought this was all handled automatically ....perhaps using your own UserDetailsService means you actually have to implement session management somewhere else as well? I'm sort of blown away that's not mentioned in the docs or in the book Spring Security 3.1 so I'm assuming I'm missing something.

This is in my web.xml bit for listening to session life cycle events

<!-- This listener updates spring-security on httpsession lifecycle events, 
in this case to ensure each user can have only 1 session at a time. -->
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>

and this is in my security.xml to prevent concurrent logins

<!-- This prevents the user from logging in more than once simultaneously -->
<security:session-management
invalid-session-url="/timeout.htm">
<security:concurrency-control
max-sessions="1" error-if-maximum-exceeded="true" />
</security:session-management>

My logout in the security context file is

    <security:logout logout-url="/logout"
        invalidate-session="true" delete-cookies="JSESSIONID,SPRING_SECURITY_REMEMBER_ME_COOKIE"
        logout-success-url="/login.htm?logout" />

I've tried a few permutations of that. None seem to work. invalidate-session="true" is the default value, so I shouldn't even have to specify this. But it doesn't seem to be happening.

O.k., I just reverted everything to try and do in-memory auth and I'm getting the same errors. Meaning, I'm not using my custom implementations anymore. Sorry - I clearly have something wrong somewhere...and this is proving extremely difficult to find. I might have to start from scratch.

Do I have to do something special on logout with my custom UserDetailsService?

Any feedback or guidance is much appreciated.

Was it helpful?

Solution 2

I discovered it was a conflict between using <session-management> in my configuration and my servlet container. I'm using STS 3.5 (custom Eclipse for Spring projects) with vFabric server that runs in the IDE. The Reference documentation did not refer to this in the actual Session Management section (Section 8). However, buried in Section 4 on auth is this little gem:

Note that if you use this mechanism to detect session timeouts, it may falsely report an error if the user logs out and then logs back in without closing the browser. This is because the session cookie is not cleared when you invalidate the session and will be resubmitted even if the user has logged out. You may be able to explicitly delete the JSESSIONID cookie on logging out, for example by using the following syntax in the logout handler:

<http>
  <logout delete-cookies="JSESSIONID" />
</http>

Unfortunately this can’t be guaranteed to work with every servlet container, so you will need to test it in your environment

Well, apparently it doesn't work in STS 3.5

At first I tried to eliminate sections of my <session-management> tag so I could just control concurrency (i.e. have the user only able to log in with one session at a time). However, I just kept getting errors.

So, at this point I've removed the session management stuff altogether and will come back to it when ready to deploy.

OTHER TIPS

To my understanding the error-if-maximum-exceeded attribute should be false. Settings the value to false will cause the original session to expire instead of throwing a exception as explained in http://docs.spring.io/spring-security/site/docs/3.0.x/reference/appendix-namespace.html#d0e7768

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top