来自同一主机上的 Invoke-WebRequest 的 WCF 客户端证书身份验证
Posted
技术标签:
【中文标题】来自同一主机上的 Invoke-WebRequest 的 WCF 客户端证书身份验证【英文标题】:WCF client certificate authentication from Invoke-WebRequest on the same host 【发布时间】:2020-12-27 08:58:09 【问题描述】:我有一个运行 Windows Server 的 WebServer WCF .NET4.6.2 应用程序。我只想从同一服务器内调用该 WebServer 的 API,因为防火墙阻止了我的 WebServer 的端口。我还想只允许具有管理员权限的用户调用 WebServer API。就此而言,我认为证书身份验证可以解决问题。我的 WCF 服务设置是
var baseAddress = new Uri("https://localhost:2000/");
var binding = new WebHttpBinding(WebHttpSecurityMode.Transport);
binding.HostNameComparisonMode = HostNameComparisonMode.Exact;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
var endpoint = new ServiceEndpoint(ContractDescription.GetContract(typeof(MyWebApi)),
binding,
new EndpointAddress(baseAddress));
webServiceHost = new WebServiceHost(kernel.Get<MyWebApi>(), baseAddress);
webServiceHost.AddServiceEndpoint(endpoint);
webServiceHost.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.PeerTrust;
webServiceHost.Credentials.ClientCertificate.Authentication.TrustedStoreLocation = StoreLocation.CurrentUser;
webServiceHost.Description.Behaviors.Find<ServiceDebugBehavior>().HttpHelpPageEnabled = false;
webServiceHost.Open();
我已经创建了一个根证书,并将其放入 LocalComputer\Trusted Root CA。
我已经创建了一个中间证书并放入 LocalComputer\Intermediate CA。
我创建了两个 [证书 + 私钥] - 名称分别为“localhost”和“client”。
我已将“localhost”放入 LocalComputer\Personal
我已将“客户端”放入 LocalComputer\Personal 和 MyUser\Trusted People。
我的 WebServer 以 MyUser 身份运行。我注册了我的网络服务器以使用 SSL。
netsh http add sslcert ipport=0.0.0.0:2000 certhash="hash of localhost" appid="00112233-4455-6677-8899-AABBCCDDEEFF" clientcertnegotiation=enable
我正在尝试使用 MyUser 在运行我的 WebServer 的同一主机上运行以下命令
Invoke-WebRequest -method post -uri https://localhost:2000/ping -CertificateThumbprint "hash of client"
但我得到的是
Invoke-WebRequest : The remote server returned an error: (403) Forbidden.
Fiddler 显示响应
System.Security.Authentication.AuthenticationException The remote certificate is invalid according to the validation procedure
将 binding.Security.Transport.ClientCredentialType 更改为 HttpClientCredentialType.None 有效,并证明我的客户端可以验证我的网络服务器的证书,但我无法弄清楚为什么网络服务器无法验证客户端的证书。 任何帮助将不胜感激。
【问题讨论】:
关于证书认证的传输安全可以参考这个链接:docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/… 您需要确保服务器信任客户端的证书。 如何让机器信任证书,可以参考这个链接:thycotic.force.com/support/s/article/… @DingPeng 有两个验证 1 - 客户端验证它是否可以信任服务器,在我的情况下,“localhost”证书是由我的中间 CA 颁发的,这是我的根 CA 的问题。我已将中间 CA 和根 CA 添加到信任库中的相应文件夹,不确定服务器证书如何受信任 2 - 服务器验证它是否可以信任客户端。我的“客户”证书是由与上述相同的中间 CA 颁发的。而且我已将“客户”证书添加到受信任的人。显然我做错了什么,但究竟是什么? 您可以使用此代码来避免验证证书 "ServicePointManager.ServerCertificateValidationCallback += (o, c, ch, er) => true;"。 【参考方案1】:我找到了解决方案,我错过了两件事:
-
我必须为我的根 CA 部署证书吊销列表
我必须创建一个包含预期用途“客户端身份验证”的客户端证书
【讨论】:
以上是关于来自同一主机上的 Invoke-WebRequest 的 WCF 客户端证书身份验证的主要内容,如果未能解决你的问题,请参考以下文章