断言令牌的XPath

时间:2014-07-01 14:04:32

标签: php soap xpath saml

我正在编写一个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;
}

感谢您的帮助, 添

2 个答案:

答案 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