在.Net中使用WSSecurityTokenSerializer对SAML断言进行身份验证时出现问题

在.Net中使用WSSecurityTokenSerializer对SAML断言进行身份验证时出现问题,.net,single-sign-on,x509certificate,pkcs#7,saml-2.0,.net,Single Sign On,X509certificate,Pkcs#7,Saml 2.0,我有一个SAML断言,我希望在.Net中使用WSSecurityTokenSerializer进行身份验证 我有钥匙链和SAML XML,尽管如此 首先,我从HTTPS帖子中获得SAML断言: // spec says "SAMLResponse=" string rawSamlData = Request["SAMLResponse"]; // read the base64 encoded bytes byte[] samlData = Convert.FromBase64String(

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

我有钥匙链和SAML XML,尽管如此

首先,我从HTTPS帖子中获得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);
调用该
ReadToken
时,我得到以下错误:

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

我的SAML XML以以下内容开头:

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

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

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

  • 验证整个响应消息上的签名
  • 提取消息的断言部分
  • 使用Saml2SecurityTokenHandler.ReadToken()读取令牌。
  • 使用Saml2SecurityTokenHandler.DetectReplayedToken()验证令牌。
  • 使用Saml2SecurityTokenHandler.ValidateConditions()验证令牌。
  • 使用
    Saml2SecurityTokenHandler.CreateClaims()
    创建索赔标识
  • 不幸的是,这些方法中的大多数都受到保护,但是您可以将
    Saml2SecurityTokenHandler子类化并获得对它们的访问权


    在项目的课堂上可以找到一个完整的工作示例。

    经过几天的挖掘(关于这方面的文档非常糟糕)我认为这可能是由于
    WSSecurityTokenSerializer
    依赖于SAML 1.1而不是SAML 2.0的变体-我已经切换到尝试直接验证签名:如果您设置配置文件并使用
    FederatedAuthentication.FederationConfiguration.IdentityConfiguration.SecurityTokenHandlers
    。实际上,当签名在顶层而不是在断言上时,我发现我错了:上面的Saml2Response类链接给出了404。你有新路径吗?@BigJoe714谢谢你注意到断开的链接,现在已经修复了。然后,自撰写此文章以来,Saml2Response类已移动到另一个命名空间。Saml2Response链接已断开。你能更新链接吗?应该是这个吗?
    <Response xmlns="urn:oasis:names:tc:SAML:2.0:protocol" ...