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 頁面