我正在编写一个PHP脚本,需要获取Assertion
令牌作为在线登录 SharePoint 的过程的一部分。我能够获得包含我需要的令牌的信封响应。
我如何解析此回复的saml:Assertion
部分?
<s:Envelope xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:s="http://www.w3.org/2003/05/soap-envelope">
<s:Header>
<a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/trust/RSTR/Issue</a:Action>
<o:Security xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" s:mustUnderstand="1">
<u:Timestamp u:Id="_0">
<u:Created>2014-07-01T13:50:22.480Z</u:Created>
<u:Expires>2014-07-01T13:55:22.480Z</u:Expires>
</u:Timestamp>
</o:Security>
</s:Header>
<s:Body>
<t:RequestSecurityTokenResponse xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust">
<t:Lifetime>
<wsu:Created xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2014-07-01T13:50:22.476Z</wsu:Created>
<wsu:Expires xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2014-07-01T14:50:22.476Z</wsu:Expires>
</t:Lifetime>
<wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
<wsa:EndpointReference xmlns:wsa="http://www.w3.org/2005/08/addressing">
<wsa:Address>urn:federation:MicrosoftOnline</wsa:Address>
</wsa:EndpointReference>
</wsp:AppliesTo>
<t:RequestedSecurityToken>
<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" MajorVersion="1" MinorVersion="1" AssertionID="_56f0eee3-ca21-4885-a40d-4ae543e9bfc8" Issuer="http://paychex.com/adfs/services/trust/" IssueInstant="2014-07-01T13:50:22.480Z">
<saml:Conditions NotBefore="2014-07-01T13:50:22.476Z" NotOnOrAfter="2014-07-01T14:50:22.476Z">
<saml:AudienceRestrictionCondition>
<saml:Audience>urn:federation:MicrosoftOnline</saml:Audience>
</saml:AudienceRestrictionCondition>
</saml:Conditions>
<saml:AttributeStatement>
<saml:Subject>
<saml:NameIdentifier Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">qo3X1/EAe0Ci5pXaS+p8JA==</saml:NameIdentifier>
<saml:SubjectConfirmation>
<saml:ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:bearer</saml:ConfirmationMethod>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Attribute AttributeName="UPN" AttributeNamespace="http://schemas.xmlsoap.org/claims">
<saml:AttributeValue>email@email.com</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute AttributeName="ImmutableID" AttributeNamespace="http://schemas.microsoft.com/LiveID/Federation/2008/05">
<saml:AttributeValue>qo3X1/p8JA==</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
<saml:AuthenticationStatement AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:password" AuthenticationInstant="2014-07-01T13:50:22.473Z">
<saml:Subject>
<saml:NameIdentifier Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified">qo3X1/EAe0p8JA==</saml:NameIdentifier>
<saml:SubjectConfirmation>
<saml:ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:bearer</saml:ConfirmationMethod>
</saml:SubjectConfirmation>
</saml:Subject>
</saml: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="#_56f0eee3-ca21-4885-a40d-4ae543e9bfc8">
<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#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<ds:DigestValue>ZzoryFYQWfks=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>UnHrvM3vUE6l4HlpsuBX7E79750MNWASBuVNIVJ01QJSID8w3IHkjfMWCjidty7F96obL5Ah6o/UY55dMjbiyWt9gyToQPrGBPjG+VX3pEz8XpXV4jrYYXJ/YMpHxdzD/OBzR/bpA+lzebkuP19woqV49ScmJ5TN4b26LEW/ynogYnNl7EEBAJR0wL9CjY6uQCNaERY0X29nyNusQyNTNW4jGeMyBu9KnfVRpVyROd4QxfwV/F8OwGlePRGPypN/VYnLRjfizS674XJ31VmLERwxgn5Xx/0bKDsNw7c5G2qFZmSi7YUxccwMxU6Ypih7D5i73uPrk7oMnRbMHsyxCQ==</ds:SignatureValue>
<KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
<X509Data>
<X509Certificate>MIIC3DCCAcSgAwIBAgIQXIfoKmHCypFBv4Ze44WbzzANBgkqhkiG9w0BAQsFADAqMSgwJgYDVQQDEx9BREZTIFNpZ25pbmcgLSBhZGZzLnBheWNoZXguY29tMB4XDTE0MDQyNDAyMDY1NloXDTE5MDQyMzAyMDY1NlowKjEoMCYGA1UEAxMfQURkhc6NJSB8fJK+Uf/ldkC8VISTp7CW9S3TwXHKn4plqMLSY7NRYII4OPDkLXA9dGx3FQGNQoTe/uH1JGaNZlAGJp4W2Sz9r1i9Ry4lu+L0G3Q==</X509Certificate>
</X509Data>
</KeyInfo>
</ds:Signature>
</saml:Assertion>
</t:RequestedSecurityToken>
<t:RequestedAttachedReference>
<o:SecurityTokenReference xmlns:k="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" k:TokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1">
<o:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.0#SAMLAssertionID">_56f0eee3-ca21-4885-a40d-4ae543e9bfc8</o:KeyIdentifier>
</o:SecurityTokenReference>
</t:RequestedAttachedReference>
<t:RequestedUnattachedReference>
<o:SecurityTokenReference xmlns:k="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" k:TokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV1.1">
<o:KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.0#SAMLAssertionID">_56f0eee3-ca21-4885-a40d-4ae543e9bfc8</o:KeyIdentifier>
</o:SecurityTokenReference>
</t:RequestedUnattachedReference>
<t:TokenType>urn:oasis:names:tc:SAML:1.0:assertion</t:TokenType>
<t:RequestType>http://schemas.xmlsoap.org/ws/2005/02/trust/Issue</t:RequestType>
<t:KeyType>http://schemas.xmlsoap.org/ws/2005/05/identity/NoProofKey</t:KeyType>
</t:RequestSecurityTokenResponse>
</s:Body>
</s:Envelope>
我解析此响应的PHP代码段是:
// Parse security token from response
$xml = new DOMDocument();
$xml->loadXML($result);
$xpath = new DOMXPath($xml);
$nodelist = $xpath->query("/*[local-name()='name']:Body/*[local-name()='name']:RequestSecurityTokenResponse/*[local-name()='name']:RequestedSecurityToken/*[local-name()='name']:Assertion");
foreach ($nodelist as $n){
return $n->nodeValue;
break;
}
感谢您的帮助, 添
答案 0 :(得分:1)
我尝试使用// saml:Assertion但它不起作用
首先需要注册命名空间前缀 - XPath表达式不关心原始文档中使用了什么前缀,您需要自己将前缀绑定到命名空间。
$xpath->registerNamespace("s", "urn:oasis:names:tc:SAML:1.0:assertion");
$nodelist = $xpath->query("//s:Assertion");
但是这可能仍然会给你null,因为DOM中元素节点的“节点值”在规范中定义为始终为null。如果您希望文本在元素节点内,那么您需要使用textContent
而不是nodeValue
,但在这种情况下,您可能需要深入挖掘树以找到您真正想要的位。
答案 1 :(得分:0)
要简单地提取值,在XPath 1.0中,您可以使用以下表达式,忽略名称空间:
/*[local-name()='Envelope']
/*[local-name()='Body']
/*[local-name()='RequestSecurityTokenResponse']
/*[local-name()='RequestedSecurityToken']
/*[local-name()='Assertion']
或使用后代轴:
//*[local-name()='Assertion']
忽略名称空间应该是第二种选择。如果您可以按照@IanRoberts的建议在另一个答案中注册它们,那就更好了。
这些表达式中的任何一个都将返回一个 node-set ,其中包含找到的所有Assertion
元素(整个树)。这些节点的节点值或文本内容可能不是您要选择的。例如,如果要获取X509Certificate
,则应该对该元素使用上下文XPath表达式并提取其text()
。如果你想要一个子元素的属性,应该使用相同的策略。
更新您添加的PHP代码仅使用for循环来提取第一个节点。您可以使用item(0)
。假设每个文档中只有一个断言,密钥,证书等,您可以使用XPath表达式来准确提取您想要的内容。例如,要获取X509Certificate
文本(忽略名称空间和中间位置步骤),您可以使用:
$key_cert = $xpath->query("//*[local-name()='X509Certificate']")->item(0)->textContent