gpt4 book ai didi

.net - 联合安全 - 单独的 SSL 和 RP 证书(.NET 4.5 和 WIF)

转载 作者:行者123 更新时间:2023-12-01 12:41:10 24 4
gpt4 key购买 nike

我目前正在研究一个解决方案,该解决方案使用 STS、客户端和客户端使用的 WCF 服务。目前,这一切都是通过配置完成的,客户端成功检索 token 并将其传递给 WCF 服务。

问题出现在证书上,我们正在使用受传输安全保护的 net.tcp 绑定(bind)以及安全 token ,并且作为此要求,我们需要 SSL 证书。这个证书配置如下(我去掉了不相关的xml):

<behavior name="Federated">
<serviceAuthorization principalPermissionMode="Always" />
<serviceCredentials useIdentityConfiguration="true">
<serviceCertificate findValue="CN=SSLCert" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectDistinguishedName" />
</serviceCredentials>
</behavior>

问题是这里指定的服务证书也是 WIF 用来解密它收到的 token 的证书,因为这种情况下的依赖方分布在多台机器上, token 在它们之间传递,这是 Not Acceptable 使用 SSL 证书作为加密 (RP) 证书。

是否有办法为 net.tcp 绑定(bind)指定单独的 SSL 证书和加密证书,还是它们必须始终相同?

只是重新迭代 token 的流程如下:

sts*(encrypted)* > client*(encrypted)* > dmz-broker*(需要解密)* > internal-服务器*(需要解密)*

我曾尝试将服务证书更改为加密证书,但随后将其用于 SSL 但失败了。我还尝试设置指定证书和 DNS 值的端点的身份,但都没有成功。

在此先感谢您的帮助。

最佳答案

我最终使用自定义 SecurityToken 解析器设法解决了这个问题。这涉及复制作为标准 .NET 类 (http://referencesource.microsoft.com/#System.IdentityModel/System/IdentityModel/Selectors/SecurityTokenResolver.cs) 的 SimpleTokenResolver,然后创建它并传入与用于解密 token 的证书相关的安全 token 。

我们可以在 .NET 4.5 源代码中看到,当初始化 WIF 时,会创建一个 token 解析器,并使用作为 token 传入的服务证书:

 SecurityTokenResolver serviceCertificateResolver = SecurityTokenResolver.CreateDefaultSecurityTokenResolver(new ReadOnlyCollection<SecurityToken>(
new SecurityToken[] { new X509SecurityToken(this.ServiceCertificate) }), false);

这意味着框架在默认情况下会创建一个解析器,该解析器使用您为 SSL 指定的完全相同的证书进行解密。

不幸的是,CreateDefaultSecurityTokenResolver 方法内部使用的 SimpleTokenResolver 是私有(private)的,不能继承或覆盖,但是通过从上面的链接中获取代码并在构造函数中传递正确的证书(可以从应用程序中读取)设置)您可以添加自己的解析器。

public CustomSecurityTokenResolver()
: this(new ReadOnlyCollection<SecurityToken>(new SecurityToken[] { new X509SecurityToken(CertificateHelper.GetFromAppSetting("EncryptionCertificate")) }), false)
{

}

然后可以在配置中指定此 token 解析器,如下所示:

<system.identityModel>
<identityConfiguration>
<securityTokenHandlers>
<securityTokenHandlerConfiguration>
<serviceTokenResolver type="MySecurity.CustomSecurityTokenResolver, MySecurity">
</serviceTokenResolver>
</securityTokenHandlerConfiguration>
</securityTokenHandlers>
</identityConfiguration>
</system.identityModel>

请注意,其他解析器仍添加到安全 token 解析器集合中,并且此解析器将在框架创建的默认值之后命中。

整个自定义解析器的代码如下所示:

public class CustomSecurityTokenResolver: SecurityTokenResolver
{
ReadOnlyCollection<SecurityToken> tokens;
bool canMatchLocalId;


public CustomSecurityTokenResolver()
: this(new ReadOnlyCollection<SecurityToken>(new SecurityToken[] { new X509SecurityToken(CertificateHelper.GetFromAppSetting("EncryptionCertificate")) }), false)
{

}

public CustomSecurityTokenResolver(ReadOnlyCollection<SecurityToken> tokens, bool canMatchLocalId)
{
this.tokens = tokens;
this.canMatchLocalId = canMatchLocalId;
}

protected override bool TryResolveSecurityKeyCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityKey key)
{


key = null;
for (int i = 0; i < this.tokens.Count; ++i)
{
SecurityKey securityKey = this.tokens[i].ResolveKeyIdentifierClause(keyIdentifierClause);
if (securityKey != null)
{
key = securityKey;
return true;
}
}

if (keyIdentifierClause is EncryptedKeyIdentifierClause)
{
EncryptedKeyIdentifierClause keyClause = (EncryptedKeyIdentifierClause)keyIdentifierClause;
SecurityKeyIdentifier keyIdentifier = keyClause.EncryptingKeyIdentifier;
if (keyIdentifier != null && keyIdentifier.Count > 0)
{
for (int i = 0; i < keyIdentifier.Count; i++)
{
SecurityKey unwrappingSecurityKey = null;
if (TryResolveSecurityKey(keyIdentifier[i], out unwrappingSecurityKey))
{
byte[] wrappedKey = keyClause.GetEncryptedKey();
string wrappingAlgorithm = keyClause.EncryptionMethod;
byte[] unwrappedKey = unwrappingSecurityKey.DecryptKey(wrappingAlgorithm, wrappedKey);
key = new InMemorySymmetricSecurityKey(unwrappedKey, false);
return true;
}
}
}
}

return key != null;
}

protected override bool TryResolveTokenCore(SecurityKeyIdentifier keyIdentifier, out SecurityToken token)
{
token = null;
for (int i = 0; i < keyIdentifier.Count; ++i)
{

SecurityToken securityToken = ResolveSecurityToken(keyIdentifier[i]);
if (securityToken != null)
{
token = securityToken;
break;
}
}

return (token != null);
}

protected override bool TryResolveTokenCore(SecurityKeyIdentifierClause keyIdentifierClause, out SecurityToken token)
{

token = null;

SecurityToken securityToken = ResolveSecurityToken(keyIdentifierClause);
if (securityToken != null)
token = securityToken;

return (token != null);
}

SecurityToken ResolveSecurityToken(SecurityKeyIdentifierClause keyIdentifierClause)
{

if (!this.canMatchLocalId && keyIdentifierClause is LocalIdKeyIdentifierClause)
return null;

for (int i = 0; i < this.tokens.Count; ++i)
{
if (this.tokens[i].MatchesKeyIdentifierClause(keyIdentifierClause))
return this.tokens[i];
}

return null;
}
}

关于.net - 联合安全 - 单独的 SSL 和 RP 证书(.NET 4.5 和 WIF),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24536091/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com