在 dotnet core 2.2 中配置 WCF 客户端绑定以使用 X509 证书 [英] Configuring WCF client binding to use X509 certificate in dotnet core 2.2

查看:28
本文介绍了在 dotnet core 2.2 中配置 WCF 客户端绑定以使用 X509 证书的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将旧的 WCF 客户端转换为 dotnet 核心.我成功地从 wsdl 生成了我的代理,并一直在尝试配置它们,以便我可以成功调用端点.根据一些谷歌搜索,在 dotnet 核心下,我似乎需要从代码配置我的 WCF 客户端.

I'm trying to convert an old WCF client to dotnet core. I successfully generated my proxies from the wsdl and have been trying to configure them so I can successfully call the endpoint. It appears, based on some googling, that under dotnet core I need to configure my WCF client from code.

这是旧应用程序的 web.config 中的 WCF 配置部分:

Here's the WCF configuration section from the web.config of the old application:

<system.serviceModel>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
  <behaviors>
    <endpointBehaviors>
      <behavior name="clientEndpointCredential">
        <clientCredentials>
          <clientCertificate storeName="My" storeLocation="LocalMachine" x509FindType="FindBySubjectName" findValue="CERTNAME" />
        </clientCredentials>
      </behavior>
    </endpointBehaviors>
  </behaviors>
  <bindings>
    <basicHttpBinding>
      <binding name="OUR_Customer_OUTBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
        <readerQuotas maxDepth="32" maxStringContentLength="5242880" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
        <security mode="Transport">
          <transport clientCredentialType="Certificate" proxyCredentialType="None" realm="" />
        </security>
      </binding>
    </basicHttpBinding>
  </bindings>
  <client>
    <endpoint address="https://the-full-url" behaviorConfiguration="clientEndpointCredential" binding="basicHttpBinding" bindingConfiguration="OUR_Customer_OUTBinding" contract="CustomerInterface.OUR_Customer_OUT" name="HTTPS_Port" />
  </client>
  <diagnostics>
    <messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="false" maxMessagesToLog="3000" />
  </diagnostics>
</system.serviceModel>

这是我在 dotnet 核心中配置它的想法:

Here's what I've come up with to configure it in dotnet core:

private OUR_Customer_OUTClient GetCustomerClient()
{
    TimeSpan Minutes(int minutes) => new TimeSpan(0, minutes, 0);

    var binding = new BasicHttpBinding();
    binding.Name = "OUR_Customer_OUTBinding";
    binding.AllowCookies = false;
    binding.SendTimeout = Minutes(1);
    binding.ReceiveTimeout = Minutes(10);
    binding.OpenTimeout = Minutes(1);
    binding.CloseTimeout = Minutes(1);
    binding.MaxBufferPoolSize = 2147483647;
    binding.MaxReceivedMessageSize = 2147483647;
    binding.TextEncoding = Encoding.UTF8;
    binding.TransferMode = TransferMode.Buffered;
    binding.BypassProxyOnLocal = false;
    binding.UseDefaultWebProxy = true;
    binding.Security.Mode = BasicHttpSecurityMode.Transport;
    binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
    binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;

    var endpointAddress = new EndpointAddress("https://the-full-url");

    var client = new OUR_Customer_OUTClient(binding, endpointAddress);
    client.ClientCredentials.ClientCertificate.SetCertificate(
        StoreLocation.LocalMachine,
        StoreName.My,
        X509FindType.FindBySubjectName,
        "CERTNAME");
    return client;
}

这是我用来调用端点的代码(dotnet 核心代理尚不支持同步调用):

And here's the code I'm using to call the endpoint (dotnet core proxies don't yet support synchronous calls):

SearchResponse searchResponse = Task.Run(() => GetCustomerClient().SearchAsync(message)).Result;

但是,我收到以下错误:

However, I'm getting the following error:

HTTP 请求未经授权,客户端身份验证方案为匿名".从服务器收到的身份验证标头是Basic realm="XISOAPApps"'

谁能看出我的方法有什么问题或建议我可以用来调试的方法?我是 WCF 的新手,此时我正在扯头发.

Can anyone see anything wrong with my approach or suggest ways I could use to debug this? I'm a WCF newbie and am tearing my hair out at this point.

推荐答案

为了让其他不幸遇到同样问题的人受益,中心问题是 X509 证书不是正在发送.(我们点击的端点接受证书或基本身份验证,因此是 401.)

For the benefit of any others who may be unlucky enough to hit the same problem, the central issue turned out to be that the X509 certificate was not being sent. (The endpoint we were hitting accepted either a certificate or basic auth, thus the 401.)

未发送证书的原因是 dotnet 核心网络堆栈比 .NET 堆栈更严格,并且要求证书将其 Enhanced Key Usage 设置为 ClientAuthentication (1.3.6.1.5.5.7.3.2) 或根本没有 EKU(请参阅 此处的源代码).我们的不是 - 它被设置为服务器身份验证.因此,尽管加载成功,证书还是被悄悄丢弃了.

The reason the certificate wasn't being sent was because the dotnet core networking stack is stricter than the .NET one, and requires the certificate to either have its Enhanced Key Usage set to ClientAuthentication (1.3.6.1.5.5.7.3.2) or have no EKU at all (see the source code here). Ours wasn't - it was set to Server Authentication. So the certificate was quietly discarded, despite having been loaded up successfully.

这个 github 问题提供了更多详细信息.

这篇关于在 dotnet core 2.2 中配置 WCF 客户端绑定以使用 X509 证书的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