0

I'm having spring MVC application where the session management is done using redis and whenever I need to retrieve current logged in user I use Securitycontextholder.getcontext().getAuthentication(). But whenever I open another case or user in same browser but in different tab and I try to retrieve the current user it gives me null authentication object. Ideally I want to retrieve the old userid from security context which is already logged in and display error to new case or user which is getting opened, but it is not working. Please assist. Does redis have any impact on security context holder authentication object.?

Ritesh
  • 7,472
  • 2
  • 39
  • 43
  • what do you mean by 'open another case or user in same browser but in different tab'? Are you logging in with a different user in the second tab and then going back to the first tab? – Ritesh Nov 07 '20 at 17:27
  • Yes , I have a scenario that if another user session is starting in another tab I need to logout of all the existing sessions and display error to the user. In this case I need to get the currently logged in user which is my first user thru security context , but the authentication object is null when I fetch it from securitycontext which is stored in redis – Sagar Pandit Nov 07 '20 at 17:30
  • I think what you are looking for is not possible. It is like asking the browser to send 2 different (session) cookies to the same website from the differnt tabs. Maybe you could explore alternatives such as 'switch user' functionality. – Ritesh Nov 08 '20 at 15:58
  • Ok, also there is an interesting scenario here, when I open second user session in another tab in less than 2 minutes from from when I opend the first session , I am able to get the first logged in user data from security context , but after say 2 minutes if I open the another user session security context does not give me the user details, so was wondering if the security context from redis has any time window or something? – Sagar Pandit Nov 08 '20 at 16:04
  • That is a session-fixation problem that you can fix with the session management configuration of spring-security. Also take a look at [Multiple HttpSessions in Single Browser](https://docs.spring.io/spring-session/docs/2.0.0.M4/reference/html5/#httpsession-multi) to support multiple users in a session. – Ritesh Nov 08 '20 at 16:25
  • Ok thanks will have a look, so you mean to say that the details of first user that I'm not able to get from security context may be after certain time is due to the second user trying to login and is kind of session fixation issue. Can you please explain a bit more here as I mentioned earlier that first user details I'm able to get before 2 minutes when I try to open another session of other user, but not after 2 minutes. – Sagar Pandit Nov 08 '20 at 16:40
  • Just need to know that why before 2 minutes from my first session , when I try to open new session I'm able to get first session user data but not after 2 minutes . – Sagar Pandit Nov 08 '20 at 17:00
  • See [Data stored in Spring Session is not removed from Redis during destroy](https://stackoverflow.com/questions/28992395/). The underlying session is marked for deletion but redis is not immediately cleaned up. And yes, it is a session-fixation issue if you are able to get details of first user when a second user has logged in in the second browser. Just to make sure, you should delete all previous cookies in the auth entry point in addition to changing the spring security config. – Ritesh Nov 08 '20 at 17:15
  • Ok, but the user details of first user are not null only during first few minutes in which I try to open new user session, but after that specified time say 2 minutes if I open another user, I'm not able to get the user details of first user, why is that time related behaviour. – Sagar Pandit Nov 08 '20 at 17:19
  • The main aim here is - let's say first user session is opened. Now if the user tries to open another user session, I need to get the user details of first user and logout the all active sessions so that no user will be in authentication. The issue is only that I need to fetch first user details to logout all the session , but to do that I'm getting the user details of first user through security context only in the specified time, not after that – Sagar Pandit Nov 08 '20 at 17:20
  • The first user’s session is available because you didn’t do anything explicitly with it when logging in the second user. The underlying session cleanup mechanism of app server (tomcat for example) combined with redis takes 2 minutes. Without the redis, the delay would be very close to 0. – Ritesh Nov 08 '20 at 17:59
  • Thanks, that clarifies a bit. So if I set the session fixation to none instead of its default which is migrate session, will I get the first user details everytime and which I can use to logout? Or can you suggest anything here . – Sagar Pandit Nov 08 '20 at 18:03
  • If you don’t need to implement ‘switch-user’ or ‘multiple-sessions in a browser’ then my recommendation would be to clear existing cookies in your entry point so that previous cookies are cleared when a user logs it. I think that there is no need to do anything else. – Ritesh Nov 08 '20 at 18:07
  • Ok my requirement here is to not allow the second user to login and display an error message and also logout the first user session. – Sagar Pandit Nov 08 '20 at 18:09
  • @Ritesh can u you please explain a bit on this session cleanup of default time of 2 minutes with redis or any reference where I can see the details. I tried to google it out but couldn't find this configuration – Sagar Pandit Nov 09 '20 at 16:16
  • See the Rob Winch's answer to the post I already linked in one of my previous comments [Data stored in Spring Session is not removed from Redis during destroy](https://stackoverflow.com/questions/28992395/d). – Ritesh Nov 09 '20 at 16:23
  • Also see the documentation [Secion 9.5 Using @EnableSpringHttpSession](https://docs.spring.io/spring-session/docs/current/reference/html5/#api-redisoperationssessionrepository-expiration): **Note that no infrastructure for session expirations is configured for you. This is because things such as session expiration are highly implementation-dependent. This means that, if you need to clean up expired sessions, you are responsible for cleaning up the expired sessions.** – Ritesh Nov 09 '20 at 16:23
  • In one of your comments, you mentioned that the defualt session fixation protection is 'migrateSession' - it is true only for old servlet containers (pre 3.1 I think). – Ritesh Nov 09 '20 at 16:32
  • Ok , I had one more point here, when I'm in the first user session and doing some activity in that tab let's say for more than 2 minutes so ideally my session is active even in redis so the session cleanup activity is not happening and now I open a new tab for new user in that case also I do not get my old logged in user, ideally I should get that right , as I was having some activity in my first user session until I opened a new user in another tab? – Sagar Pandit Nov 09 '20 at 16:34
  • When the second user logs in in a different tab, the session of first user is invalidated and `session.getId()` will be different. The SESSION cookie value will also be different. For a few moments (2 minutes in your case), redis and/or `SpringSessionBackedSessionRegistry` may hold the old session info until the cleanup. Can you share code that you are using to get the first user? – Ritesh Nov 09 '20 at 16:55
  • Ok, I'm using the below code to get the principal object. Securitycontext holder.getcontext(). getAuthentication(). – Sagar Pandit Nov 09 '20 at 16:57
  • I see. So you get the first user inforamtion when you call `SecurityContextHolder.getContext().getAuthentication()' _after_ the second user logs in? if it is so then I think there is some design/config issue. – Ritesh Nov 09 '20 at 17:07
  • Yes, so basically I use this code to get first user details and log him out/display error when second tab opens for new user. Anyway I think as u mentioned the session cleanup can take time to clean up the old user details, that might be the issue. May be I will discuss this once with my team. Thanks Ritesh for your fruitful inputs, it was a good discussion – Sagar Pandit Nov 09 '20 at 17:10

0 Answers0