IDP,即提供身份认证服务的一端,通常,当 IDP 接收到 SP 发送的 SAML 认证请求后,解析 SAMLRequest 参数,包括 acs 地址、SP EntityId、绑定方式、是否加密等信息,当身份认证成功后便根据 SP 请求参数进行后续的通信。
在绑定方式为 Http post 方式中,当 IDP 认证成功后,便生成 Response 信息返回给 SP,一个 Response 的 xml 如下:
1 <samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" Destination="https://bw30.worktile.com/api/sso/postback/5a2f38f7499e182113286d28" ID="_8e8dc5f69a98cc4c1ff3427e5ce34606fd672f91e6" IssueInstant="2017-12-13T09:05:48Z" Version="2.0"> 2 <saml:Issuer>https://localhost:8080/idp</saml:Issuer> 3 <samlp:Status> 4 <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/> 5 </samlp:Status> 6 <saml:Assertion xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ID="_d71a3a8e9fcc45c9e9d248ef7049393fc8f04e5f75" IssueInstant="017-12-13T09:05:48Z" Version="2.0"> 7 <saml:Issuer>https://localhost:8080/idp</saml: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="#_d71a3a8e9fcc45c9e9d248ef7049393fc8f04e5f75"><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>k9i4QGA5BDFkW5I+Igr8hR1ibZs=</DigestValue></Reference></SignedInfo><SignatureValue>PLIKGZOFbMt8qEM1yw6f/Uct7R9Xd8KWZXw5925gIJdA8+q9MfY34+sQwDcy1Tqnxzak6hx6A6ol 8 Qr+zJCQH8O/S+sDgCEUhXG+PFU4j2pxnnYqwI3jKc2yeT7A7f8ShStgwN7IgjZ0TFLx2TO3tlZ76 9 2GwFHNN0lH9ohtAv8Zs=</SignatureValue><KeyInfo><X509Data><X509Certificate>MIICaDCCAdGgAaIBAgIEfnIVCzANBgkqhkiG9w0BAQsFADBnMQ4wDAYDVQQGEwVjaGluYTEQMA4G 10 A1UECBMHYmVpamluZzEQMA4GA1UEBxMHYmVpamluZzERMA8GA1UEChMIYmV3aW5uZXIxDTALBgNV 11 BAsTBGJ3MzAxDzANBgNVBAMTBnhpYW9zeTAeFw0xNzExMDgwOTU1NDVaFw0yNzExMDYwOTU1NDVa 12 MGcxDjAMBgNVBAYTBWNoaW5hMRAwDgYDVQQIEwdiZWlqaW5nMRAwDgYDVQQHEwdiZWlqaW5nMREw 13 DwYDVQQKEwhiZXdpbm5lcjENMAsGA1UECxMEYnczMDEPMA0GA1UEAxMGeGlhb3N5MIGfMA0GCSqG 14 SIb3DQEBAQUAA4GNADCBiQKBgQCgmrEMgAMY7zygYqBtYzMal0vTVsQNyjGkD3tbA+pEk18YfN13 15 UEBoqrp/XQiR4v334xqHjdtG8lxDzEUJ4fQippxMpw6Fab45pz6uOr33DI6X3IwLPxtb7q1MyIj3 16 TXBY6R01rwIaE+G8/5z76mN5qq4/lhoY3bs0D06pwUSSSQIDAQABoyEwHzAdBgNVHQ4EFgQURAyK 17 5AjoSEOk32ceEloftZ8TiWcwDQYJKoZIhvcNAQELBQADgYEAZuNWxMO8HOItqAoCI8f6+PfjbL/7 18 xTwDjs8PxnermmVjACx5JiW0O98M0D5Guo0OABf8mMxiDYQvRwpNoEfMOXr3TjPxqioLMq+s1Nt8 19 0Duilqel+O6Q/XDJ8rlVdm8vPhLxWZ14FIdI8n7CuuUwUExe4Uj05shCMwgNRo6bmaU=</X509Certificate></X509Data></KeyInfo></Signature> 20 <saml:Subject> 21 <saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">test@qq.com</saml:NameID> 22 <saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"> 23 <saml:SubjectConfirmationData NotOnOrAfter="2024-01-18T06:21:48Z" Recipient="https://localhost:8080/idp/sso"/> 24 </saml:SubjectConfirmation> 25 </saml:Subject> 26 <saml:Conditions NotBefore="017-12-13T09:05:48Z" NotOnOrAfter="2024-01-18T06:21:48Z"> 27 <saml:AudienceRestriction> 28 <saml:Audience>https://localhost:8080/sp/</saml:Audience> 29 </saml:AudienceRestriction> 30 </saml:Conditions> 31 <saml:AuthnStatement AuthnInstant="017-12-13T09:05:48Z"> 32 <saml:AuthnContext> 33 <saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef> 34 </saml:AuthnContext> 35 </saml:AuthnStatement> 36 </saml:Assertion> 37 </samlp:Response>
1、 samlp:Response
根节点,表明这是一个 response 对象
2、 Destination
目标地址,即 ACS 地址,Response 返回的地址
3、 ID
唯一标识
4、 IssueInstant
时间戳
5、 saml:Issuer
IDP 身份信息,IDP 的 EntityId
6、 samlp:Status
认证结果, samlp:StatusCode
表明认证成功或失败
7、 saml:Assertion
断言,这是 Response 中最为重要的字段,里面包含着用户身份信息
8、 Signature
断言的签名,使用非对称私钥对 Assertion 内容(不包含 Signature)进行签名,防止信息被篡改
9、 saml:Subject
身份主体,主要包括身份信息
10、 saml:NameID
身份信息
11、 saml:Conditions
给出了断言被认为有效的验证条件。
12、 saml:AuthnStatement
描述了在身份提供者的认证行为。
首先生成断言信息 Assertion,然后对断言进行签名,将签名信息插入到 Assertion 的子节点中,即 <Signature>
的信息,最后生成 Response 结构,将 Response 字符串进行 base64 编码后 post 到 acs 地址上,SP 对其进行验证。
当然,如果 SP 请求需要加密断言、加密响应,IDP 端必须对 Assertion 和 Signature 进行加密处理。
SAML 中的签名:
1 <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="#_d71a3a8e9fcc45c9e9d248ef7049393fc8f04e5f75"><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>k9i4QGA5BDFkW5I+Igr8hR1ibZs=</DigestValue></Reference></SignedInfo><SignatureValue>PLIKGZOFbMt8qEM1yw6f/Uct7R9Xd8KWZXw5925gIJdA8+q9MfY34+sQwDcy1Tqnxzak6hx6A6ol 2 8 Qr+zJCQH8O/S+sDgCEUhXG+PFU4j2pxnnYqwI3jKc2yeT7A7f8ShStgwN7IgjZ0TFLx2TO3tlZ76 3 9 2GwFHNN0lH9ohtAv8Zs=</SignatureValue><KeyInfo><X509Data><X509Certificate>MIICaDCCAdGgAaIBAgIEfnIVCzANBgkqhkiG9w0BAQsFADBnMQ4wDAYDVQQGEwVjaGluYTEQMA4G 4 10 A1UECBMHYmVpamluZzEQMA4GA1UEBxMHYmVpamluZzERMA8GA1UEChMIYmV3aW5uZXIxDTALBgNV 5 11 BAsTBGJ3MzAxDzANBgNVBAMTBnhpYW9zeTAeFw0xNzExMDgwOTU1NDVaFw0yNzExMDYwOTU1NDVa 6 12 MGcxDjAMBgNVBAYTBWNoaW5hMRAwDgYDVQQIEwdiZWlqaW5nMRAwDgYDVQQHEwdiZWlqaW5nMREw 7 13 DwYDVQQKEwhiZXdpbm5lcjENMAsGA1UECxMEYnczMDEPMA0GA1UEAxMGeGlhb3N5MIGfMA0GCSqG 8 14 SIb3DQEBAQUAA4GNADCBiQKBgQCgmrEMgAMY7zygYqBtYzMal0vTVsQNyjGkD3tbA+pEk18YfN13 9 15 UEBoqrp/XQiR4v334xqHjdtG8lxDzEUJ4fQippxMpw6Fab45pz6uOr33DI6X3IwLPxtb7q1MyIj3 10 16 TXBY6R01rwIaE+G8/5z76mN5qq4/lhoY3bs0D06pwUSSSQIDAQABoyEwHzAdBgNVHQ4EFgQURAyK 11 17 5AjoSEOk32ceEloftZ8TiWcwDQYJKoZIhvcNAQELBQADgYEAZuNWxMO8HOItqAoCI8f6+PfjbL/7 12 18 xTwDjs8PxnermmVjACx5JiW0O98M0D5Guo0OABf8mMxiDYQvRwpNoEfMOXr3TjPxqioLMq+s1Nt8 13 19 0Duilqel+O6Q/XDJ8rlVdm8vPhLxWZ14FIdI8n7CuuUwUExe4Uj05shCMwgNRo6bmaU=</X509Certificate></X509Data></KeyInfo></Signature>
SAML 中的签名算法就是对 xml 文档树进行签名,说明如下:
1、确认签名内容,通过 URL 将这些内容表示为引用资源,用 Reference
标识。对于断言信息来说,其 URI 是saml:Assertion
的 ID
2、对待签名的数据进行转化处理,包括执行编码规则、规范化算法等, Transform
指定了转化的算法
3、对整个断言进行消息摘要, DigestMethod
指定了消息摘要算法,消息摘要的结果保存在 DigestValue
元素中
4、构造包含 Reference 的 SignedInfo
元素
5、 CanonicalizationMethod
元素指定了规范化的算法,如果不对其进行规范化处理,验证 xml 签名时可能因为 xml 结构表示不同而失败
6、计算 SignedInfo 的摘要,使用 SignatureMethod
声明的签名算法,并对其进行签名,结果保存到 SignatureValue
元素中
7、 KeyInfo
元素可选,表明签名的公钥信息
SP 接收到 IDP 的响应后,验证签名,获取用户的信息后跳转响应页面。
写了一个小 demo, 源码地址是:https://github.com/xiaosiyuan/saml.git
验证方法:
1、运行 APP.java
2、模拟用户访问http://localhost:8080/index.html ,index.html 是一个受保护的资源
3、被重定向到 login.html 页面,输入用户名 admin、密码 admin, 登陆成功后跳转到 index.html 页面