1.问题的提出
近期要使用Realme作为第三方接入,因为研究了一下Realme的请求过程(Request)和响应(Response),其中包含了一些加密和解密的方式。我们接下来分别从Request和Response两个方面进行讲述。
2.向Realme提交metadata
2.1根据模版修改sp-metadata.xml文件
我们在接入Realme之前,首先要向Realme平台提交我们的信息,其实就相当于把我们的应用注册到Realme。
我们可以从https://developers.realme.govt.nz/assets/Uploads/Integration-Bundle-MTS-V2.1.zip下载相关的资源包。
我们以资源包中的MTSSP_PostBinding_Sample.xml作为模版进行修改,需要修改以下几个项目:
(1)entityID
entityID: http://realme.test/mts2/sp
这个是我们接触Realme的唯一标识符,也就是ID。根据RealMe Messaging Specification Login V1.0.pdf第3.2.2 Element <Issuer>小节的说明:

entityID的值应该和AuthnRequest的Issuer的格式一致,Issuer格式要求请查询:https://developers.realme.govt.nz/how-realme-works/realme-request-parameters/#login-service-authentication-request
(2)Location
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://qacand.sflab.ondemand.com/saml2/SAMLAssertionConsumer?company=hmcscindiaec" index="0" isDefault="true" />
location属性就是IDP返回结果的时候,我们的服务器的接收地址,所以这个必须是公网可以访问的地址,不能使用内网的地址。 我们的配置如下:
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://52.198.228.221/post.php" index="0" isDefault="true" />
(3)Organization
1<md:Organization> 2 <md:OrganizationName xml:lang="en-us"> 3 Sample Service Provider 4 </md:OrganizationName> 5 <md:OrganizationDisplayName xml:lang="en-us"> 6 Sample Service Provider 7 </md:OrganizationDisplayName> 8 <md:OrganizationURL xml:lang="en-us"> 9 http://52.198.228.221/ 10 </md:OrganizationURL> 11</md:Organization>
这几个参数都是机构名称、机构显示名称、机构的URL这些参数,可以根据情况随便填。
(4)ContactPerson
1<md:ContactPerson contactType="technical"> 2 <md:Company>cloes</md:Company> 3 <md:GivenName>cloes</md:GivenName> 4 <md:SurName>375600284@qq.com</md:SurName> 5</md:ContactPerson>
这些是联系人信息,也可以根据情况随便填
一个完整的SP-metadata.xml例子如下:
1<md:EntityDescriptor ID="MTS SP" entityID="http://myrealme.test/mts2/sp" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:query="urn:oasis:names:tc:SAML:metadata:ext:query" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"> 2 <md:SPSSODescriptor AuthnRequestsSigned="true" WantAssertionsSigned="true" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"> 3 <md:KeyDescriptor use="signing"> 4 <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> 5 <ds:X509Data> 6 <ds:X509Certificate> 7MIIDgzCCAmugAwIBAgIEZ2ZIfzANBgkqhkiG9w0BAQsFADByMQswCQYDVQQGEwJO 8WjEQMA4GA1UECBMHVW5rbm93bjEQMA4GA1UEBxMHVW5rbm93bjEQMA4GA1UEChMH 9VW5rbm93bjEQMA4GA1UECxMHVW5rbm93bjEbMBkGA1UEAxMSbXRzLmNsaWVudC5z 10aWduaW5nMB4XDTE2MDMyNDIxNTQzNFoXDTE5MDMyNDIxNTQzNFowcjELMAkGA1UE 11BhMCTloxEDAOBgNVBAgTB1Vua25vd24xEDAOBgNVBAcTB1Vua25vd24xEDAOBgNV 12BAoTB1Vua25vd24xEDAOBgNVBAsTB1Vua25vd24xGzAZBgNVBAMTEm10cy5jbGll 13bnQuc2lnbmluZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANItT07w 1487HLup/Waw+Ek7S6RlJEu9xn1UXVfL84dkLufy21Cklnyzxzd2op9FbUq68jalIa 159hlguI9B7QqLplIcNOfhTWT+CFz9j0LL3PyOpl+/oDKJdwUPwtzz312fqfWz/vqZ 16Rz9cx0kmJlHUdz97WeD0Iem3px/4lM6nZtJWXF+0olZO5PxNnG/X8W9Y4qPT00FY 17AyHh0s2PUjbOuB9LAf4oWFxzNiluT5vifXLo0AR2u0m46dxxDbplX+G17/Ozs5Pv 18Ew/rBeUsLlgS862KClir16iw43TY6cTuw1fHUmqXuywrFwuKZUi5FX5yahGjKVxP 19oI/xg8QYDJASA5UCAwEAAaMhMB8wHQYDVR0OBBYEFFjGNNt5tDt6KqJcmo/HAv7F 20E2aeMA0GCSqGSIb3DQEBCwUAA4IBAQB1TvX7QbikPh/J2auRT+MWrScwDh9KQ/7c 21VysDKTqGFvQWm+t38hFwjy8DG6/GWzMmlvPzs+cpxxrU4wYINIki3q2XRMU5pNDS 22EWTqvcz+Of4WCNf0Kl6vaiQMo3AGhz36VemJeatiKTMnId9b//QKwG5qx9SGDKmY 23QOpm6Rtvai8oMhIX7Zgdv1pyVOIFvFbj8gC1U5krrwufSjTIZD8Vi0KCVYXLMXad 24BQj0IlNkxjIYgqj0oNhwemLs2vcXm/emYVjIekJVVgaY7E+pUTOkGQqJlLWP5p/G 254QhF24m0cEw6CaJVbXOuxQPo7u27TCM8FM1SBZEaFdOtVVB8rxO5 26 </ds:X509Certificate> 27 </ds:X509Data> 28 </ds:KeyInfo> 29 </md:KeyDescriptor> 30 <md:KeyDescriptor use="encryption"> 31 <ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> 32 <ds:X509Data> 33 <ds:X509Certificate> 34MIIDgzCCAmugAwIBAgIEZ2ZIfzANBgkqhkiG9w0BAQsFADByMQswCQYDVQQGEwJO 35WjEQMA4GA1UECBMHVW5rbm93bjEQMA4GA1UEBxMHVW5rbm93bjEQMA4GA1UEChMH 36VW5rbm93bjEQMA4GA1UECxMHVW5rbm93bjEbMBkGA1UEAxMSbXRzLmNsaWVudC5z 37aWduaW5nMB4XDTE2MDMyNDIxNTQzNFoXDTE5MDMyNDIxNTQzNFowcjELMAkGA1UE 38BhMCTloxEDAOBgNVBAgTB1Vua25vd24xEDAOBgNVBAcTB1Vua25vd24xEDAOBgNV 39BAoTB1Vua25vd24xEDAOBgNVBAsTB1Vua25vd24xGzAZBgNVBAMTEm10cy5jbGll 40bnQuc2lnbmluZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANItT07w 4187HLup/Waw+Ek7S6RlJEu9xn1UXVfL84dkLufy21Cklnyzxzd2op9FbUq68jalIa 429hlguI9B7QqLplIcNOfhTWT+CFz9j0LL3PyOpl+/oDKJdwUPwtzz312fqfWz/vqZ 43Rz9cx0kmJlHUdz97WeD0Iem3px/4lM6nZtJWXF+0olZO5PxNnG/X8W9Y4qPT00FY 44AyHh0s2PUjbOuB9LAf4oWFxzNiluT5vifXLo0AR2u0m46dxxDbplX+G17/Ozs5Pv 45Ew/rBeUsLlgS862KClir16iw43TY6cTuw1fHUmqXuywrFwuKZUi5FX5yahGjKVxP 46oI/xg8QYDJASA5UCAwEAAaMhMB8wHQYDVR0OBBYEFFjGNNt5tDt6KqJcmo/HAv7F 47E2aeMA0GCSqGSIb3DQEBCwUAA4IBAQB1TvX7QbikPh/J2auRT+MWrScwDh9KQ/7c 48VysDKTqGFvQWm+t38hFwjy8DG6/GWzMmlvPzs+cpxxrU4wYINIki3q2XRMU5pNDS 49EWTqvcz+Of4WCNf0Kl6vaiQMo3AGhz36VemJeatiKTMnId9b//QKwG5qx9SGDKmY 50QOpm6Rtvai8oMhIX7Zgdv1pyVOIFvFbj8gC1U5krrwufSjTIZD8Vi0KCVYXLMXad 51BQj0IlNkxjIYgqj0oNhwemLs2vcXm/emYVjIekJVVgaY7E+pUTOkGQqJlLWP5p/G 524QhF24m0cEw6CaJVbXOuxQPo7u27TCM8FM1SBZEaFdOtVVB8rxO5 53 </ds:X509Certificate> 54 </ds:X509Data> 55 </ds:KeyInfo> 56 </md:KeyDescriptor> 57 <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="http://52.198.228.221/post.php" index="0" isDefault="true" /> 58 </md:SPSSODescriptor> 59 <md:Organization> 60 <md:OrganizationName xml:lang="en-us"> 61 Sample Service Provider 62 </md:OrganizationName> 63 <md:OrganizationDisplayName xml:lang="en-us"> 64 Sample Service Provider 65 </md:OrganizationDisplayName> 66 <md:OrganizationURL xml:lang="en-us"> 67 http://52.198.228.221/ 68 </md:OrganizationURL> 69 </md:Organization> 70 <md:ContactPerson contactType="technical"> 71 <md:Company>cloes</md:Company> 72 <md:GivenName>cloes</md:GivenName> 73 <md:SurName>375600284@qq.com</md:SurName> 74 </md:ContactPerson> 75</md:EntityDescriptor>
2.2上传sp的metadata文件
sp的metadata文件上传地址:https://mts.realme.govt.nz/logon-mts/metadataupdate
然后如果通过格式校验后,就会显示如下的页面:

