Spring Security SAML One Login Global Single Logout LogoutRequest Parsing Issue

时光怂恿深爱的人放手 提交于 2020-01-03 03:02:28

问题


I am implementing Spring Security SAML with One Login. I have set all the configuration files and meta data is set.

I am able to get login work and logout is working if I logoff from the same application I logged in. In this scenario from SAML IDP I get LogoutResponse and Spring Security is able to parse and process it.

http://localhost:8080/web/saml/SingleLogout?SAMLResponse=..............

Problem is when I login in two applications, currently I login to One Login admin console, there is a link to my app, I click on it and I am able to login directly in my application, now when I log off from One Login admin console, my application gets LogoutRequest.

http://localhost:8080/web/saml/SingleLogout?SAMLRequest=.........

Spring Security parses it fine and passes the object to a validation check logic.

org.springframework.security.saml.websso.processLogoutRequest(SAMLMessageContext context, SAMLCredential credential)

This method has following check.

// Make sure request was authenticated if required, authentication is done as part of the binding processing
        if (!context.isInboundSAMLMessageAuthenticated() && context.getLocalExtendedMetadata().isRequireLogoutRequestSigned()) {
            throw new SAMLStatusException(StatusCode.REQUEST_DENIED_URI, "LogoutRequest is required to be signed by the entity policy");
        }

I tried to follow the trace but the context object's field inboundSAMLMessageAuthenticated is never set to true. The above check fails and exception is thrown.

In debug mode I explicitly chencged the value to true, it went ahead but there is one more issue.

In the same method there is another check.

try {
            // Fail if NameId doesn't correspond to the currently logged user
            NameID nameID = getNameID(context, logoutRequest);
            if (nameID == null || !equalsNameID(credential.getNameID(), nameID)) {
                throw new SAMLStatusException(StatusCode.UNKNOWN_PRINCIPAL_URI, "The requested NameID is invalid");
            }
        } catch (DecryptionException e) {
            throw new SAMLStatusException(StatusCode.RESPONDER_URI, "The NameID can't be decrypted", e);
        }

The method equalsNameId is as follows.

private boolean equalsNameID(NameID a, NameID b) {
        boolean equals = !differ(a.getSPProvidedID(), b.getSPProvidedID());
        equals = equals && !differ(a.getValue(), b.getValue());
        equals = equals && !differ(a.getFormat(), b.getFormat());
        equals = equals && !differ(a.getNameQualifier(), b.getNameQualifier());
        equals = equals && !differ(a.getSPNameQualifier(), b.getSPNameQualifier());
        equals = equals && !differ(a.getSPProvidedID(), b.getSPProvidedID());
        return equals;
    }

Here it fails on differ(a.getFormat(), b.getFormat())

Question

I am not sure is there something I am missing, kind of lost where exactly to check to tackle this issue.

My binding for Single Logout is HTTP-Redirect.

Would appreciate if pointers are provided. Let me know if more information is required.

Thanks for time.

Stack (Legacy Application):

Spring 3.0.6

Spring Security 3.1.2

Spring Security SAML 1.0.0

Tomcat 7.x


回答1:


Having encountered this two years after the original post, I had to do some further research. I still have some reading to do regarding the SAML specifications, but I think I found an entry in SAML 2.0 Errata on the structure of the NameIDType which underlies the NameID and Issuer. All four elements in this type are optional. OneLogin appears to be following this document and does not send a NameID.Format in the SingleLogout request.

So, the inboundMessage has a nameID with a null format while the credential's nameID has a format of "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress". This is what causes the getFormat line to return false and fail the entire check.



来源:https://stackoverflow.com/questions/33931488/spring-security-saml-one-login-global-single-logout-logoutrequest-parsing-issue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!