spring-attic / spring-security-saml

SAML extension for the Spring Security project
Other
419 stars 484 forks source link

SES-159: Single Logout Problems with Logout Request Issued by the IDP. #137

Open spring-projects-issues opened 9 years ago

spring-projects-issues commented 9 years ago

Hubert Wagener (Migrated from SES-159) said:

SingleLogout is not functional.

Logout requests issued by the IDP fail.

More verbose: Consider in the SingleLogout the IDP sent a logout request like

<?xml version="1.0" encoding="UTF-8"?>
<saml2p:LogoutRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Destination="http://localhost:8080/security-sso/saml/SingleLogout" ID="ejbloofedgbpinebbeioijllbigpobecghaajlkd" IssueInstant="2015-02-02T10:20:16.090Z" NotOnOrAfter="2015-02-02T10:25:16.090Z" Reason="urn:oasis:names:tc:SAML:2.0:logout:user" Version="2.0">
  <saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">
    https://localhost:9443/samlsso
  </saml2:Issuer>
  <saml2:NameID xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:entity">
    demo@xxx.de
  </saml2:NameID>
  <saml2p:SessionIndex>
    fd011a38-32bb-48eb-9a59-253b5ddf531f
  </saml2p:SessionIndex>
</saml2p:LogoutRequest>  

In SAMLLogoutProcessingFilter.processLogout(..) the credential are computed as

Authentication auth = SecurityContextHolder.getContext().getAuthentication();
SAMLCredential credential = null;
      if (auth != null) {
              credential = (SAMLCredential) auth.getCredentials();
      }

Actually I don't understand how (and where) the credentials of the user " demo@xxx.de" are (or should be) put into the security context when called from the IDP like given above.

What happens is: The logout request fails with an exception (due to null credential) thrown at:

SingleLogoutProfileImpl.processLogoutRequest(...)

...
// Check whether any user is logged in
        if (credential == null) {
            throw new SAMLStatusException(StatusCode.UNKNOWN_PRINCIPAL_URI, "No user is logged in");
        }

Sure the session of the user should be destroyed, but I don't see where this case is considered in the code. Can you please help in understanding?

spring-projects-issues commented 9 years ago

Johannes Larsson said:

My customer experience the same problem. They have 2 spring saml applications where IDP initiated SLO fails.

Once the IDP sends a SAML SLO request to Spring SAML, its just doing a local logout and returning the logout page (/logout.jsp). This is using default configuration. If there are more than one SP logged in the SLO flow will be stuck at the Spring-SAML-Security applications.

The page its 'stuck' or locally loggged out is logoff.do?SAMLRequest=....

spring-projects-issues commented 9 years ago

Johannes Larsson said:

Resolved, this only seem to be a issue with the POST SLO binding. Configure redirect is the workaround.

<!-- Filter automatically generates default SP metadata -->
<bean id="metadataGeneratorFilter" class="org.springframework.security.saml.metadata.MetadataGeneratorFilter">
    <constructor-arg>
        <bean class="org.springframework.security.saml.metadata.MetadataGenerator">
                <property name="bindingsSLO" value="redirect" />
        </bean>
    </constructor-arg>
</bean>

<!-- Logout handler terminating local session -->
<bean id="logoutHandler"
      class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler">
    <property name="invalidateHttpSession" value="true"/>
</bean>
spring-projects-issues commented 9 years ago

Mohit Jain said:

I have made the above mentioned changes but problem still persist. Authentication object is always coming null as securitycontextholder doesnt have authentication credentials. Please help me out to figure out that how we can get the authentication object.

spring-projects-issues commented 9 years ago

Vladimir Schäfer said:

The Security Context is created during authentication and the call SecurityContextHolder.getContext().getAuthentication(); should therefore be returning a non-null value. If it is null it either means that the user's session has already been terminated, or your IDP is making a direct HTTP call instead of using user's browser to deliver the logout message. This is not supported by the SAML specification. This issue is known to happen at least with the WSO2IS IDP, is this your provider as well?

spring-projects-issues commented 8 years ago

Sree Ganesh Thyagarajan said:

Hi Vladimir,

I am using spring security for SAML integration with my application. The application is performing SSO properly. But when I try to do Single Logout, I am getting an error in the logout response as "No user logged in". I am using Microsoft AD and ADFS. Please find my status code and error message.

saml2p:Status

    saml2p:StatusMessageNo user is logged in/saml2p:StatusMessage

/saml2p:Status

Please provide your inputs on the same. Thanks.

Regards, Sree

spring-projects-issues commented 8 years ago

Jeremy Simon said:

I am a user of WSO2 IS 5.0.0 and running into this issue right now as well. I have three questions about this:

  1. Could I have some direction spelled out if I wished to write a "patch" to handle how WSO2 IS handles this? I'm not sure I'm at the luxury of switching out IDPs.
  2. Is there a known list of IDPs that play well with this? Or is it basically everyone one save for WSO2 IS? OpenAM ok, etc?
  3. Would there ever be a plan to address this case, even though it's said to be out of spec?

Answers appreciated!

wussup commented 7 years ago

Same here:

else if (context.getInboundSAMLMessage() instanceof LogoutRequest) {

                Authentication auth = SecurityContextHolder.getContext().getAuthentication();
                SAMLCredential credential = null;
                if (auth != null) {
                    credential = (SAMLCredential) auth.getCredentials();
                }
disccomp commented 6 years ago

Old thread, but anyone looking at this should note: I've seen this behavior because the SLO request is coming directly from the WSO2 server, not from the user. Check your server logs and note what IP address the SLO request is coming from.

rmangesh1988 commented 6 years ago

I'm getting a AnonymousAuthenticationToken instead for some reason , which gives SAMLCredentials as empty string and I get a ClassCastException, Authentication auth = SecurityContextHolder.getContext().getAuthentication(); SAMLCredential credential = null; if (auth != null) { credential = (SAMLCredential) auth.getCredentials(); } Please help!!, @vschafer

homaxto commented 3 years ago

Hi rmangesh1988

Did you ever find a solution for your issue? I see this same behaviour when user logs out on a different SP, and the session has timed out on our side. Is the session still alive, SLO works fine.