使用WSSecurityTokenSerializer读取在.Net中验证SAML断言的问题

Kei*_*ith 3 .net x509certificate single-sign-on saml-2.0 pkcs#7

我有一个SAML断言,我希望在.Net中使用WSSecurityTokenSerializer.

尽管存在一些问题,我还是拥有了密钥链和SAML XML .

首先,我从HTTPS POST获得SAML断言:

// spec says "SAMLResponse=" 
string rawSamlData = Request["SAMLResponse"];

// read the base64 encoded bytes
byte[] samlData = Convert.FromBase64String(rawSamlData);

// read back into a UTF string
string samlAssertion = Encoding.UTF8.GetString(samlData);

// get the SAML data in an XML reader
var assertionPostStream = new StringReader(samlAssertion);
var reader = XmlReader.Create(assertionPostStream);
Run Code Online (Sandbox Code Playgroud)

然后我得到了我的IdP提供的密钥:

// get the key data
byte[] certificateData = System.IO.File.ReadAllBytes("myKeys.p7b");

// decode the keys
var cms = new SignedCms(SubjectIdentifierType.IssuerAndSerialNumber);
cms.Decode(certificateData);

// we have a keychain of X509Certificate2s, we need a collection of tokens
var certificatesAsTokens =
    from X509Certificate2 cert in cms.Certificates
    select new X509SecurityToken(cert) as SecurityToken;

// get a token resolver
var tokens = new ReadOnlyCollection<SecurityToken>(
    certificatesAsTokens.ToList());
var resolver = SecurityTokenResolver.CreateDefaultSecurityTokenResolver(
    tokens, true);
Run Code Online (Sandbox Code Playgroud)

最后我收到一个错误:

// use the WS Security stuff to parse the reader
var securityToken = WSSecurityTokenSerializer.
    DefaultInstance.ReadToken(reader, resolver) as SamlSecurityToken;
Run Code Online (Sandbox Code Playgroud)

在调用时ReadToken我收到以下错误:

无法从'Response'元素中读取带有'urn:oasis:names:tc:SAML:2.0:protocol'的BinarySecretSecurityToken命名空间的标记,带有''ValueType.如果预期此元素有效,请确保将安全性配置为使用指定了名称,名称空间和值类型的标记.

我的SAML XML以:

<Response xmlns="urn:oasis:names:tc:SAML:2.0:protocol" ...
Run Code Online (Sandbox Code Playgroud)

很明显我Responseurn:oasis:names:tc:SAML:2.0:protocol命名空间中有一个元素.

知道这里有什么不对/错过吗?

And*_*bel 5

看起来您正在收到SAML2响应.尽管.NET 4.5中支持SAML2,但遗憾的是只支持断言 - 而不是协议本身(包括响应消息).

要在.NET中处理SAML2响应,您必须:

  1. 验证整个响应消息上的签名.
  2. 提取消息的断言部分.
  3. 阅读令牌Saml2SecurityTokenHandler.ReadToken().
  4. 使用验证令牌Saml2SecurityTokenHandler.DetectReplayedToken().
  5. 使用验证令牌 Saml2SecurityTokenHandler.ValidateConditions()
  6. 使用Saml2SecurityTokenHandler.CreateClaims()创建声明身份.

不幸的是,大多数这些方法都受到保护,但您可以继承Saml2SecurityTokenHandler并访问它们.

一个完整的工作示例可以在发现Saml2Response在类Sustainsys.Saml2项目.