【问题标题】:Configuring WCF client binding to use X509 certificate in dotnet core 2.2在 dotnet core 2.2 中配置 WCF 客户端绑定以使用 X509 证书
【发布时间】:2019-06-07 07:05:49
【问题描述】:

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

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

<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 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 核心代理还不支持同步调用):

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

但是,我收到以下错误:

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

任何人都可以看出我的方法有什么问题或建议我可以用来调试的方法吗?我是 WCF 新手,现在我的头发都快掉光了。

【问题讨论】:

    标签: wcf .net-core wcf-binding wcf-security


    【解决方案1】:

    为了任何不幸遇到同样问题的其他人的利益,中心问题原来是 X509 证书没有被发送。 (我们点击的端点接受了证书或基本身份验证,因此是 401。)

    未发送证书的原因是 dotnet 核心网络堆栈比 .NET 更严格,并且要求证书将其 Enhanced Key Usage 设置为 ClientAuthentication (1.3.6.1.5.5.7.3.2)或者根本没有 EKU(参见 source code here)。我们的不是 - 它被设置为服务器身份验证。所以证书被悄悄地丢弃了,尽管已经成功加载了。

    This github issue 提供更多详细信息。

    【讨论】:

      【解决方案2】:

      您的代码 sn-ps 看起来不错。我们可能还有一件事要做。当服务器用证书对客户端进行认证时,我们应该相互建立信任关系,请参考以下链接。
      https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/transport-security-with-certificate-authentication
      此外,我们应该提供一个 Identity 标志来标识服务器,如下所示。

      <client>
          <endpoint address="http://vabqia593vm:4434/Service1.svc" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService1" contract="ServiceReference1.IService1" name="WSHttpBinding_IService1" behaviorConfiguration="mybeh">
              <identity>
                  <dns value="vabqia130vm"/>
              </identity>
          </endpoint>
      </client>
      

      我们可以通过 Micorosoft WCF Web 服务参考提供者生成客户端代理类。(添加连接的服务)。 如果有什么我可以帮忙的,请随时告诉我。
      亚伯拉罕

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-30
        • 2023-03-03
        • 2011-03-25
        • 1970-01-01
        • 1970-01-01
        • 2011-11-20
        • 2012-12-02
        • 2010-09-25
        相关资源
        最近更新 更多