Centrify & Azure 因为 IDP 没有 return LogoutResponse on Single Log Out

Centrify & Azure as IDP does not return LogoutResponse on Single Log Out

我正在尝试将支持 SAML 的应用程序作为 SP 连接到 Mircrosoft Azure 并作为 IDP 连接 Centrify。 SSO(单点登录)正常工作,但我在完成完整的单点注销过程时遇到了一些问题。

当用户单击 SP 内的注销按钮时,将向 IDP 发送一个(有效的)注销请求。 IDP 会话按预期终止,但浏览器未重定向到 SP 以完成注销过程。似乎完全缺少 LogoutResponse。


有关 Centrify 的更新
正如 Centrify 的 Nick Gamb 所说(请参阅下面他的回答),目前 Centrify 不支持此功能,但将在未来实现。



有关 Azure 的更新
您必须提供一个 'wreply' 参数 - 包含用户在注销后应重定向到的站点的 url_ecoded URL - 以及注销请求: https://login.microsoftonline.com/common/wsfederation?wa=wsignout1.0&wreply=https%3A%2F%2Fmyapp.landingpage.com%2F&SAMLRequest=...

如果您使用的是 Onelogin PHP 工具包,那么您还必须启用 'retrieveParametersFromServer' 设置,否则注销响应将始终以 'Signature validation failed. Logout Request rejected' 错误结束。


遵循 SAML requests/responses(我允许自己删除证书信息...):

Centrify // 登录请求

<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
                xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
                ID="ONELOGIN_17b5cbaaa30c8a9edca9935a320b0de3a4088fcc"
                Version="2.0"
                ProviderName="MYAPP"
                IssueInstant="2017-01-27T12:08:52Z"
                Destination="https://aap1234.my.centrify.com/applogin/appKey/1234567-1234-1234-1234-123456789/customerId/ABC0123"
                ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
                AssertionConsumerServiceURL="https://myapp.com/acs"
                >
<saml:Issuer>https://myapp.com/metadata</saml:Issuer>
<samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
                    AllowCreate="true"
                    />
<samlp:RequestedAuthnContext Comparison="exact">
    <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
</samlp:RequestedAuthnContext>

Centrify // 登录响应

<saml2p:Response ID="_7367bcc4-f4a1-4bf0-b845-ecaf0e7d6b86"
             InResponseTo="ONELOGIN_17b5cbaaa30c8a9edca9935a320b0de3a4088fcc"
             Version="2.0"
             IssueInstant="2017-01-27T12:08:53.978Z"
             Destination="https://myapp.com/acs"
             xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"
             >
<Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">https://aap1234.my.centrify.com/1234567-1234-1234-1234-123456789</Issuer>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
    <SignedInfo>
        <CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
        <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
        <Reference URI="#_7367bcc4-f4a1-4bf0-b845-ecaf0e7d6b86">
            <Transforms>
                <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
                <Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            </Transforms>
            <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
            <DigestValue>EpN1bP9vKhLUUpyr0Hfnb3lM6gA=</DigestValue>
        </Reference>
    </SignedInfo>
    <SignatureValue>...</SignatureValue>
    <KeyInfo>
        <X509Data>
            <X509Certificate>...</X509Certificate>
        </X509Data>
    </KeyInfo>
</Signature>
<saml2p:Status>
    <saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
</saml2p:Status>
<Assertion Version="2.0"
           ID="_71ccde7d-6a7b-4b79-a6ed-1f8465b7a835"
           IssueInstant="2017-01-27T12:08:53.869Z"
           xmlns="urn:oasis:names:tc:SAML:2.0:assertion"
           >
    <Issuer>https://aap1234.my.centrify.com/1234567-1234-1234-1234-123456789</Issuer>
    <Subject>
        <NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">centrify@myapp.com</NameID>
        <SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
            <SubjectConfirmationData NotOnOrAfter="2017-01-27T13:08:53.869Z"
                                     Recipient="https://myapp.com/acs"
                                     InResponseTo="ONELOGIN_17b5cbaaa30c8a9edca9935a320b0de3a4088fcc"
                                     />
        </SubjectConfirmation>
    </Subject>
    <Conditions NotBefore="2017-01-27T12:05:53.869Z"
                NotOnOrAfter="2017-01-27T13:08:53.869Z"
                >
        <AudienceRestriction>
            <Audience>https://myapp.com/metadata</Audience>
        </AudienceRestriction>
    </Conditions>
    <AuthnStatement AuthnInstant="2017-01-27T12:08:53.869Z"
                    SessionIndex="_71ccde7d-6a7b-4b79-a6ed-1f8465b7a835"
                    >
        <AuthnContext>
            <AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:unspecified</AuthnContextClassRef>
        </AuthnContext>
    </AuthnStatement>
    <AttributeStatement>
        <Attribute Name="firstname"
                   NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
                   >
            <AttributeValue>Firstname</AttributeValue>
        </Attribute>
        <Attribute Name="lastname"
                   NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
                   >
            <AttributeValue>Lastname</AttributeValue>
        </Attribute>
        <Attribute Name="emailaddress"
                   NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
                   >
            <AttributeValue>centrify@myapp.com</AttributeValue>
        </Attribute>
        <Attribute Name="groups"
                   NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"
                   >
            <AttributeValue>group1,group2</AttributeValue>
        </Attribute>
    </AttributeStatement>
