从SAML断言中提取SecurityToken

zim*_*nen 4 c# saml

我有一个SAML断言的XML,如下所示:

<saml:Assertion MajorVersion="1" MinorVersion="1" AssertionID="_9b6e6302-d6a8-47f0-9155-1051a05edbfb" Issuer="http://example.com/adfs/services/trust" IssueInstant="2013-04-29T19:35:51.197Z" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion">
...
</saml:Assertion>
Run Code Online (Sandbox Code Playgroud)

我试图使用类似于以下代码从这个XML中获取SecurityToken:

// Loading the XML referenced above.
XDocument doc = XDocument.Load(new StringReader(assertion));

// Creating config to use in TokenHandlers below; required if not using a SecurityTokenHandlerCollection.
SecurityTokenHandlerConfiguration config = new SecurityTokenHandlerConfiguration();
config.AudienceRestriction.AllowedAudienceUris.Add(new Uri("https://localhost/Orchard/"));
config.CertificateValidator = X509CertificateValidator.None;

// Both of these lines throw Exceptions, as explained below.
new Saml11SecurityTokenHandler() { Configuration = config }.ReadToken(doc.CreateReader());
new Saml2SecurityTokenHandler() { Configuration = config }.ReadToken(doc.CreateReader());
Run Code Online (Sandbox Code Playgroud)

如果我尝试使用它读取令牌Saml11SecurityTokenHandler,我会得到以下异常:

ID4075:SAML断言缺少必需的"MajorVersion"属性.

如果我尝试使用它读取令牌Saml2SecurityTokenHandler,我会得到一个不同的例外:

没有找到名称空间名称为'urn:oasis:names:tc:SAML:2.0:assertion'的Element'Assertion'.

显然Saml2SecurityTokenHandler,这是有意义的,因为这是一个SAML 1.1断言.但是,为什么SAML 1.1 TokenHandler不能读取此断言?

编辑:读者似乎是空的; 这是为什么? doc有内容.

string notEmpty = doc.FirstNode.ToString();
string empty = doc.CreateReader().ReadOuterXml();
Run Code Online (Sandbox Code Playgroud)

zim*_*nen 7

根据此处显示的技术,这适用于:

SecurityToken token;
using (StringReader sr = new StringReader(assertion))
{
    using (XmlReader reader = XmlReader.Create(sr))
    {
        if (!reader.ReadToFollowing("saml:Assertion"))
        {
            throw new Exception("Assertion not found!");
        }
        SecurityTokenHandlerCollection collection = SecurityTokenHandlerCollection.CreateDefaultSecurityTokenHandlerCollection();
        token = collection.ReadToken(reader.ReadSubtree());
    }
}
Run Code Online (Sandbox Code Playgroud)

确保不要更改XML文档中的空格,否则您将收到签名验证错误.