Announcement Announcement Module
Collapse
No announcement yet.
Spring Security, UserDetailsService, Load balancer, Session State Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring Security, UserDetailsService, Load balancer, Session State

    Alright so first using Spring 3.0 and Spring Security 3.0.

    First problem is that we are using a load balancer in our production environment and I've been told that we will not be using sticky sessions in tomcat. I've been looking for most of today trying to see if there is anything that could help me out. Have yet to find anything. The problem is that we use a custom authentication manager and filter when users log in to the system. I was going to use the remember me functionality but then trying to find on how to create a custom User details service to work with our custom autherntication manager is drawing a blank.

    The way everything currently works is that a user logs in, the authentication manager sends the data over to a userservice class that encrypts the password with an attached key that then gets sent to Cold Fusion template that returns back the data on the user. Then the data returns gets processed by the service and then sent back to the authentication manager where it assigns the roles and sets the authentication based off the processed data. Then the filter is called and adds extra information for the webapp to use while the user is logged in. After everything is successful the user is redirected to the home page.

    So everything works with a single box, user logs in and can use the site not problem. When its on the load balance the session is of course being invalidated since it's jumping between different boxes. The solution I came up with was to use remember me, except that I know I'm supposed to write a custom user detail service since we are using custom authentication classes. Now the only thing is I don't know exactly how to go about that or what needs to even be passed in to the user details class so that remember me works. If anyone can help me that would be great, because as of right now I'm at a loss. If anyone has any other ideas that could work that would be great as well. The more information the better.

    Thanks,
    Ricardo

  • #2
    Originally posted by matenwego View Post
    First problem is that we are using a load balancer in our production environment and I've been told that we will not be using sticky sessions in tomcat.
    Why won't they support sticky sessions?

    Originally posted by matenwego View Post
    The problem is that we use a custom authentication manager and filter when users log in to the system. I was going to use the remember me functionality but then trying to find on how to create a custom User details service to work with our custom autherntication manager is drawing a blank.
    So long as you have a way to obtain the user principal, user password (optional), and roles given a username this should be pretty straight forward. If you do not have a way of doing this, you cannot really implement the UserDetailsService.

    Originally posted by matenwego View Post
    ... that encrypts the password with an attached key
    You may already know this, but as an FYI it is best to hash passwords rather than encrypting them.

    Originally posted by matenwego View Post
    The solution I came up with was to use remember me, except that I know I'm supposed to write a custom user detail service since we are using custom authentication classes.
    Using rememberme will require a hit to your UserDetailsService every time a different session is established (i.e. every time a user is routed to a different Tomcat instance). Depending on the UserDetailsService implementation, this can (and likely will) be quite costly from a performance perspective. It is better to try to allow the container to manage the session rather than creating your own session management.

    Originally posted by matenwego View Post
    Now the only thing is I don't know exactly how to go about that or what needs to even be passed in to the user details class so that remember me works. If anyone can help me that would be great, because as of right now I'm at a loss. If anyone has any other ideas that could work that would be great as well. The more information the better.
    You really are going to be better off setting up the cluster to use sticky sessions. There are likely other reasons you will be using session which will also be impacted by this problem. For example, if you use the PRG a common way to deal with passing messages to error pages is to use the session. Spring Security does this when dealing with errors (i.e. a failed login). That isn't to say you cannot work around this, but the more you work around vs use things the way they are intended the more difficult it will be.

    If I were you and I absolutely could not use sticky sessions, I would look into writing a custom SecurityContextRepository. This would allow you to save/retrieve the SecurityContext using something other than session. I would really be cautious doing this because security is a difficult thing (even the experts have a difficult time getting it right). Also keep in mind that this is called for every request, so it should perform really well otherwise your application will not perform.

    PS: You may want to update to the latest Spring and Spring Security to avoid a number of security vulnerabilities that have been fixed.

    Cheers,

    Comment


    • #3
      Originally posted by rwinch View Post
      Why won't they support sticky sessions?
      They don't want to store sessions server side. Part of our security protocol. Nothing I can do about it.


      Originally posted by rwinch View Post
      So long as you have a way to obtain the user principal, user password (optional), and roles given a username this should be pretty straight forward. If you do not have a way of doing this, you cannot really implement the UserDetailsService.
      Okay I can see now how to do this. Does seem pretty straight forward.


      Originally posted by rwinch View Post
      You may already know this, but as an FYI it is best to hash passwords rather than encrypting them.
      We are hashing the passwords, just used the word encrypt instead of hash my mistake. xD

      Originally posted by rwinch View Post
      Using rememberme will require a hit to your UserDetailsService every time a different session is established (i.e. every time a user is routed to a different Tomcat instance). Depending on the UserDetailsService implementation, this can (and likely will) be quite costly from a performance perspective. It is better to try to allow the container to manage the session rather than creating your own session management.
      Yet again nothing I can do. All I can say is that as far as I know we are using apache, tomcat, with load balance and AJP. How it's all connected together is something I don't know (once I do know I'll edit this). Does anyone know of someone or some documentation that has done this decently?



      Originally posted by rwinch View Post
      You really are going to be better off setting up the cluster to use sticky sessions. There are likely other reasons you will be using session which will also be impacted by this problem. For example, if you use the PRG a common way to deal with passing messages to error pages is to use the session. Spring Security does this when dealing with errors (i.e. a failed login). That isn't to say you cannot work around this, but the more you work around vs use things the way they are intended the more difficult it will be.

      If I were you and I absolutely could not use sticky sessions, I would look into writing a custom SecurityContextRepository. This would allow you to save/retrieve the SecurityContext using something other than session. I would really be cautious doing this because security is a difficult thing (even the experts have a difficult time getting it right). Also keep in mind that this is called for every request, so it should perform really well otherwise your application will not perform.
      I knew this was not going to be a walk in the park, looks like I have my work cut out for me. Question is now is there anyone who might have some resources that could lead me to the right track. Especially with writing a custom SecurityContextRepository. I was thinking as well couldn't I try to use session cookies somehow? Or with the current way does that not seem possible?

      Originally posted by rwinch View Post
      PS: You may want to update to the latest Spring and Spring Security to avoid a number of security vulnerabilities that have been fixed.
      Oh wow yes I will do so, thank you for that heads up. There shouldn't be any problems if I update to the latest from 3.0 correct?

      Thanks,
      Ricardo

      Comment


      • #4
        Originally posted by matenwego View Post
        They don't want to store sessions server side. Part of our security protocol. Nothing I can do about it.
        Just because you are not using sticky sessions doesn't mean that is going to prohibit putting things in session. It may deter developers from using it (since it makes it effectively useless), but values can still be placed in the session. Also, I am curious why this would be a security measure. If your application needs a session (which it appears like it does to manage the user), then in all likely hood writing your own implementation to manage session will be less secure than something that has been around for a long time, well tested, used by many more users, etc.

        Originally posted by matenwego View Post
        Yet again nothing I can do. All I can say is that as far as I know we are using apache, tomcat, with load balance and AJP. How it's all connected together is something I don't know (once I do know I'll edit this). Does anyone know of someone or some documentation that has done this decently?
        This is not really the best place to look for that information. I can tell you the tomcat docs have pretty good information on clustering. If you have trouble please consult their forums.

        Originally posted by matenwego View Post
        Especially with writing a custom SecurityContextRepository.
        Again this should be pretty clear cut. If it doesn't make sense read the javadoc and try looking at the HttpSessionSecurityContextRepository (the default implementation).

        Originally posted by matenwego View Post
        I was thinking as well couldn't I try to use session cookies somehow? Or with the current way does that not seem possible?
        The session cookie is used in the default implementation, but that will not work with out using sticky sessions. Technically you could enable session replication so that each node recognizes the other's session, but without sticky sessions the replication would have to occur so frequently it would cause a significant impact on performance.

        Originally posted by matenwego View Post
        There shouldn't be any problems if I update to the latest from 3.0 correct?
        You should be fine to update to the latest 3.0.x of Spring and Spring Security if you are already using 3.0.

        Comment

        Working...
        X