如何创建签名的 AuthNRequest?

Posted

技术标签:

【中文标题】如何创建签名的 AuthNRequest?【英文标题】:How to created signed AuthNRequest? 【发布时间】:2013-02-21 17:41:48 【问题描述】:

我正在与 IDP 交互,并创建了一个基本的 AuthNRequest,如下所示:

<samlp:AuthnRequest
  xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
  xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
  ID="IDTest1" 
  Version="2.0"
  IssueInstant="2013-03-04T09:21:59"
  AssertionConsumerServiceIndex="0"
  AttributeConsumingServiceIndex="0">
  <saml:Issuer>https://myapp.com/saml2/sp</saml:Issuer> 
 <samlp:NameIDPolicy
   AllowCreate="true"
   Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"/>
</samlp:AuthnRequest>     

IDP 希望我发送已签名的请求。我的问题是:

    如何设置摘要值? 如何设置签名值? 对于 x509 证书,我设置了我的应用程序的公钥。正确吗? 用于计算任何值的数据是什么?这是我没有签名元素的原始身份验证请求吗?

【问题讨论】:

我已经编辑了你的标题。请参阅“Should questions include “tags” in their titles?”,其中的共识是“不,他们不应该”。 @user1922049:如果你得到答案,你可以通过编辑你的问题来发布吗? 本书新版发布,涵盖OpenSAML V3 gumroad.com/l/a-guide-to-opensaml-v3 【参考方案1】:

请注意,文档中涵盖了很多内容:

SAML metadata.

要对请求进行签名,您需要添加类似这样的内容(通常在 sp.xml 中找到):

<SPSSODescriptor AuthnRequestsSigned="true" WantAssertionsSigned="false"
                 protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">

签名密钥看起来像:

<KeyDescriptor use="signing">
    <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
        <ds:X509Data>
            <ds:X509Certificate>
                MIIDWTC...CAkGgAwIBAgIEe+a+/uaSZCp5g2z+hRWRV+DyfQc9nO
            </ds:X509Certificate>
        </ds:X509Data>
    </ds:KeyInfo>
</KeyDescriptor>

其中 MII... 是公钥。

根据@Stefan,使用库要容易得多。

【讨论】:

【参考方案2】:

SAML 身份验证请求是一个 XML 文档。您可以像签署任何其他 XML 文档一样签署 SAML 身份验证请求。但是,有一些限制:

    签名必须是信封的签名。 在消化之前,SAML 身份验证请求不得通过封装签名转换和排他规范化转换以外的方法进行转换。 Signature 元素必须只包含一个 Reference 元素。 唯一 Reference 元素的 URI 必须包含签名的 SAML 身份验证请求的 ID 属性值。 在签名之前,必须使用专有规范化方法对 SignedInfo 元素进行规范化。

您可以在第 5 节中阅读 SAML 断言和协议规范 (http://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf) 的更多详细信息。

【讨论】:

【参考方案3】:

你的问题不充分!

您发送的 AuthRequest 似乎是 REDIRECT 请求,您不会看到摘要、签名和证书,因为所有这些详细信息都将作为参数在 URL 中。

尝试使用 POST SSO 请求,您将在其中看到 SAML 请求中的摘要、签名和证书。

一些要点:

常见

IdP 和 SP 都应该共享他们的 Metadata,这将有他们的基本配置,如 id、签名算法、散列方法、公钥等。 因此,根据 IdP 之间的合同,您应该使用您首选的编程语言对您的请求进行哈希处理和签名。

SP:

您应该使用您的公钥进行加密。 您应该使用您的私钥进行签名。 您应该使用 Base64 对您的请求进行编码。

IdP:

他们将使用请求中的公钥进行身份验证。 他们将使用加密和签名的 XML 进行响应。 您应该解密并取消签名响应。

快速链接

    Official Doc about SAML 2.0

    SAML Online Tool by OneLogin

【讨论】:

HTTP-Redirect 绑定中的 URL 参数只是相同数据的 Base64 编码版本。该问题询问如何生成签名,无论绑定类型如何,签名都是相同的(而不是如何发送签名,这可能会有所不同)。【参考方案4】:

如果您在没有任何更大框架的情况下构建自己的请求,我可以推荐 OpenSAML。它是一个帮助构建 SAML 消息的库。

在我的书A Guide to OpenSAML 中,对此以及更多内容进行了详细解释。

编辑我发布了一个new edition of the book,涵盖 OpenSAML V3

Here 是我写的关于签署 SAML 消息的示例

And one 关于如何调度 AuthnRequests。

【讨论】:

【参考方案5】:

嗯,关于安全的事情从来都不是一件容易的事…… 你应该明确地检查由@nzpcmad 链接的文档,以及 SAML2 profiles(查找 WB SSO - Web Browser Single Sign On)。

对于 Java,OpenSaml 确实是最简单的解决方案之一。

【讨论】:

【参考方案6】:

一个陷阱似乎是 HTTP 重定向绑定签名是由附加 URL 参数传输的,而不是 SAMLRequest 值的一部分,例如https://my-idp.com/login?SAMLRequest=nVNN...%3D&SigAlg=http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmldsig-more%23rsa-sha256&Signature=QZ64...%3D%3D

【讨论】:

以上是关于如何创建签名的 AuthNRequest?的主要内容,如果未能解决你的问题,请参考以下文章

配置 ADFS / Spring Security 以接受未签名的 SAML AuthnRequest

没有签名的AuthnRequest在Gitlab上使用SAML

Identity Server不验证SAML LogoutRequest签名

构造一个签名的 SAML2 LogOut 请求

Spring Security SAML:让 <Signature> 块出现在 <AuthnRequest>

shell 带签名请求,yii 处理带签名的请求