</Assertion>

Centrify // 注销请求

<samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
                 xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
                 ID="ONELOGIN_dc16bcf1e9a5de948d336fbca93d4a5718b56f3d"
                 Version="2.0"
                 IssueInstant="2017-01-27T12:10:12Z"
                 Destination="https://aap1234.my.centrify.com/applogout"
                 >
<saml:Issuer>https://myapp.com/metadata</saml:Issuer>
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">centrify@myapp.com</saml:NameID>
<samlp:SessionIndex>_71ccde7d-6a7b-4b79-a6ed-1f8465b7a835</samlp:SessionIndex>

Microsoft Azure // 登录请求

<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
                xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
                ID="ONELOGIN_40becfa9c4dc2697c9778b7b598399fbc55cef98"
                Version="2.0"
                ProviderName="MYAPP"
                IssueInstant="2017-01-27T12:31:26Z"
                Destination="https://login.microsoftonline.com/1234567-1234-1234-1234-123456789/saml2"
                ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
                AssertionConsumerServiceURL="https://myapp.com/acs"
                >
<saml:Issuer>https://myapp.com/metadata</saml:Issuer>
<samlp:NameIDPolicy Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"
                    AllowCreate="true"
                    />
<samlp:RequestedAuthnContext Comparison="exact">
    <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef>
</samlp:RequestedAuthnContext>

Microsoft Azure // 登录响应

<samlp:Response ID="_4221c6ce-51b5-48df-b33e-5c601bbc22ad"
            Version="2.0"
            IssueInstant="2017-01-27T12:31:27.170Z"
            Destination="https://myapp.com/acs"
            InResponseTo="ONELOGIN_40becfa9c4dc2697c9778b7b598399fbc55cef98"
            xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
            >
<Issuer xmlns="urn:oasis:names:tc:SAML:2.0:assertion">https://sts.windows.net/1234567-1234-1234-1234-123456789/</Issuer>
<samlp:Status>
    <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
</samlp:Status>
<Assertion ID="_ad52e38a-5f8f-4a60-9b3b-d904afd9b82e"
           IssueInstant="2017-01-27T12:31:27.170Z"
           Version="2.0"
           xmlns="urn:oasis:names:tc:SAML:2.0:assertion"
           >
    <Issuer>https://sts.windows.net/1234567-1234-1234-1234-123456789/</Issuer>
    <ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        <ds:SignedInfo>
            <ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
            <ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256" />
            <ds:Reference URI="#_ad52e38a-5f8f-4a60-9b3b-d904afd9b82e">
                <ds:Transforms>
                    <ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
                    <ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#" />
                </ds:Transforms>
                <ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256" />
                <ds:DigestValue>mv1wKPg7iHLzZ5cNnu8oYX0/YvZqGsxKHsUc0umZVYw=</ds:DigestValue>
            </ds:Reference>
        </ds:SignedInfo>
        <ds:SignatureValue>...</ds:SignatureValue>
        <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
            <X509Data>
                <X509Certificate>...</X509Certificate>
            </X509Data>
        </KeyInfo>
    </ds:Signature>
    <Subject>
        <NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">jMPrg5XmAUzfnoCKSAXJGJMDZ8Hdj_bRU2YY6-Ozugg</NameID>
        <SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
            <SubjectConfirmationData InResponseTo="ONELOGIN_40becfa9c4dc2697c9778b7b598399fbc55cef98"
                                     NotOnOrAfter="2017-01-27T12:36:27.170Z"
                                     Recipient="https://myapp.com/acs"
                                     />
        </SubjectConfirmation>
    </Subject>
    <Conditions NotBefore="2017-01-27T12:26:27.154Z"
                NotOnOrAfter="2017-01-27T13:26:27.154Z"
                >
        <AudienceRestriction>
            <Audience>https://myapp.com/metadata</Audience>
        </AudienceRestriction>
    </Conditions>
    <AttributeStatement>
        <Attribute Name="http://schemas.microsoft.com/identity/claims/tenantid">
            <AttributeValue>1234567-1234-1234-1234-123456789</AttributeValue>
        </Attribute>
        <Attribute Name="http://schemas.microsoft.com/identity/claims/objectidentifier">
            <AttributeValue>12345-123-123-1234-12345678</AttributeValue>
        </Attribute>
        <Attribute Name="http://schemas.microsoft.com/identity/claims/identityprovider">
            <AttributeValue>live.com</AttributeValue>
        </Attribute>
        <Attribute Name="firstname">
            <AttributeValue>Firstname</AttributeValue>
        </Attribute>
        <Attribute Name="lastname">
            <AttributeValue>Lastname</AttributeValue>
        </Attribute>
        <Attribute Name="emailaddress">
            <AttributeValue>mail@myapp.com</AttributeValue>
        </Attribute>
    </AttributeStatement>
    <AuthnStatement AuthnInstant="2017-01-27T11:09:28.000Z"
                    SessionIndex="_ad52e38a-5f8f-4a60-9b3b-d904afd9b82e"
                    >
        <AuthnContext>
            <AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</AuthnContextClassRef>
        </AuthnContext>
    </AuthnStatement>
