首页 > 解决方案 > 无法为 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();

谁能看到我做错了什么?提前致谢。

标签: wcfsoap

解决方案


我们最好使用 配置证书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
如果有什么我可以帮忙的,请随时告诉我。


推荐阅读