单点登录-使用WSSecurityTokenSerializer读取.Net中的SAML断言身份验证时出现问题



我有一个SAML断言,我希望使用WSSecurityTokenSerializer在.Net中进行身份验证。

尽管存在一些问题,但我已经获得了密钥链和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);

然后我得到我的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);

最后我在这里得到一个错误:

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

当调用ReadToken时,我得到以下错误:

无法从BinarySecretSecurityToken的命名空间为"urn:assias:names:tc:SAML:2.0:protocol"、ValueType为"的"Response"元素中读取令牌。如果此元素预期是有效的,请确保将安全性配置为使用指定名称、命名空间和值类型的令牌。

我的SAML XML以开头

<Response xmlns="urn:oasis:names:tc:SAML:2.0:protocol" ...

很明显,我在urn:oasis:names:tc:SAML:2.0:protocol名称空间中有一个Response元素。

知道这里出了什么问题/缺了什么吗?

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

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

  1. 验证整个响应消息的签名
  2. 提取消息的断言部分
  3. 使用Saml2SecurityTokenHandler.ReadToken()读取令牌
  4. 使用Saml2SecurityTokenHandler.DetectReplayedToken()验证令牌
  5. 使用Saml2SecurityTokenHandler.ValidateConditions()验证令牌
  6. 使用Saml2SecurityTokenHandler.CreateClaims()创建索赔标识

不幸的是,这些方法中的大多数都受到保护,但您可以将Saml2SecurityTokenHandler子类化并访问它们。

在Sustainsys.Saml2项目的Saml2Response类中可以找到一个完整的工作示例。

相关内容

最新更新