2

I am working with Spring MVC 4 and Spring Security 3.1 on a web application. I have a requirement where I need to update user's detail when user logs in and whenever he logs out. I searched a lot here and found answers that explained use of HttpSessionListener and HttpSessionPublishEvent of Spring. I also understood that SecurityContextHolder.getContext().getAuthentication() and then getting the principal object wouldn;t work in these listeners. But somebody exaplained to get it through

      session.getAttribute("SPRING_SECURITY_CONTEXT") 

However I am not able to access

       session.getAttribute("SPRING_SECURITY_CONTEXT")

when user logs in so that I can get authentication and principal objects. In both above implementations I get this attribute as null whenever sessionCreated/sessionDestroyed event is called.

My login page is rendered using a action

      http://localhost:8081/myapp/auth/showLogin 

and then I login using form login.

 I am using custom UserDetails object as follows :.

 public class SecurityContext {

public static ChatterUserDetails getCurrentUser(){
    Object principal = SecurityContextHolder.getContext().getAuthentication().
        getPrincipal();
    if(principal instanceof MyUserDetails){
        return (MyUserDetails) principal;
    }
    MyUserDetails anonymousJkWebUserDetails = new  MyUserDetails("anonymous","anonymous",
      new ArrayList<GrantedAuthority>());                                
    anonymousJkWebUserDetails.setAnonymous(true);
    return anonymousJkWebUserDetails;
}

}

and security.xml is as follows (only relevant sections ) :

  <http use-expressions="true">
          <intercept-url pattern="/auth/showLogin" access="permitAll()"></intercept-url>
        ....
   </http>

   <form-login login-page="/auth/showLogin" always-use-default-target="true"
        default-target-url="/auth/home" authentication-failure-url="/auth/showLogin?error=1"
        login-processing-url="/auth/login" password-parameter="userPassword" 
        username-parameter="userId" />
    <logout logout-success-url="http://${email.link.host}" logout-url="/auth/logout" delete-cookies="JSESSIONID" invalidate-session="true"></logout>
Shailesh Vaishampayan
  • 1,766
  • 5
  • 24
  • 52
  • I couldn't help but notice this, the first answer looks promising http://stackoverflow.com/questions/1629211/how-do-i-get-the-session-object-in-spring – Josh Nov 15 '14 at 01:58
  • Nope.. what i want to do is update user's info when he logs in and update again when he logs out. but how do it get the user id when he logs in and logs out in listeners? I dont mind using any listener plain sessionlistener or spring's event listener – Shailesh Vaishampayan Nov 15 '14 at 02:07
  • 1
    Don't use a session listener for that, as session might get created for other reasons as well. Create a class that implements `ApplicationListener` which is an event fired from Spring Security when a user logs on successfully. To capture logout let the same class implement `LogoutHandler` or listen for the `HttpSessionDestroyedEvent` the latter has the advantage of also capturing session invalidation. There is also [this issue](https://jira.spring.io/browse/SEC-2680) for requesting an event on logout just for this purpose (which is handy in stateless environments). – M. Deinum Nov 15 '14 at 09:00
  • @M.Deinum thanks, I did just that and it worked. Just have another doubt. does this AuthenticationSuccessEvent when fired, guarantee that user session has been created/or will be created.? Also what if I want to have access to session/context for some reason in such event handlers? As I am declaring the the event handler class as just another bean can i dependency inject servlet context/session into it directly? I am already injecting one of my services bean in this class and it works. but didn't work with servletcontext auto-wiring? – Shailesh Vaishampayan Nov 15 '14 at 10:30
  • Why do you need the session, you wanted the user (authentication) and that is what you get. As long as you handle events synchronously you could get access to the session or whatever you like but in general you want to write such code not dependent on things like that. – M. Deinum Nov 15 '14 at 13:21
  • right.as i explained when i trap this event i am making an update on DB which is an indication to my further actions that a session exists. is that a sureshot way to assume that session will indeed be created? – Shailesh Vaishampayan Nov 15 '14 at 13:43

1 Answers1

0

In my case I implemented the example detailed above, listening to ApplicationListener<InteractiveAuthenticationSuccessEvent> and injecting the HttpSession https://stackoverflow.com/a/19795352/2213375

Community
  • 1
  • 1
Teixi
  • 1,077
  • 8
  • 21