点击“import”后,就会显示如下页面:

3.创建AuthnRequest请求
3.1 AuthnRequest的例子
我们可以在RealMe Messaging Specification Login V1.0.pdf中的3.6 Sample Request中找到AuthnRequest的例子:
1<samlp:AuthnRequest 2 xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" 3 xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" 4 AssertionConsumerServiceIndex="0" 5 Destination="https://realme.govt.nz/sso/SSORedirect/metaAlias/logon-idp" 6 ID="a958a20e059c26d1cfb73163b1a6c4f9" 7 IssueInstant="2012-05-21T00:39:32Z" 8 ProviderName="Sample Service Provider" 9 Version="2.0"> 10 <saml:Issuer>https://www.sample-client.co.nz/onlineservices/service1</saml:Issuer> 11 <samlp:NameIDPolicy AllowCreate="true" Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"></samlp:NameIDPolicy> 12 <samlp:RequestedAuthnContext> 13 <saml:AuthnContextClassRef> 14 urn:nzl:govt:ict:stds:authn:deployment:GLS:SAML:2.0:ac:classes:ModStrength 15 </saml:AuthnContextClassRef> 16 </samlp:RequestedAuthnContext> 17</samlp:AuthnRequest>
3.2 对AuthnRequest的xml数据进行处理
根据saml-bindings-2.0-os.pdf中3.4.4 Message Encoding的描述,我们需要对AuthnRequest按照以下顺序进行操作:
- DEFLATE compression
- base64-encoded
- URL-encoded
具体可以使用Realme-Go-SDK(https://github.com/cloes/Realme-GO-SDK)
注意:
-
在这里ID的规则必须以字母"a"开头,例如上面例子中的ID="a958a20e059c26d1cfb73163b1a6c4f9"
-
issueInstant为AuthnRequest的生成时间,有效时间只有60s,如果超时的话,就需要重新生成issueInstant时间
-
issueInstant使用的是UTC时间,格式是2012-05-21T00:39:32Z
3.3 向Realme的测试平台提交AuthnRequest
3.3.1 向MTS平台提交测试请求
我们可以向Realme的测试地址提交POST请求,对我们的AuthnRequest进行测试。
测试地址:https://mts.realme.govt.nz/logon-mts/mtsEntryPoint
例如,我们经过上述的数据处理后,我们得到的url地址是:
https://mts.realme.govt.nz/logon-mts/mtsEntryPoint?SAMLRequest=fZJbbxoxEIWfm19h%2BR32QkLCiF0JQVshJRUKVR7y5ngHWMlrbz2zFPLra3ORNlLFq%2BccnW%2FGZ0qqMS3MOt7ZV%2FzTIbE4NMYSxEEhO2%2FBKaoJrGqQgDWsZy%2FPkA9TUETouXZW9iztbU%2FrHTvtjBSzq3vuLHUN%2BjX6fa1xaSs8FDKVYhFgaquippA75pYgSRqmoUdlGhxu3Z6H9jMxbuvsIAzi8Ltlf1y52rIUy0Uh1eThSeUppg8TnY%2BrTG8%2BHkfZePSRqbG%2B30yCiqgLqcTKciHzNHsapPkgG%2F9OR5A%2Fwn32LsXKu31dof8VFjqzRJTjBYQDaMzOE2qleENPJ%2BSwryzvhJjGu8Apxpe3vNOkr7w6W4ipy8XKmVofxcwY93ce3BxI2HcoxQ%2FnG8W3Dx9f6mqwOUmhjYzEGK5UnlO%2FpvTCL63A6tSR8FmMBy7vvp236j%2FOTWjEK27KyGE%2FDcQPglozEFcEKkqhwta4YxOS4efzulcmDTr6A%2FaLq9bs0W55d7nIf1MiYnKT8Trut7v8Bw%3D%3D&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1&Signature=0U0j1l0a5rwCMWxN8fcU%2BJsLjAJLiTTZgBVWRdz3GkJ%2BojkeGWFVcyGgUepRWYyC%2FlemTluAKpHOAXr1INg2luskaZ%2BWSpQRKUC6t68zEzuZSkhkxnp1YiOWMNlqMCfAT0OdxlADqvwGd2qzCeBN5FxJ0cdqpNdy7g%2BP%2B6PukB8wOTGWqp0AfAaAK506ZDiuvZofg8rotIxYYmuloA44mOiQw5D5aV04FkThZSPBsZ9XvEXeB4aKHFpaTRsguxxsUNc8tttuW5aUJsNwunU%2Fk2ybxYYiA80CSqZR5qTFc7DP%2Fz90DtvzADXoyrMTpKGJp6pWWobNRly9g17IJxtqoA%3D%3D
在有效时间内,访问上述地址,测试系统会显示如下页面:

3.3.2 向MTS的在线校验平台验证AuthnRequest的格式正确性(可选步骤)
我们可以先在线验证我们的AuthnRequest请求格式,确定了格式的正确性后,我们再向正式的MTS平台发起请求。
在线校验地址:https://mts.realme.govt.nz/logon-mts/authnrequestsubmit
如果验证不通过的话,它会显示相关的错误信息,如图:

如果验证通过,我们会得到以下的页面:

我们可以在User fit输入框中输入我们自定义的内容,本例中我们输入"CLoesTest"
4.对Response响应进行解密
4.1 进行base64逆向编码
Realme返回的Response是经过base64的,我们需要对它进行base64的逆向编码。逆向编码后的结果如下:
1<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="s25cb319258fe2feb9b98c29d2bb3819de8d9950cc" InResponseTo="a958a20e059c26d1cfb73163b1a6c4f9" Version="2.0" IssueInstant="2018-01-23T11:19:44Z" Destination="http://52.198.228.221/post.php"><saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://mts.realme.govt.nz/saml2</saml:Issuer><samlp:Status xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"> 2<samlp:StatusCode xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" 3Value="urn:oasis:names:tc:SAML:2.0:status:Success"> 4</samlp:StatusCode> 5</samlp:Status><saml:EncryptedAssertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"><xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Type="http://www.w3.org/2001/04/xmlenc#Element"><xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><xenc:EncryptedKey><xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/><xenc:CipherData><xenc:CipherValue>lPptVGLFfJk/BiJsS1/XPwtJGwuGc8M4c1Qq1RkBYbS4cwIIS1AljVC88qaSCKTqh7PFBF+LSyeW 6tiXPhx8N01T9s1OYfxszXSSWB/u0P8KB4Vh9mpux+ZRxvlDm46Nn7FZ6lnR/bqWbec058Gpi+yt8 7iC5lNPT4yYjJZw5WZi2wMCSLlalQZtgQ156hhCmg8jcEqVi887j2+XwBkCl5ooUef3cezg/nFx40 8f4kdbXwaKJFASg2iM98KHo3HNeJRM/u/rNgrvmbjoHWvTZAbd4Im4yzmB+b7EpSX+YGOqySD8HF4 9uY70nayiLskLAbqfM6X9Vsmp3njksgbNO+WYBw==</xenc:CipherValue></xenc:CipherData></xenc:EncryptedKey></ds:KeyInfo><xenc:CipherData><xenc:CipherValue>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 787Ju8XPlIDZNSQOATi6VCbdJQYw==</xenc:CipherValue></xenc:CipherData></xenc:EncryptedData></saml:EncryptedAssertion></samlp:Response>
我们看到samlp:StatusCode标签:
1<samlp:StatusCode xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Value="urn:oasis:names:tc:SAML:2.0:status:Success"> 2</samlp:StatusCode>
StatusCode标签的结果表明了我们的这次请求是成功的。下面是请求失败的情况下的错误代码:

4.2 对Response内容进行AES解密
4.2.1 获取AES密钥
标签xenc:CipherValue中的内容就是AES的密钥:
1<xenc:CipherValue>lPptVGLFfJk/BiJsS1/XPwtJGwuGc8M4c1Qq1RkBYbS4cwIIS1AljVC88qaSCKTqh7PFBF+LSyeW 2tiXPhx8N01T9s1OYfxszXSSWB/u0P8KB4Vh9mpux+ZRxvlDm46Nn7FZ6lnR/bqWbec058Gpi+yt8 3iC5lNPT4yYjJZw5WZi2wMCSLlalQZtgQ156hhCmg8jcEqVi887j2+XwBkCl5ooUef3cezg/nFx40 4f4kdbXwaKJFASg2iM98KHo3HNeJRM/u/rNgrvmbjoHWvTZAbd4Im4yzmB+b7EpSX+YGOqySD8HF4 5uY70nayiLskLAbqfM6X9Vsmp3njksgbNO+WYBw==</xenc:CipherValue>
这个密钥也是经过base64编码的,我们需要对它进行base64的逆向编码。接下来,我们还需要对其进行RSA解密,我们使用Integration-Bundle-MTS-V2.1.zip中的mts_saml_sp.pem文件作为RSA的私钥,然后对AES的密钥进行解密,解密后的内容才是真正的AES密钥。
CipherValue标签值->base64解码->RSA解密
4.2.2 获取AES的IV值
Response的xml里面指明了加密方式:
<xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
Algorithm值说明了使用的是AES128-CBC加密方式,我们打开链接http://www.w3.org/2001/04/xmlenc#aes128-cbc
然后,我们可以在章节 "5.2.2 AES" 看到如下的内容:
1[AES] is used in the Cipher Block Chaining (CBC) mode with a 128 bit initialization vector (IV). The resulting cipher text is prefixed by the IV. If included in XML output, it is then base64 encoded. An example AES EncryptionMethod is as follows: 2 3<EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/>
上面的内容指出AES的加密内容的前面的128bit就是initialization vector (IV),128 bit就是16字母。
我们在xenc:CipherValue中找到了AES的内容,截取前面的16个字符就是:
eFNfWyzq4uqUjtZI
4.2.3 对主体内容进行AES解密
xenc:CipherValue标签里面的内容就是AES的主体加密内容,也是经过了base64编码的,我们对其进行base64逆向编码,然后得到的是经过AES加密的一串乱码。接下来,我们使用前面获得的AES密钥和IV对AES的内容进行解密。
PS:AES使用的padding方式是PKCS#5
AES正确解密后的内容格式是xml:
1<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="s208b1e913d1cbc624cc460731a07d0a20029f0fe2" IssueInstant="2018-01-23T11:19:44Z" Version="2.0"> 2<saml:Issuer>https://mts.realme.govt.nz/saml2</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> 3<ds:SignedInfo> 4<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:CanonicalizationMethod> 5<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"></ds:SignatureMethod> 6<ds:Reference URI="#s208b1e913d1cbc624cc460731a07d0a20029f0fe2"> 7<ds:Transforms> 8<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"></ds:Transform> 9<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"></ds:Transform> 10</ds:Transforms> 11<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"></ds:DigestMethod> 12<ds:DigestValue>VtVdWXO0ra7OOBUT6S5X0QyaNAk=</ds:DigestValue> 13</ds:Reference> 14</ds:SignedInfo> 15<ds:SignatureValue> 16emG7LErhFWVv6CqGvrY3IxeKT8MssQn8ZfrkuLIwZgnxSoCunq8sqnJDd5U2YIhp/jJwn2R/fA4L 17foAeIlDwMX+/VRTcBoQAer5lBNPDqIWFqzza1R5+KxTfgQAe+tgvLAypk7M18u8vwAkLSaNtlE2Y 18zu7CK5i6QVN+3V6Rt2LzjoQE8MYZwG9Qu75+xHeurZ9xzccfG64FmAB5QG+vRFXVUeYCywGuhhen 198AvFn+zOfSdxfe/FIXDCp4a4dajHFtuJTBhbX255skKX+XPebApydgJlulQ5VX/Xzr27Kpnbo4J0 20WGDLOs/FyssV79a3LszIKyBqVjP4fy0GZ3gYCA== 21</ds:SignatureValue> 22<ds:KeyInfo> 23<ds:X509Data> 24<ds:X509Certificate> 25MIIECTCCAvGgAwIBAgIEM4QPozANBgkqhkiG9w0BAQUFADCBtDELMAkGA1UEBhMCTloxEzARBgNV 26BAgTCldlbGxpbmd0b24xEzARBgNVBAcTCldlbGxpbmd0b24xJzAlBgNVBAoTHkRlcGFydG1lbnQg 27b2YgSW50ZXJuYWwgQWZmYWlyczEnMCUGA1UECxMeRGVwYXJ0bWVudCBvZiBJbnRlcm5hbCBBZmZh 28aXJzMSkwJwYDVQQDEyBtdHMuc2lnbmluZy5sb2dvbi5yZWFsbWUuZ292dC5uejAeFw0xMzA5MTEy 29MTU5NDVaFw0yMzA5MDkyMTU5NDVaMIG0MQswCQYDVQQGEwJOWjETMBEGA1UECBMKV2VsbGluZ3Rv 30bjETMBEGA1UEBxMKV2VsbGluZ3RvbjEnMCUGA1UEChMeRGVwYXJ0bWVudCBvZiBJbnRlcm5hbCBB 31ZmZhaXJzMScwJQYDVQQLEx5EZXBhcnRtZW50IG9mIEludGVybmFsIEFmZmFpcnMxKTAnBgNVBAMT 32IG10cy5zaWduaW5nLmxvZ29uLnJlYWxtZS5nb3Z0Lm56MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A 33MIIBCgKCAQEA5A+xjCmkrgqpSnkhCllJeisEfZn0VoyhLrPRSyZfjikufWhNoR9lDUP1wjqz/jIm 34q7H46t8qHFkGbLO85ODkCsYiq+gSxh+TF1K3bGwtlz7m6QYFNURFid7AH8NaXEF6rylogHjSoJx/ 351cuujIcb/qXCd0YXDICVqG74g0jkyk3V3gJuy5utTft6KrU/h9IuIudTP5xKwcaRtXlZoZkxxcOa 36P6aBw8EPks3mfA7pknOtb1fvlYF4bXggNFYqxJCtBi5gLYQISRL8UWAW/EdN+mDIXn9BuQAsuS3s 371DTx/+dJy+9CZXNzK5i6bCj6TBnugasbkoOx8fdpYBmGlIZO7QIDAQABoyEwHzAdBgNVHQ4EFgQU 38k53+2zIt62M8okGTDzgEiYfDR4swDQYJKoZIhvcNAQEFBQADggEBAFatYWgm1Tst/UbCDOXYziVp 39nzCs8DPcswcETlQuju3Y4ys/spMgugrErqxyWcEB9nf9amtYFPkeuCwQ9PUxHCjSCCzmS9T6PhK+ 40iX83vL+IlMe3RsR9pdAYBI2lUcTMLHy2jGfgwTF+nGvH/48PImu7EAZj7pQgY3gk3J1F23BZ28aH 415N+RuDBY+17nk/yiqierT1J8/RUE2SGT9029sM0XSTQNYj3rB7K6foISbhqeiNlVDBmXUBWNtNxX 42k6M088a1Op/ZucUC1haKpHtsszuF8wxC0PApX+yZWdiOPTewCWBhRjWMbr1gQJ7FV+LcpIHUqxaq 43JPsnOwYNA0BljHk= 44</ds:X509Certificate> 45</ds:X509Data> 46</ds:KeyInfo> 47</ds:Signature><saml:Subject> 48<saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" NameQualifier="https://mts.realme.govt.nz/saml2" SPNameQualifier="http://myrealme.test/mts2/sp">CloesTest</saml:NameID><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"> 49<saml:SubjectConfirmationData InResponseTo="a958a20e059c26d1cfb73163b1a6c4f9" NotOnOrAfter="2018-01-23T11:29:44Z" Recipient="http://52.198.228.221/post.php"></saml:SubjectConfirmationData></saml:SubjectConfirmation> 50</saml:Subject><saml:Conditions NotBefore="2018-01-23T11:09:44Z" NotOnOrAfter="2018-01-23T11:29:44Z"> 51<saml:AudienceRestriction> 52<saml:Audience>http://myrealme.test/mts2/sp</saml:Audience> 53</saml:AudienceRestriction> 54</saml:Conditions> 55<saml:AuthnStatement AuthnInstant="2018-01-23T11:19:44Z" SessionIndex="s217b46f7dc993c8eca69f20759bead732962ddb01"><saml:AuthnContext><saml:AuthnContextClassRef>urn:nzl:govt:ict:stds:authn:deployment:GLS:SAML:2.0:ac:classes:ModStrength</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement></saml:Assertion>
请注意下面的xml标签:
<saml:SubjectConfirmationData InResponseTo="a958a20e059c26d1cfb73163b1a6c4f9" NotOnOrAfter="2018-01-23T11:29:44Z" Recipient="http://52.198.228.221/post.php">
里面的InResponseTo是和AuthnRequest中的ID是对应的,这个请求的AuthnRequest可以看前面的内容,这里再发一遍ID部分内容:
1<samlp:AuthnRequest 2xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" 3xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" 4AssertionConsumerServiceIndex="0" 5Destination="https://realme.govt.nz/sso/SSORedirect/metaAlias/logon-idp" 6ID="a958a20e059c26d1cfb73163b1a6c4f9" 7IssueInstant="2012-05-21T00:39:32Z" 8ProviderName="Sample Service Provider" 9Version="2.0">
通过这个InResponseTo的返回值,我们可以和AuthnReauest请求一一对应起来。
另外,Response还返回了User Fit的值:
<saml:NameID Format="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent" NameQualifier="https://mts.realme.govt.nz/saml2" SPNameQualifier="http://myrealme.test/mts2/sp">CloesTest</saml:NameID>
我们前面在Realme的测试地址中,使用"CloesTest"作为User Fit的值,在这个Response中系统返回了这个值。
至此,对于Realme的AuthnRequest已经完成,我们可以根据自身的业务需要,根据AuthnRequest的返回结果来写入session等相关的用户凭证操作。