wcf - 无法为 WCF SOAP 请求设置 ClientCredentials
问题描述
我正在使用 Visual Studio 2019 尝试创建一个 .Net 4.5.2 客户端,该客户端使用 SOAP over HTTPS 使用远程 Web 服务。要进行身份验证,该服务需要将客户端证书附加到所有请求。客户端实例化 System.ServiceModel.ClientBase 类。似乎无论我如何生成客户端类,我都无法设置我认为的 ClientCredentials,因为 ClientCredentials 是只读的。
这是我用来生成客户端类的命令:
svcutil.exe /t:metadata https://example.com?WSDL
svcutil.exe /language:cs /config:app.config /messagecontract *.xsd *.wsdl
这是我在 web.config 文件中使用的绑定:
<bindings>
<basicHttpBinding>
<binding name="TCSOnlineServicePortBinding">
<!-- I am not sure of the mode below, message also does not work -->
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Certificate" proxyCredentialType="None" />
<message clientCredentialType="Certificate" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://example.com"
binding="basicHttpBinding" bindingConfiguration="TCSOnlineServicePortBinding"
contract="TCSOnlineService" name="TCSOnlineServicePort" />
</client>
这是不起作用的代码:
var TCSSvcClient = new TCSOnlineServiceClient(tcs_endpoint, TCSEndpointAddr);
var aCert = new X509Certificate2();
... [omitting code to find cert in MY store]
// The line below leave the ClientCertificate.Certificate set to NULL????? Why??
TCSSvcClient.ClientCredentials.ClientCertificate.Certificate = aCert;
// This also does not work, certificate is left NULL
TCSSvcClient.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2();
谁能看到我做错了什么?提前致谢。
解决方案
我们最好使用 配置证书LocalMachine store
,然后将运行客户端应用程序的当前用户添加到证书私钥的管理组中。
ServiceReference1.TestServiceClient client = new ServiceReference1.TestServiceClient();
client.ClientCredentials.ClientCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.My, X509FindType.FindByThumbprint, "9ee8be61d875bd6e1108c98b590386d0a489a9ca");
var result = client.GetResult("a");
result = client.Test();
Console.WriteLine(result);
对于客户端生成的证书Powershell
,我们最好针对DotNet4.6.2或以上的应用。
以这种方式提供客户端证书存在问题。我们需要确保当前用户可以读取证书的私钥。
TCSSvcClient.ClientCredentials.ClientCertificate.Certificate = new X509Certificate2();
此外,使用证书对客户端进行身份验证需要客户端和服务器端之间的信任关系。调用服务之前建立信任关系了吗?
https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/transport-security-with-certificate-authentication
如果有什么我可以帮忙的,请随时告诉我。
推荐阅读
- python - 如何在 python 中绘制 3D 轮廓线?
- django - Django 选择未使用 {% if %} 正确呈现
- kotlin - 如何在 Kotlin 中设置数组参数的默认值?
- django - TypeError:“NoneType”对象在测试 django 约束时不可调用
- sockets - Python在同一个套接字多个线程上发送/接收
- javascript - ChartJS - 覆盖属性(AngularJS)
- flutter - 如何在 indexedStack Flutter 上打开键盘时隐藏 positionWigdet
- javascript - 错误处理:如何在我的前端接收来自我的后端的错误消息?
- python - 如何在 Python 中通过两种不同的变量类型运行 for 循环?
- python - 如何在 celery 中模拟具有状态的长 i/o 数据库操作?