#c# #.net #xpath #xml-namespaces #xpathnavigator
#c# #.net #xpath #xml-пространства имен #xpathnavigator
Вопрос:
Мне нужно извлечь утверждение из токена 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>
Комментарии:
1. Используемый вами подход — .NET 2.0. У вас есть доступ к использованию .NET 3.5 ? Вы действительно должны использовать System.Xml.Linq msdn.microsoft.com/en-us/library/bb299195.aspx для более эффективной и простой загрузки и анализа этих данных.
Ответ №1:
Причина проста:
Assertion
Элемент находится в пространстве имен по умолчанию ( "urn:oasis:names:tc:SAML:2.0:assertion"
).
Xpath считает, что имена без префиксов находятся в «no namespace» и при создании предоставленного выражения XPath:
//t:RequestSecurityTokenResponse
/t:RequestedSecurityToken
/Assertion
/AttributeStatement/Attribute
не удается найти ни один Assertion
элемент, который находится в «no namespace».
Таким образом, никакие элементы не выбираются вообще.
Решение:
-
Добавьте к
XmlNamespaceManager
дополнительный префикс (скажем, «x») с URL:"urn:oasis:names:tc:SAML:2.0:assertion"
-
Используйте следующее выражение 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>
Комментарии:
1. Спасибо, но, похоже, это не работает, или происходит что-то еще. Когда я перечисляю через «itr», перечисление не дает результатов. Мой код соответствует тому, что я опубликовал, в соотношении 1: 1. Также я заметил, что URI пространства имен для
x == t
2. @TLDR: У меня есть проверка на основе XSLT — следовательно, ваша проблема в коде C # — пожалуйста, убедитесь, что вы предоставляете точные пространства имен (важна чувствительность к регистру). Кроме того, проверьте cont выбранного набора узлов.
3. @TLDR: Я добавил проверку на основе XSLT в конец своего ответа. Я собираюсь работать сейчас — если у меня найдется 5 минут свободного времени, я также предоставлю полный код C #.