我有一个使用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作为发行者,从而导致冒充攻击。有没有办法根据用于令牌验证的证书来确定发布组织安全?
答案 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登录响应,则无法知道此特定响应令牌的位置来自 - 您正在查看当前身份,声称可能来自多个来源。但我认为在大多数现实情况下这应该足够了。