Announcement Announcement Module
Collapse
No announcement yet.
Global/Single Logout with SAML Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Global/Single Logout with SAML

    Hi,

    We have a SAML authentication system up and running using the spring-security-saml module. It uses a checkout from around August 2011 and so I’m afraid it hasn’t got a version number.

    We are encountering a problem when people logout from our system, and they are not logged out from their IDP. This causes no problems until 2 hours after their initial login at which point if they try to login to our system using SAML they get the following:-

    HTTP ERROR: 401

    Authentication Failed: Users authentication data is too old

    This continues for another 6 hours until the IDP session times out (at 8 hours) or until they restart their browser which kills off the IDP session.

    To fix this I am thinking that we need to change our system so that when they logout they are also logged out from the IDP. I think this is called Single Logout or Global Logout, and in our case it would be SP initiated. I'm going to tackle IDP initiated Single Logout (if its possible) later.

    I have 3 questions regarding this:-

    1. The documentation (from 2009, which was updated 5 months ago) which is at:-
    https://github.com/SpringSource/spri...umentation.pdf
    says "The SAML Single log-out profile is currently not supported, invocation of logout filter at /saml/logout context will only destroy the local session.". Its possible that between 2009 and when we downloaded the module in August 2011 this functionality was implemented. In the code we have the org.springframework.security.saml.SAMLLogoutFilter has the comment:-

    /**
    * Logout filter leveraging SAML 2.0 Single Logout profile. Upon invocation of the filter URL it is
    * determined whether global (termination of all participating sessions) or local (termination of only
    * session running within Spring Security) logout is requested based on request attribute.
    * <p/>
    * In case global logout is in question a LogoutRequest is sent to the IDP.
    *
    * @author Vladimir Schäfer
    */

    So from this I'm thinking that /saml/logout should now try to logout the user from the IDP. Is that correct?



    2. I've been debugging org.springframework.security.saml.SAMLLogoutFilter .doFilterHttp and have found that it is not doing the global logout because the Authentication object that it gets from:-
    Authentication auth = SecurityContextHolder.getContext().getAuthenticati on();
    is an object of class org.springframework.security.providers.ExpiringUse rnameAuthenticationToken which has a null value in its Object credentials. This causes isGlobalLogout to return false, which stops the global logout code from executing.

    I looked for places where ExpiringUsernameAuthenticationToken is created and found it being constructed at org.springframework.security.saml.SAMLAuthenticati onProvider.authenticate(Authentication authentication) at:-
    ExpiringUsernameAuthenticationToken result = new ExpiringUsernameAuthenticationToken(expiration, principal, credential, entitlements);
    Debugging this showed that the credential in this object (which had id 13760) was set to the credential used in login.

    But debugging:-
    Authentication auth = SecurityContextHolder.getContext().getAuthenticati on();
    when I do a logout shows that the same object (id 13760) now has a null value, so it has been erased by something.

    The superclass of ExpiringUsernameAuthenticationToken is UsernamePasswordAuthenticationToken which I see has a eraseCredentials() method. Putting a breakpoint there I find that during login

    org.springframework.security.saml.SAMLProcessingFi lter.attemptAuthentication() calls:-

    return getAuthenticationManager().authenticate(token);

    which calls:-
    org.springframework.security.authentication.Provid erManager.authenticate(Authentication authentication)

    which has the following bit of code in:-

    if (result != null) {
    if (eraseCredentialsAfterAuthentication && (result instanceof CredentialsContainer)) {
    // Authentication is complete. Remove credentials and other secret data from authentication
    ((CredentialsContainer)result).eraseCredentials();
    }

    The comment at the top of org.springframework.security.authentication.Provid erManager says:-

    * Post-authentication, the credentials will be cleared from the returned {@code Authentication} object, if it
    * implements the {@link CredentialsContainer} interface. This behaviour can be controlled by modifying the
    * {@link #setEraseCredentialsAfterAuthentication(boolean) eraseCredentialsAfterAuthentication} property.



    Searching google for "spring saml erase credentials" I find:-

    http://forum.springsource.org/showth...g-Security-3-1

    which says:-

    A few people have been asking how to run Spring SAML with Spring Security 3.1. This is pretty easy, you need to:


    Change references to GrantedAuthority to ? extends GrantedAuthority
    Update the securityContext.xml to use the new <security:http security="none"> format
    If you want to use the sample example as is you will also need to use erase-credentials=false



    I've put together a patched version of the saml2-core which runs against Spring Security 3.1 and also updated the saml2-sample app so it also works with 3.1. You can download it here (see the "Others" section). I'll contact the spring saml team and see if they want these changes feeding into the project

    Cheers



    It is possible that our SAML code was written and tested before an upgrade of Spring Security Core was done, and when it was upgraded to spring.security.core-3.1.0 that we are now using the Global Logout stopped working (we didn't notice because we don't have any live users yet).

    Doing more searching for "authentication-manager and eraseCredentialsAfterAuthentication" I found:-

    https://issues.jasig.org/browse/CAS-...story-tabpanel

    which is about a bug with "CAS Server" where the following isn't working:-

    <sec:authentication-manager alias="casAuthenticationManager" erase-credentials="false">

    So I looked in our security xml config and found:-

    <security:authentication-manager alias="authenticationManager">

    to which I added the erase-credentials="false" string:-

    <security:authentication-manager alias="authenticationManager" erase-credentials="false">

    and now it all works. Debugging shows that the eraseCredentials() method is no longer being called, and when I logout from our system it also logs out from the IDP server and then comes back and logs out from our server.

    So, finally, to question number 2. Is this the right way of getting single logout to work and are there any security implications I should be worried about now we are keeping the users credentials in memory for the whole of the session (24 hours), when without the erase-credentials="false" setting they would automatically be erased?

    3. If we did upgrade to Spring Security 3.1 since the original SAML code was written should I be worrying about changing the other 2 things mentioned in the Post above i.e. "Change references to GrantedAuthority to ? extends GrantedAuthority" and "Update the securityContext.xml to use the new <security:http security="none"> format" ?


    I have also downloaded the latest version of the code+sample+docs and am going to read the new doc and follow the instructions to get it working with Global Logout as its says "Pressing global logout will destroy both local session and session at IDP."

    Thanks in advance for your help.



    Steve

  • #2
    Hi Steve,

    One alternative to getting the SAML Single Logout profile running is to simply increase the allowed age of the SAML authentication. You can do so by setting property maxAuthenticationAge of the webSSOprofileConsumer to a higher value (7200 seconds is the default). This would make your 401 error go away. Although I'm not sure whether this possibility is available in the version you're currently running.

    To your questions:

    1. Your version from 2011 contains support for Single Logout. The documentation from 2009 is outdated. Please refer to the document at https://github.com/SpringSource/spri...n.pdf?raw=true

    2. The current trunk version (upcoming RC2 release) supports Spring Security 3.1 and doesn't require the erase-credentials setting. The SAMLCredential is now by default left in memory. The SAMLAssertion cannot be reused even in case someone would gain access to it. So unless you have additional sensitive data sent as part of the SSO (e.g. some attributes) keeping it in memory is ok.

    3. If you update to the current trunk version (or wait for the RC2) you should only go through the latest securityContext.xml of the SAML module and make sure all components there are also part of your own securityContex.xml. You don't need to make any code changes to the SAML module itself.

    Hope this helps,
    Vladimír Schäfer

    Comment


    • #3
      Hi Vladimir,

      I was trying to run the spring-saml integration sample. But whenever I tried to login, it is giving me a an error message syaing "The SAML request is invalid". I tried with "http://saml-federation.appspot.com/" as well. But no joy. I am getting the same error there as well...any idea on this?

      Comment


      • #4
        Hi, Are you using the latest version from GitHub? Have you carefully followed the instructions in the quick-start-guide of the manual in chapter 3? Mainly the entityId change. Is your system clock synchronized?

        The https://saml-federation.appspot.com/ now works again for both SSO and SLO. Service metadata was accidentally removed from the IDP.
        Last edited by vsch; Jan 21st, 2013, 04:47 AM.

        Comment


        • #5
          Hi,

          I have downloaded the same file which you had mentioned in your reply. I have followed the tutorial stuff as well to get the application running.

          I didn't understand the question regarding system clock.

          If possible, can you kindly send me the working copy of the project (excluding jars) so that I can understand where am I going wrong?

          Thanks a lot!

          Comment


          • #6
            Test Failure

            I am getting test failures with the attached trace.
            Any idea on this? I am using exactly what I have downloaded

            Also I am getting below exception while deploying the application in tomcat 7.0

            forg.springframework.beans.factory.BeanCreationExc eption: Error creating bean with name 'org.springframework.security.filterChains': Cannot resolve reference to bean 'org.springframework.security.web.DefaultSecurityF ilterChain#3' while setting bean property 'sourceList' with key [3]; nested exception is org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'org.springframework.security.web.DefaultSecurityF ilterChain#3': Cannot resolve reference to bean 'metadataGeneratorFilter' while setting constructor argument with key [0]; nested exception is org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'metadataGeneratorFilter': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationExce ption: Could not autowire method: public void org.springframework.security.saml.metadata.Metadat aGeneratorFilter.setDisplayFilter(org.springframew ork.security.saml.metadata.MetadataDisplayFilter); nested exception is org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'metadataDisplayFilter': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationExce ption: Could not autowire method: public void org.springframework.security.saml.metadata.Metadat aDisplayFilter.setGenerator(org.springframework.se curity.saml.metadata.MetadataGenerator); nested exception is org.springframework.beans.factory.NoSuchBeanDefini tionException: No matching bean of type [org.springframework.security.saml.metadata.Metadat aGenerator] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}rom git.
            Last edited by syammohan; Jan 22nd, 2013, 03:05 AM.

            Comment


            • #7
              Hi,

              The deployment exception suggest that bean metadataGeneratorFilter is missing from your securityContext.xml, can you verify that it is there?

              With system clock synchronization I mean whether your system time is correct, e.g. synchronized with an NTP service. Difference in time settings on your server and IDP can cause SAML requests to be rejected.

              Regarding the test - it cannot access file classpath:org/springframework/security/saml/key/keystore.jks and therefore fails. The JKS file is located in saml2-core/src/test/resources/org/springframework/security/saml/key/keystore.jks and should be part of the classpath. Are you running the tests from the command line with maven or in some other way? Do you see any reason why the jks wouldn't be in classpath in your environment? What Java/Maven versions are you using?

              A war file (renamed as a zip) created, configured and tested (with Java 7 + Tomcat 7) as is described in the manual is attached.

              Vladimír Schäfer

              Comment


              • #8
                Hi,
                Thanks a bunch for such a quick reply.

                I am using ssocircle itself as my IDP. How can I set the the timezone there?

                I am really sorry for the inconvenience happening. In fact, I am very new to Spring security.

                1. I couldn't see the keystore file in the CP. Not sure why.
                2. I am running maven from command prompt.
                3. Java -1.7, Maven - 3.0.4
                Last edited by syammohan; Jan 22nd, 2013, 04:47 AM.

                Comment


                • #9
                  Hi, There's no need to set timezone on IDP. You can find more information about clock synchronization e.g. here http://en.wikipedia.org/wiki/Clock_synchronization

                  Comment


                  • #10
                    Ok..sure..Let me go through the wiki

                    Comment


                    • #11
                      Hi Vladimír,

                      Great, thanks a lot for that reply. So that the solution works with any IDP (no matter how long it takes their sessions to time out) I've decided to go with setting erase-credentials="false" rather than extending the maxAuthenticationAge.

                      Now everything seems to be working OK I think we'll wait for the RC2 release that supports Spring Security 3.1 and when we upgrade we'll go through the latest securityContext.xml and make sure all the components are also part of our own securityContext.xml

                      BTW - is there a rough ETA for RC2?

                      Thanks again


                      Steve

                      Comment


                      • #12
                        Hi Steve,

                        It should be published in a couple of weeks.

                        Vladi

                        Comment

                        Working...
                        X