Reputation: 303
I have a federated spring authorisation server which uses social login. To restrict the number user login sessions, enabled the spring security session management but it didn’t worked out for me. I would like to implement following:
When user logout, terminate the user session and ask him to login through social login again.
If user already logged in, trying to login from another device or browser, we should terminate the old session (spring security session management had this)
Issue is even though I’m enabled the session management, it is still allowing multiple login sessions across devices/browsers.
Upvotes: 0
Views: 1723
Reputation: 527
I have a very similar problem. I wanted to use a stateless authorization server, so followed the example starter guide, but then hit problems.
Since NullSecurityContextRepository was used, it would never actually authenticate, and run the success handler. I also wondered how I would get the redirect url, since the RequestCache is normally stored with a session.
Please see here:
Spring Security - cannot get Stateless Authorization Server to work
Is it not recommended to use a stateless authorization server.
If you want to use Concurrent Session Management Control (e.g. to limit a user from opening multiple sessions), then should I leave session Management on, and to use something like Redis with Spring Session to manage sessions.
(I get a bit confused when I read articles that say that if you're using tokens, JWT or opaque, then sessions should be stateless... or does that apply to session management on the resource server only?)
My goal is to use a public Angular client, with a custom login / sign up page, that goes through a Spring authorization server to then access resources on a Spring resource server, via the opaque access token method, using the authorization grant code method, with PKCE.
I can share what I have so far.
Upvotes: 0
Reputation: 6158
The issue you're finding is on the client application where you configure concurrent session control for oauth2Login()
. Maximum sessions is enforced correctly on the authorization server, which only uses formLogin()
.
First, your client sample is missing a HttpSessionEventPublisher
bean, as suggested in the docs.
Second, your client sample is not configured to use Spring Session for backing the session store. Because of this, it is using an in-memory SessionRegistry
implementation, which is the default. This in-memory implementation is simple in nature, and maps the sessions by the principal
. It therefore considers two users who log in with OAuth2 to be different, because it simply uses the equals()
and hashCode()
methods of the principal (an instance of DefaultOidcUser
). These methods do not consider the same user from different logins to be equal, because they have different values in the token response from the authorization server.
In order for this sample to work correctly with concurrent session controls, you will need to add and configure spring-session as the backing store for your sessions on the client application, which is quite easy to do. See a list of samples and guides to get started.
It might also be worth reporting this as a bug in spring-security, since the in-memory (default) implementation of SessionRegistry
is not compatible with DefaultOidcUser
and DefaultOAuth2User
as the principal. However, it shouldn't be an issue in production as you should not rely on in-memory implementations for production deployments. You would normally configure Spring Session for your application at a minimum.
Upvotes: 1