找出哪个联盟合作伙伴向WIF发放了令牌

时间:2016-01-29 00:18:22

标签: asp.net wif adfs federated-identity ws-federation

我有一个使用Windows Identity Foundation的应用程序来启用来自多个合作伙伴的联合单点登录(让他们称之为Org1,Org2,Org3等)。因此,我的WIF配置包含所有合作伙伴的缩略图。证书 - 配置看起来像这样(为简洁省略了无关的部分):

<system.identityModel>
<identityConfiguration>    
  <issuerNameRegistry type="System.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry">
    <trustedIssuers>
      <add name="Org1" thumbprint="...certificate1..." />
      <add name="Org2" thumbprint="...certificate2..." />
      <add name="Org3" thumbprint="...certificate3..." />
    </trustedIssuers>
  </issuerNameRegistry>
</identityConfiguration>

但是,我不明白如何确定在验证传入令牌时实际使用了哪些证书。也就是说,我如何知道Org1,Org2或Org3是否向我发送了令牌?即,在以下代码中:

        var authModule = FederatedAuthentication.WSFederationAuthenticationModule;
        var request = new HttpRequestWrapper(Request);

        if (authModule.CanReadSignInResponse(request, true))
        {
            var principal = Thread.CurrentPrincipal;
            var message = authModule.GetSignInResponseMessage(request);
            var token = authModule.GetSecurityToken(request) as SamlSecurityToken;
            //???
        }

...如何使用principal / message / token变量(或者可能完全使用其他方法)来确定是否已发送Org1,Org2或Org3我的代币?我知道token.Assertion.Issuer,但这似乎直接来自令牌,所以看起来像是Org1可以发出一个令牌列表Org2作为发行者,从而导致冒充攻击。有没有办法根据用于令牌验证的证书来确定发布组织安全

1 个答案:

答案 0 :(得分:0)

我设法找到了2个解决方案:

方法1:

创建源自IssuerNameRegistry的自定义System.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry,并将其设置为您的名称注册表(例如<issuerNameRegistry type="MyNamespace.MyConfigurationBasedIssuerNameRegistry, My.Assembly.Name">)。

在自定义注册表中,覆盖同时带有令牌和字符串的GetIssuerName重载(根据令牌本身<令牌发布者 )。

在此覆盖中,调用基本GetIssuerName方法,您将获得name语句的<add thumbprint="..." name="...">属性,该证书实际用于验证令牌签名

此时,您拥有所需的所有信息(令牌声称的身份以及实际来自谁)。比较两者,如果令牌被模拟,则返回null(这将导致WIF拒绝令牌),否则返回从基本方法获得的内容。

如果name语句中的<add>属性始终是预期的令牌发行者网址,那么所有这些都变得非常简单:

class ValidatingConfigurationBasedIssuerNameRegistry : ConfigurationBasedIssuerNameRegistry
{
    public override string GetIssuerName(SecurityToken securityToken, string requestedIssuerName)
    {
        var configuredName = base.GetIssuerName(securityToken, requestedIssuerName);
        return (configuredName == requestedIssuerName) ? configuredName : null;
    }
}

方法2:

如答案here中所述,您可以访问Claims上的Thread.CurrentPrincipal as ClaimsPrincipal,并且每个Claim都有Issuer属性。事实证明,对于实际使用的证书来验证令牌签名,此属性将始终设置为name语句中的<add thumbprint="..." name="...">属性。

这有点不方便 - 如果您正在处理WS-Federation登录响应,则无法知道此特定响应令牌的位置来自 - 您正在查看当前身份,声称可能来自多个来源。但我认为在大多数现实情况下这应该足够了。