</Assertion>

Microsoft Azure // 注销请求

<samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
                 xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
                 ID="ONELOGIN_a90edfe3da4eb07dd1e2a52df7d4cb5385cbd6c8"
                 Version="2.0"
                 IssueInstant="2017-01-27T12:32:05Z"
                 Destination="https://login.microsoftonline.com/common/wsfederation?wa=wsignout1.0"
                 >
<saml:Issuer>https://myapp.com/metadata</saml:Issuer>
<saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent">jMPrg5XmAUzfnoCKSAXJGJMDZ8Hdj_bRU2YY6-Ozugg</saml:NameID>
<samlp:SessionIndex>_ad52e38a-5f8f-4a60-9b3b-d904afd9b82e</samlp:SessionIndex>

注销请求与其他 GET 参数一起发送: RelayState <= 指向 SP 的单点注销 URL wa <= 设置为 „wsignout1.0“

我针对第三个 IDP (Onelogin) 测试了 SP 配置,这里 SP 启动的注销按预期工作。用户退出 IDP 会话,然后使用 LogoutResponse 重定向到 SP。这里唯一的区别是我能够在 Onelogin 应用程序配置中明确设置 SP 注销URL。

是否有任何选项可以在 Azure 或 Centrify 中定义 SP 注销 url? 我错过了什么吗?

谢谢!

感谢您提交问题。这是最近的一个常见问题。简短的回答是 Centrify 目前不支持 SAML 单点退出。从 Centrify 中的 SAML 应用注销 URL 只是对 IDP 的注销请求。之后用户总是被重定向到 Centrify 登录页面。它不支持 SAML,因此没有响应。

好消息是此功能目前正在解决中,应该会在未来的产品版本中发布,以符合完整的 SAML 规范。在那之前,我有一个可能的解决方案供您考虑。

如果您有能力修改您的 Web 应用程序,特别是它如何进行注销调用,您可以将逻辑设置为对注销 URL 进行注销调用作为 API调用而不是重定向。您需要从站点 Javascript 调用注销 URL,以便在 API 调用中传递用户会话 cookie,而不是从服务器代码进行。在这样做时,您将用户从 Centrify 中注销,然后您可以将他们重定向到您希望他们最终到达的任何页面(即您的 Web 应用程序登录页面)。该调用不需要任何 JSON。只需让网络请求调用注销 url,然后将用户重定向到您的登录页面。

请随时通过 devsupport@centrify.com 与我联系,我很乐意为您提供进一步的帮助。我也很高兴接到电话来更详细地讨论这个问题。

谢谢,

尼克·甘姆 开发者倡导者 集中

正如我更新的问题中提到的那样:

如果您正在使用 Centrify

正如 Centrify 的 Nick Gamb 所说(见他上面的回答),目前 Centrify 不支持此功能,但会在未来实现。

如果您使用的是 Microsoft Azure

您必须提供一个 'wreply' 参数 - 包含用户在注销后应重定向到的站点的 url_ecoded URL - 注销请求:https://login.microsoftonline.com/common/wsfederation?wa=wsignout1.0&wreply=https%3A%2F%2Fmyapp.landingpage.com%2F&SAMLRequest=...

如果您使用的是 Onelogin PHP 工具包,那么您还必须启用 'retrieveParametersFromServer' 设置,否则注销响应将始终以 'Signature validation failed. Logout Request rejected' 错误结束。