[英].NET Core ChannelFactory - Set a X509Certificate2 as Client Certificate
我需要將客戶端證書(例如,不是來自Windows證書存儲區)設置到我的wcf通道,但是我總是會收到異常:
System.InvalidOperationException:“對象是只讀的。”
這很奇怪,因為這些屬性都有一個setter,但是如果我分配了X509Certificate2,則會崩潰。
System.InvalidOperationException
HResult=0x80131509
Nachricht = Object is read-only.
Quelle = System.Private.ServiceModel
Stapelüberwachung:
at System.ServiceModel.Security.X509CertificateRecipientClientCredential.ThrowIfImmutable()
at System.ServiceModel.Security.X509CertificateRecipientClientCredential.set_DefaultCertificate(X509Certificate2 value)
var binding = new BasicHttpsBinding();
var endpoint = new EndpointAddress(new Uri("https://myservice.com"));
var channelFactory = new ChannelFactory<MyService>(binding, endpoint);
var serviceClient = channelFactory.CreateChannel();
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
var token = GetToken(); // Just an method that reads a pfx from disk
channelFactory.Credentials.
ServiceCertificate.DefaultCertificate = token.Certificate; // throws exception
channelFactory.Credentials.
ClientCertificate.Certificate = token.Certificate; // throws exception too
方法SetCertificate
引發相同的System.InvalidOperationException: "Object is read-only."
例外。
using (X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser))
{
store.Open(OpenFlags.ReadWrite);
var x509Certificate2Collection = store.Certificates.Find(X509FindType.FindByThumbprint, token.Certificate.Thumbprint, false);
if(x509Certificate2Collection.Count == 0)
store.Add(token.Certificate);
}
channelFactory.Credentials.ClientCertificate.SetCertificate(StoreLocation.CurrentUser, StoreName.My,X509FindType.FindByThumbprint, token.Certificate.Thumbprint);
X509CertificateRecipientClientCredential.cs的實現很有趣。
public X509Certificate2 DefaultCertificate
{
get
{
return _defaultCertificate;
}
set
{
ThrowIfImmutable();
_defaultCertificate = value;
}
}
internal void MakeReadOnly()
{
_isReadOnly = true;
this.Authentication.MakeReadOnly();
if (_sslCertificateAuthentication != null)
{
_sslCertificateAuthentication.MakeReadOnly();
}
}
private void ThrowIfImmutable()
{
if (_isReadOnly)
{
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.Format(SR.ObjectIsReadOnly)));
}
}
什么是調用internal void MakeReadOnly()
並讓我的生活困難。
在github上閱讀ClientCredentials.cs
時,我發現了方法MakeReadOnly()
。
channelFactory.CreateChannel()
的調用使ClientCertificate實例成為只讀實例,因此,在更改語句的順序之后,它將起作用!
var binding = new BasicHttpsBinding();
var endpoint = new EndpointAddress(new Uri("https://myservice.com"));
var channelFactory = new ChannelFactory<MyService>(binding, endpoint);
// Must set before CreateChannel()
channelFactory.Credentials.
ClientCertificate.Certificate = token.Certificate;
var serviceClient = channelFactory.CreateChannel();
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.