【问题标题】:How do I use XPATH to parse the following that has a namespace?如何使用 XPATH 解析具有命名空间的以下内容?
【发布时间】:2011-11-09 02:31:56
【问题描述】:

我需要从 SAML 令牌中提取声明。我感兴趣的声明是http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider,在这种情况下我想获得值“Google”。

我在下面的代码中做错了什么?我稍微编辑了我的令牌响应,但还没有正确

代码:

    string strExpression = "//t:RequestSecurityTokenResponse/" +
            "t:RequestedSecurityToken/"+
            ""+"Assertion/AttributeStatement/Attribute";

        XmlDocument xmlDocument = new XmlDocument();
        xmlDocument.Load(@"claim.xml"); 
        XmlNode rootNode = xmlDocument.DocumentElement; 

        string ssNamespacePrefix = "t";
        string ssNamespaceURI = rootNode.GetNamespaceOfPrefix(ssNamespacePrefix);

        XPathNavigator xpathNav = xmlDocument.CreateNavigator();  

        XmlNamespaceManager namespaceManager = new XmlNamespaceManager(xmlDocument.NameTable);
        namespaceManager.AddNamespace(ssNamespacePrefix, ssNamespaceURI);

        XPathNodeIterator itr = xpathNav.Select(strExpression, namespaceManager);  

数据

<t:RequestSecurityTokenResponse Context="http://localhost:2600/" 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">2011-11-09T01:56:10.759Z</wsu:Created>
        <wsu:Expires xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2011-11-09T02:06:10.759Z</wsu:Expires>
    </t:Lifetime>
    <wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
        <EndpointReference xmlns="http://www.w3.org/2005/08/addressing">
            <Address>urn:federatasdf600</Address>
        </EndpointReference>
    </wsp:AppliesTo>
    <t:RequestedSecurityToken>
        <Assertion ID="_d70a5dasdfb868" IssueInstant="2011-11-09T01:56:10.775Z" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
            <Issuer>https://tlsadmin.accesscontrol.windows.net/</Issuer>
            <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/2001/04/xmldsig-more#rsa-sha256" />
                    <ds:Reference URI="#_d70aasdf868">
                        <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/2001/04/xmlenc#sha256" />
                        <ds:DigestValue>4WLBasdfouzBQ=</ds:DigestValue>
                    </ds:Reference>
                </ds:SignedInfo>
                <ds:SignatureValue>TiDaasfg5iA==</ds:SignatureValue>
                <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
                    <X509Data>
                        <X509Certificate>MIIDEasdfasdfasdfasdfasdfasdfzg==</X509Certificate>
                    </X509Data>
                </KeyInfo>
            </ds:Signature>
            <Subject>
                <NameID>https://www.google.com/accounts/o8/id?id=AItasdffMAm4</NameID>
                <SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer" />
            </Subject>
            <Conditions NotBefore="2011-11-09T01:56:10.759Z" NotOnOrAfter="2011-11-09T02:06:10.759Z">
                <AudienceRestriction>
                    <Audience>urn:federation:dev:rootwebDEV2600</Audience>
                </AudienceRestriction>
            </Conditions>
            <AttributeStatement>
                <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress">
                    <AttributeValue>User@gmail.com</AttributeValue>
                </Attribute>
                <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name">
                    <AttributeValue>Chris</AttributeValue>
                </Attribute>
                <Attribute Name="http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider">
                    <AttributeValue>Google</AttributeValue>
                </Attribute>
            </AttributeStatement>
        </Assertion>
    </t:RequestedSecurityToken>
    <t:RequestedAttachedReference>
        <SecurityTokenReference d3p1:TokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0" xmlns:d3p1="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
            <KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLID">_d70asdf1b868</KeyIdentifier>
        </SecurityTokenReference>
    </t:RequestedAttachedReference>
    <t:RequestedUnattachedReference>
        <SecurityTokenReference d3p1:TokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0" xmlns:d3p1="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
            <KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLID">_d70aasdfb868</KeyIdentifier>
        </SecurityTokenReference>
    </t:RequestedUnattachedReference>
    <t:TokenType>urn:oasis:names:tc:SAML:2.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>

【问题讨论】:

标签: c# .net xpath xml-namespaces xpathnavigator


【解决方案1】:

原因很简单

Assertion 元素位于默认 ("urn:oasis:names:tc:SAML:2.0:assertion") 命名空间中。

Xpath 认为不带前缀的名称位于“无命名空间”中,并且在评估提供的 XPath 表达式时:

//t:RequestSecurityTokenResponse
       /t:RequestedSecurityToken
          /Assertion
            /AttributeStatement/Attribute

找不到“无命名空间”中的Assertion元素。

因此,根本没有选择任何元素。

解决方案

  1. XmlNamespaceManager 中添加一个附加前缀(比如“x”),网址为:"urn:oasis:names:tc:SAML:2.0:assertion"

  2. 使用以下 XPath 表达式:

