简体   繁体   English

.NET Core ChannelFactory-将X509Certificate2设置为客户端证书

[英].NET Core ChannelFactory - Set a X509Certificate2 as Client Certificate

I need to set a client certificate (as instance, not from windows certificate store) to my wcf channel, but I always get the Exception: 我需要将客户端证书(例如,不是来自Windows证书存储区)设置到我的wcf通道,但是我总是会收到异常:

System.InvalidOperationException: "Object is read-only." System.InvalidOperationException:“对象是只读的。”

This is strange, because the these properties have a setter but if I assigned a X509Certificate2 is crashes. 这很奇怪,因为这些属性都有一个setter,但是如果我分配了X509Certificate2,则会崩溃。

Stacktrace 堆栈跟踪

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)

Code

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

Update 1 更新1

The method SetCertificate throws the same System.InvalidOperationException: "Object is read-only." 方法SetCertificate引发相同的System.InvalidOperationException: "Object is read-only." exception. 例外。

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);

Update 2 更新2

The implementation of X509CertificateRecipientClientCredential.cs is interesting. 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)));
    }
}

Something is calling internal void MakeReadOnly() and make so my life harder. 什么是调用internal void MakeReadOnly()并让我的生活困难。

While reading the ClientCredentials.cs on github, I found the method MakeReadOnly() . 在github上阅读ClientCredentials.cs时,我发现了方法MakeReadOnly()

The call of channelFactory.CreateChannel() makes the ClientCertificate instance read-only, so after change the order of the statements it works! channelFactory.CreateChannel()的调用使ClientCertificate实例成为只读实例,因此,在更改语句的顺序之后,它将起作用!

Working ClientCertificate Authentication with WCF: 使用WCF进行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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM