【问题标题】:Secured selfhosted WCF service: load certificate from file安全的自托管 WCF 服务:从文件加载证书
【发布时间】:2019-07-27 03:09:47
【问题描述】:

我有一个发布 REST Web API 的自托管 WCF 服务。该服务以编程方式配置,当前通过 HTTP 正常工作。 现在我需要通过基于证书文件的身份验证使其通过 HTTPS 工作。 我知道建议的方法是在服务器计算机上的 Windows 证书存储中安装证书,但在我的情况下这种方法是不可能的。 我需要从文件中加载证书。

经过一些研究,我编写了代码,但是当我尝试访问 Web 服务时,会抛出 System.ServiceModel.CommunicationException,并显示以下消息: 发出 HTTP 请求时出错... 这可能是由于在 HTTPS 情况下未使用 HTTP.SYS 正确配置服务器证书。这也可能是由于客户端和服务器之间的安全绑定不匹配造成的。

这是我的服务器端代码:

_host = new WebServiceHost(_hostedService, Uri);

//Configuring the webHttpBinding settings
var httpBinding = new WebHttpBinding();
httpBinding.Security.Mode = WebHttpSecurityMode.Transport;
httpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
httpBinding.SendTimeout = new TimeSpan(0, 5, 0);
httpBinding.MaxBufferSize = 2147483647;
httpBinding.MaxBufferPoolSize = 2147483647;
httpBinding.MaxReceivedMessageSize = 2147483647;
httpBinding.ReaderQuotas.MaxDepth = 2147483647;
httpBinding.ReaderQuotas.MaxStringContentLength = 2147483647;
httpBinding.ReaderQuotas.MaxArrayLength = 2147483647;
httpBinding.ReaderQuotas.MaxBytesPerRead = 2147483647;
httpBinding.ReaderQuotas.MaxNameTableCharCount = 2147483647;

//Add the endpoint with the webHttpBinding settings to the WebServiceHost configuration
_host.AddServiceEndpoint(typeof(IService), httpBinding, Uri);

ServiceDebugBehavior stp = _host.Description.Behaviors.Find<ServiceDebugBehavior>();
stp.HttpHelpPageEnabled = false;
ServiceBehaviorAttribute sba = _host.Description.Behaviors.Find<ServiceBehaviorAttribute>();
sba.InstanceContextMode = InstanceContextMode.Single;
ServiceMetadataBehavior smb = new ServiceMetadataBehavior() { HttpsGetEnabled = true };
_host.Description.Behaviors.Add(smb);

X509Certificate2 trustedCertificate = new X509Certificate2("certificate.pfx", "password");
_host.Credentials.ServiceCertificate.Certificate = trustedCertificate;
_host.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;

这是我的客户端代码:

var httpBinding = new WebHttpBinding();
httpBinding.Security.Mode = WebHttpSecurityMode.Transport;
httpBinding.Security.Transport = new HttpTransportSecurity() { ClientCredentialType = HttpClientCredentialType.Certificate };
var httpUri = new Uri(String.Format("https://{0}:{1}", ipAddress, tcpPort));
var httpEndpoint = new EndpointAddress(httpUri);
var newFactory = new ChannelFactory<IService>(httpBinding, httpEndpoint);
newFactory.Endpoint.Behaviors.Add(new WebHttpBehavior());

X509Certificate2 trustedCertificate = new X509Certificate2("certificate.pfx", "password"); //SSL
newFactory.Credentials.ClientCertificate.Certificate = trustedCertificate;

var channel = newFactory.CreateChannel();

var response = channel.Ping("helo");

在最后一行抛出异常 (channel.Ping("helo"))。

我需要让它工作而不在服务器机器上安装证书。

非常感谢。

再见。

【问题讨论】:

    标签: c# rest wcf https


    【解决方案1】:

    据我所知,当我们通过 Https 托管自托管的 WCF 服务时,无论使用何种方式(加载证书文件或通过 Windows 证书存储配置证书),都不可能使服务正常工作。我们需要做的唯一方法是使用以下命令手动绑定证书。

    netsh http add sslcert ipport=0.0.0.0:8000 certhash=0000000000003ed9cd0c315bbb6dc1c08da5e6 appid={00112233-4455-6677-8899-AABBCCDDEEFF}
    

    这是官方文档,希望对你有用。
    https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-configure-a-port-with-an-ssl-certificate

    https://docs.microsoft.com/en-us/windows/desktop/http/add-sslcert
    以下是我曾经写过的一些例子。
    WCF Service over HTTPS without IIS, with SSL Certificate from CERT and KEY strings or files

    Chrome (v71) ERR_CONNECTION_RESET on Self Signed localhost on Windows 8 Embedded
    如果有什么我可以帮忙的,请随时告诉我。

    【讨论】:

    • 这就是我所害怕的……非常感谢。
    • 还有一个问题:如何知道我的 certificate.pfx 文件的 certash?
    • Certhash 参数是证书的指纹,你可以通过程序获取它,或者证书属性(安装,并在 Windows 证书存储中检查它)。 X509Certificate2 证书 = 新 X509Certificate2("1.pfx", "123456"); Console.WriteLine(cert.Thumbprint);
    • 对了,你提供的方法是用来保护http通信的,比如我们要设置自定义用户名/密码认证,就需要使用上面的方法提供证书来实现功能。此外,如果我们在 IIS 中通过 https 托管服务,则 IIS 绑定可以帮助我们绑定证书。 docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/…
    • netsh http add sslcert ipport=0.0.0.0:8000 certash=... appid={...} 似乎只有当证书进入证书存储时才有效...否则我有错误 1312...似乎我的需求无法实现... :(
    猜你喜欢
    • 1970-01-01
    • 2020-04-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-21
    • 1970-01-01
    相关资源
    最近更新 更多