在工作中,我们有一个 Web 应用程序,我们需要使用 SAML 验证的单点登录与另一家公司的 Web 应用程序交互。我们的 Web 应用程序是用 PHP 编写的,显然与其他公司使用的语言选择无关。尽管如此,我需要编写一个简单的 API,这家其他公司可以使用 SAML 请求向其发送 SOAP 请求,并生成回 SAML 响应。我一直从头开始编写它,原因有三个:1)即使我想要一个用 PHP 编写的 SAML 交互,似乎也没有很多选择,2)它限制了添加另外三分之一所涉及的开销- 派对组件,以及3)从头开始创建东西通常会让我有更好的理解,并使我更有能力在未来需要时适应这些东西。
无论如何,总的来说,我对 SAML、SOAP 和 XML 标准还很陌生,所以我一直在自学。对于我们的目的,我已经获得了非常完整的 API,除了另一家公司指定我们的响应将需要使用证书进行数字签名(并且我们收到的请求也将类似地进行数字签名)。所以我一直在试图弄清楚如何处理/生成 XML 签名,但老实说,这有点令人困惑,因为 W3C 规范并不是很容易阅读。
OASIS 安全标记语言 (SAML) V1.1文档的断言和协议的第 5.4.8 节(我一直在关闭的文档,因为另一家公司说他们将使用 v1.1)包括一个示例包含签名断言的签名响应,我将在此处包含它以供参考:
<Response IssueInstant="2003-04-17T00:46:02Z" MajorVersion="1" MinorVersion="1"
Recipient="www.opensaml.org" ResponseID="_c7055387-af61-4fce-8b98-e2927324b306"
xmlns="urn:oasis:names:tc:SAML:1.0:protocol"
xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<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/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#_c7055387-af61-4fce-8b98-e2927324b306">
<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#">
<InclusiveNamespaces PrefixList="#default saml samlp ds xsd xsi"
xmlns="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>TCDVSuG6grhyHbzhQFWFzGrxIPE=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>x/GyPbzmFEe85pGD3c1aXG4Vspb9V9jGCjwcRCKrtwPS6vdVNCcY5rHaFPYWkf+5EIYcPzx+pX1h43SmwviCqXRjRtMANWbHLhWAptaK1ywS7gFgsD01qjyen3CP+m3Dw6vKhaq1ed10BYyrIzb4KkHO4ahNyBVXbJwqv5pUaE4=</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIICyjCCAjOgAwIBAgICAnUwDQYJKoZIhvcNAQEEBQAwgakxCzAJBgNVBAYTA1VT ... 8I3bsbmRAUg4UP9hH6ABVq4KQKMknxu1xQxLhpR1y1GPdiowMNTrEG8cCx3w/w==</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
<Status><StatusCode Value="samlp:Success"/></Status>
<Assertion AssertionID="_a75adf55-01d7-40cc-929f-dbd8372ebdfc"
IssueInstant="2003-04-17T00:46:02Z" Issuer="www.opensaml.org"
MajorVersion="1" MinorVersion="1" xmlns="urn:oasis:names:tc:SAML:1.0:assertion"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Conditions NotBefore="2003-04-17T00:46:02Z" NotOnOrAfter="2003-04-17T00:51:02Z">
<AudienceRestrictionCondition>
<Audience>http://www.opensaml.org</Audience>
</AudienceRestrictionCondition>
</Conditions>
<AuthenticationStatement AuthenticationInstant="2003-04-17T00:46:00Z"
AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:password">
<Subject>
<NameIdentifier Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">scott@example.org</NameIdentifier>
<SubjectConfirmation>
<ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:bearer</ConfirmationMethod>
</SubjectConfirmation>
</Subject>
<SubjectLocality IPAddress="127.0.0.1"/>
</AuthenticationStatement>
<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/2000/09/xmldsig#rsa-sha1"/>
<ds:Reference URI="#_a75adf55-01d7-40cc-929f-dbd8372ebdfc">
<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#">
<InclusiveNamespaces PrefixList="#default saml samlp ds xsd xsi"
xmlns="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transform>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>Kclet6XcaOgOWXM4gty6/UNdviI=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>hq4zk+ZknjggCQgZm7ea8fI79gJEsRy3E8LHDpYXWQIgZpkJN9CMLG8ENR4Nrw+n7iyzixBvKXX8P53BTCT4VghPBWhFTSt9tHWu/AtJfOTh6qaAsNdeCyG86jmtp3TDMWuL/cBUj2OtBZOQMFn7jQ9YB7k1Iz3RqVL+wNmeWI4=</ds:SignatureValue>
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIICyjCCAjOgAwIBAgICAnUwDQYJKoZIhvcNAQEEBQAwgakxCzAJBgNVBAYTA1VT ... 8I3bsbmRAUg4UP9hH6ABVq4KQKMknxu1xQxLhpR1y1GPdiowMNTrEG8cCx3w/w==</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</ds:Signature>
</Assertion>
</Response>
那么我如何生成这样的东西呢?如果我收到这样的东西,我该如何验证它?<ds:Signature>
此外,任何人都可以提供这里标签的基本概念概述吗?似乎有两个<ds:Signature>
标签,一个在 main<Response>
中,一个在 中<Assertion>
,每个标签都包含自己的<ds:DigestValue>
,<ds:SignatureValue>
和<ds:X509Certificate>
(并且每个标签都不同)。这些是如何产生的?您可以对此有所了解的任何信息将不胜感激。教程或代码示例将更加感激!但在这一点上,如果你能让我走上正轨,这就是我真正想要的。现在,这一切对我来说仍然像是一个大黑匣子。
顺便说一句,如果这有帮助,它在 SAML 1.1 规范的其他地方说,SAML 实现应该只使用“Exclusive Canonicalization”方法(Excl-C14N)并且应该只使用“envelope transform”。我仍然不完全确定这意味着什么。