Results 1 to 4 of 4

Thread: Spring Security, UserDetailsService, Load balancer, Session State

  1. #1
    Join Date
    Sep 2011
    Posts
    2

    Default 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. #2
    Join Date
    Jan 2008
    Posts
    1,826

    Default

    Quote 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?

    Quote 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.

    Quote 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.

    Quote 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.

    Quote 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,
    Rob Winch - @rob_winch
    Spring Security Lead
    Pivotal

  3. #3
    Join Date
    Sep 2011
    Posts
    2

    Default

    Quote 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.


    Quote 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.


    Quote 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

    Quote 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?



    Quote 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?

    Quote 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

  4. #4
    Join Date
    Jan 2008
    Posts
    1,826

    Default

    Quote 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.

    Quote 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.

    Quote 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).

    Quote 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.

    Quote 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.
    Rob Winch - @rob_winch
    Spring Security Lead
    Pivotal

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •