如何将具有联合绑定的 wcf 客户端从 .net 框架迁移到 .net 核心?
How can I migrate a wcf client with federation binding from .net framework to .net core?
我正在将 WCF 客户端从 .Net Framework 迁移到 .Net Core。我正在创建从 ClientBase 派生的客户端并使用联合绑定。
这是在 .Net Framework 中工作的绑定创建代码:
private Binding CreateBinding()
{
var issuerBinding = new WSHttpBinding(SecurityMode.Transport);
issuerBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
var binding = new WS2007FederationHttpBinding(WSFederationHttpSecurityMode.TransportWithMessageCredential);
binding.Security.Message.IssuedKeyType = SecurityKeyType.SymmetricKey;
binding.Security.Message.NegotiateServiceCredential = false;
binding.Security.Message.EstablishSecurityContext = false;
binding.Security.Message.IssuerAddress = new EndpointAddress(this.stsAddress);
binding.Security.Message.IssuerBinding = issuerBinding;
return binding
}
.Net core中对应的代码如下:
private Binding CreateBinding()
{
var issuerBinding = new WSHttpBinding(SecurityMode.Transport);
issuerBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
var endpointAddress = new EndpointAddress(this.stsAddress);
var tokenParameters = WSTrustTokenParameters.CreateWS2007FederationTokenParameters(issuerBinding, endpointAddress);
tokenParameters.KeyType = SecurityKeyType.SymmetricKey;
var binding = new WSFederationHttpBinding(tokenParameters);
binding.Security.Message.NegotiateServiceCredential = false;
binding.Security.Message.EstablishSecurityContext = false;
return binding;
}
不幸的是,.net 核心版本不起作用 - 调用该服务会抛出“客户端身份验证方案 'Anonymous' 禁止 HTTP 请求。”
原来是请求sts失败了。
我创建了一个代理来拦截 http 请求,并发现对 sts 服务的调用存在以下差异:
- .net 框架请求包含以下 .net 核心版本中缺少的属性:
<trust:KeyWrapAlgorithm>
http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p
</trust:KeyWrapAlgorithm>
<trust:EncryptWith>
http://www.w3.org/2001/04/xmlenc#aes256-cbc
</trust:EncryptWith>
<trust:SignWith>
http://www.w3.org/2000/09/xmldsig#hmac-sha1
</trust:SignWith>
<trust:CanonicalizationAlgorithm>
http://www.w3.org/2001/10/xml-exc-c14n#
</trust:CanonicalizationAlgorithm>
<trust:EncryptionAlgorithm>
http://www.w3.org/2001/04/xmlenc#aes256-cbc
</trust:EncryptionAlgorithm>
trust:BinarySecret
trust:Entropy
元素不同。 .net 框架版本包含 .net 核心版本中缺少的类型属性 Type="http://docs.oasis-open.org/ws-sx/ws-trust/200512/Nonce"
。根据 WS-Trust 文档,默认值是 SymmetricKey。
- .net 核心请求包含 .net 框架版本中缺少的
trust:TokenType
元素
<trust:TokenType>
http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0
</trust:TokenType>
如何设置适当的绑定以使其在 .net 核心中工作?
Core不支持Wshttpbinding,wcf只支持BasicHttpBinding、CustomBinding、NetHttpBinding、NetTcpBinding:
建议您继续使用.net framework或者修改服务端绑定
关于WCF核心特性的更多信息,可以参考这篇link。
事实证明,.net 核心 WCF 客户端没有随请求发送证书。
.net core 检查证书是否有私钥,如果没有则跳过它。
https://github.com/dotnet/corefx/blob/fe7adb2bf92bba926268c2e9f562b11c84932a07/src/Common/src/System/Net/Security/CertificateHelper.cs#L39-L42
if (!cert.HasPrivateKey)
{
continue;
}
我从 Azure Key Vault 获取证书,默认情况下 returns 它没有私钥。将其更改为包含私钥解决了该问题。
我的 .net 框架应用程序使用相同的方法获取证书(因此它也没有私钥),但它能够从我安装证书的本地机器商店获取私钥.
我正在将 WCF 客户端从 .Net Framework 迁移到 .Net Core。我正在创建从 ClientBase 派生的客户端并使用联合绑定。
这是在 .Net Framework 中工作的绑定创建代码:
private Binding CreateBinding()
{
var issuerBinding = new WSHttpBinding(SecurityMode.Transport);
issuerBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
var binding = new WS2007FederationHttpBinding(WSFederationHttpSecurityMode.TransportWithMessageCredential);
binding.Security.Message.IssuedKeyType = SecurityKeyType.SymmetricKey;
binding.Security.Message.NegotiateServiceCredential = false;
binding.Security.Message.EstablishSecurityContext = false;
binding.Security.Message.IssuerAddress = new EndpointAddress(this.stsAddress);
binding.Security.Message.IssuerBinding = issuerBinding;
return binding
}
.Net core中对应的代码如下:
private Binding CreateBinding()
{
var issuerBinding = new WSHttpBinding(SecurityMode.Transport);
issuerBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
var endpointAddress = new EndpointAddress(this.stsAddress);
var tokenParameters = WSTrustTokenParameters.CreateWS2007FederationTokenParameters(issuerBinding, endpointAddress);
tokenParameters.KeyType = SecurityKeyType.SymmetricKey;
var binding = new WSFederationHttpBinding(tokenParameters);
binding.Security.Message.NegotiateServiceCredential = false;
binding.Security.Message.EstablishSecurityContext = false;
return binding;
}
不幸的是,.net 核心版本不起作用 - 调用该服务会抛出“客户端身份验证方案 'Anonymous' 禁止 HTTP 请求。”
原来是请求sts失败了。 我创建了一个代理来拦截 http 请求,并发现对 sts 服务的调用存在以下差异:
- .net 框架请求包含以下 .net 核心版本中缺少的属性:
<trust:KeyWrapAlgorithm>
http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p
</trust:KeyWrapAlgorithm>
<trust:EncryptWith>
http://www.w3.org/2001/04/xmlenc#aes256-cbc
</trust:EncryptWith>
<trust:SignWith>
http://www.w3.org/2000/09/xmldsig#hmac-sha1
</trust:SignWith>
<trust:CanonicalizationAlgorithm>
http://www.w3.org/2001/10/xml-exc-c14n#
</trust:CanonicalizationAlgorithm>
<trust:EncryptionAlgorithm>
http://www.w3.org/2001/04/xmlenc#aes256-cbc
</trust:EncryptionAlgorithm>
trust:BinarySecret
trust:Entropy
元素不同。 .net 框架版本包含 .net 核心版本中缺少的类型属性Type="http://docs.oasis-open.org/ws-sx/ws-trust/200512/Nonce"
。根据 WS-Trust 文档,默认值是 SymmetricKey。- .net 核心请求包含 .net 框架版本中缺少的
trust:TokenType
元素
<trust:TokenType>
http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0
</trust:TokenType>
如何设置适当的绑定以使其在 .net 核心中工作?
Core不支持Wshttpbinding,wcf只支持BasicHttpBinding、CustomBinding、NetHttpBinding、NetTcpBinding:
建议您继续使用.net framework或者修改服务端绑定
关于WCF核心特性的更多信息,可以参考这篇link。
事实证明,.net 核心 WCF 客户端没有随请求发送证书。 .net core 检查证书是否有私钥,如果没有则跳过它。 https://github.com/dotnet/corefx/blob/fe7adb2bf92bba926268c2e9f562b11c84932a07/src/Common/src/System/Net/Security/CertificateHelper.cs#L39-L42
if (!cert.HasPrivateKey)
{
continue;
}
我从 Azure Key Vault 获取证书,默认情况下 returns 它没有私钥。将其更改为包含私钥解决了该问题。
我的 .net 框架应用程序使用相同的方法获取证书(因此它也没有私钥),但它能够从我安装证书的本地机器商店获取私钥.