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

查看:64
本文介绍了在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;

但是,出现以下错误:

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严格,并且要求证书将其增强密钥用法设置为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问题提供了更多详细信息.

This github issue provides further details.

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

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