//t:RequestSecurityTokenResponse
       /t:RequestedSecurityToken
          /x:Assertion
            /x:AttributeStatement/x:Attribute

基于 XSLT 的验证

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust"
 xmlns:x="urn:oasis:names:tc:SAML:2.0:assertion">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
  <xsl:copy-of select=
  "//t:RequestSecurityTokenResponse
          /t:RequestedSecurityToken
               /x:Assertion
                   /x:AttributeStatement/x:Attribute "/>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于提供的 XML 文档时

<t:RequestSecurityTokenResponse Context="http://localhost:2600/" 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">2011-11-09T01:56:10.759Z</wsu:Created>
        <wsu:Expires xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">2011-11-09T02:06:10.759Z</wsu:Expires>
    </t:Lifetime>
    <wsp:AppliesTo xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy">
        <EndpointReference xmlns="http://www.w3.org/2005/08/addressing">
            <Address>urn:federatasdf600</Address>
        </EndpointReference>
    </wsp:AppliesTo>
    <t:RequestedSecurityToken>
        <Assertion ID="_d70a5dasdfb868" IssueInstant="2011-11-09T01:56:10.775Z" Version="2.0" xmlns="urn:oasis:names:tc:SAML:2.0:assertion">
            <Issuer>https://tlsadmin.accesscontrol.windows.net/</Issuer>
            <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/2001/04/xmldsig-more#rsa-sha256" />
                    <ds:Reference URI="#_d70aasdf868">
                        <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/2001/04/xmlenc#sha256" />
                        <ds:DigestValue>4WLBasdfouzBQ=</ds:DigestValue>
                    </ds:Reference>
                </ds:SignedInfo>
                <ds:SignatureValue>TiDaasfg5iA==</ds:SignatureValue>
                <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#">
                    <X509Data>
                        <X509Certificate>MIIDEasdfasdfasdfasdfasdfasdfzg==</X509Certificate>
                    </X509Data>
                </KeyInfo>
            </ds:Signature>
            <Subject>
                <NameID>https://www.google.com/accounts/o8/id?id=AItasdffMAm4</NameID>
                <SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer" />
            </Subject>
            <Conditions NotBefore="2011-11-09T01:56:10.759Z" NotOnOrAfter="2011-11-09T02:06:10.759Z">
                <AudienceRestriction>
                    <Audience>urn:federation:dev:rootwebDEV2600</Audience>
                </AudienceRestriction>
            </Conditions>
            <AttributeStatement>
                <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress">
                    <AttributeValue>User@gmail.com</AttributeValue>
                </Attribute>
                <Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name">
                    <AttributeValue>Chris</AttributeValue>
                </Attribute>
                <Attribute Name="http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider">
                    <AttributeValue>Google</AttributeValue>
                </Attribute>
            </AttributeStatement>
        </Assertion>
    </t:RequestedSecurityToken>
    <t:RequestedAttachedReference>
        <SecurityTokenReference d3p1:TokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0" xmlns:d3p1="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
            <KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLID">_d70asdf1b868</KeyIdentifier>
        </SecurityTokenReference>
    </t:RequestedAttachedReference>
    <t:RequestedUnattachedReference>
        <SecurityTokenReference d3p1:TokenType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0" xmlns:d3p1="http://docs.oasis-open.org/wss/oasis-wss-wssecurity-secext-1.1.xsd" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
            <KeyIdentifier ValueType="http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLID">_d70aasdfb868</KeyIdentifier>
        </SecurityTokenReference>
    </t:RequestedUnattachedReference>
    <t:TokenType>urn:oasis:names:tc:SAML:2.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>

选择想要的节点并将其复制到输出

<Attribute xmlns="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust" Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress">

   <AttributeValue>User@gmail.com</AttributeValue>

</Attribute>
<Attribute xmlns="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust" Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name">

   <AttributeValue>Chris</AttributeValue>

</Attribute>
<Attribute xmlns="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust" Name="http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider">

   <AttributeValue>Google</AttributeValue>

</Attribute>

【讨论】:

  • 谢谢,但它似乎不起作用,或者发生了其他事情。当我枚举“itr”时,枚举不会产生任何结果。我的代码与我发布的代码 1:1 匹配。我还注意到 x == t 的命名空间 URI
  • @TLDR:我有一个基于 XSLT 的验证——因此你的问题出在 C# 代码中——请检查你是否提供了确切的命名空间(区分大小写很重要)。另外,检查所选节点集的 cont。
  • @TLDR:我在答案的末尾添加了基于 XSLT 的验证。我现在要去工作了——如果我有 5 分钟的空闲时间,我也会提供完整的 C# 代码。
猜你喜欢
  • 2014-02-06
  • 2012-06-09
  • 2011-10-09
  • 2013-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多