【问题标题】:WCF SOAP security negotiation after changing certificate更改证书后的 WCF SOAP 安全协商
【发布时间】:2018-12-12 19:41:31
【问题描述】:

将自签名证书“​​localhost”(DNS=localhost)更改为“Cloudflare Origin Certificate”(dns=mydomain.com)后,出现以下错误:

SOAP security negotiation with 'http://localhost:8000/MyService.svc' for target 'http://localhost:8000/MyService.svc' failed. See inner exception for more details.

内部异常:

Either the client credential was invalid or there was an error collecting the client credentials by the SSPI.

我注意到在我启动客户端后,我得到了输入凭据的窗口。不知道为什么。

我到底做了什么:

  1. 在 IIS 中生成的证书请求
  2. 已完成 CloudFlare 证书
  3. 收到的密钥使用 CloudFlare Root CA 粘贴到文本文件中
  4. 在 IIS(个人、本地机器)中完成证书
  5. 在 MMC 中添加到 Trusted Publishers CloudFlare 根 CA (LocalMachine)
  6. 对于 WCF 网站,将 SSL 证书更改为 CloudFlare
  7. 客户端值从“localhost”更改为“mydomain.com”
  8. 将服务器值从“localhost”更改为“mydomain.com”
  9. 更改了 findValue

WCF web.config

<system.serviceModel>
    <client />
    <behaviors>
      <serviceBehaviors>
        <behavior name="authBehavior">
          <serviceAuthorization principalPermissionMode="UseWindowsGroups">
            <authorizationPolicies>
              <add policyType="WCF.Common.AuthorizationPolicy, WCF" />
            </authorizationPolicies>
          </serviceAuthorization>
          <serviceCredentials>
            <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="WCF.Common.IdentityValidator, WCF" />
            <serviceCertificate findValue="CloudFlare Origin Certificate" storeLocation="LocalMachine" x509FindType="FindBySubjectName" storeName="My" />
          </serviceCredentials>
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
        <behavior name="svcBehavior">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
        <behavior name="">
          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <bindings>
      <basicHttpsBinding>
        <binding name="basicHttpsEndpointBinding" maxReceivedMessageSize="1073741824" maxBufferSize="1073741824" maxBufferPoolSize="1073741824">
          <readerQuotas maxDepth="32" maxArrayLength="1073741824" maxStringContentLength="1073741824" />
          <security mode="Transport">
            <transport clientCredentialType="Windows" />
          </security>
        </binding>
      </basicHttpsBinding>
      <wsHttpBinding>
        <binding name="wsHttpEndpointBinding"></binding>
      </wsHttpBinding>
    </bindings>
    <services>
      <service name="WCF.MyService" behaviorConfiguration="svcBehavior">
        <endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding" contract="WCF.IMyService">
          <identity>
            <dns value="mydomain.com" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
      </service>
    </services>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  </system.serviceModel>

客户端app.config

<system.serviceModel>
        <bindings>
            <wsHttpBinding>
                <binding name="MessageAndUserName">
                    <security mode="Message">
                        <message clientCredentialType="UserName" />
                    </security>
                </binding>
                <binding name="WSHttpBinding_IMyService" />
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://localhost:8777/MyService.svc"
                binding="wsHttpBinding" contract="WCF.IMyService"
                name="WSHttpBinding_IMyService">
                <identity>
                    <dns value="mydomain.com" />
                </identity>
            </endpoint>
        </client>

      <behaviors>  
        <serviceBehaviors>  
          <behavior name="DefaultServiceBehavior">  
            <serviceMetadata httpGetEnabled="true" />  
            <serviceDebug includeExceptionDetailInFaults="true" />  
          </behavior>  
        </serviceBehaviors>  
      </behaviors>  
    </system.serviceModel>

我在 WCF 中托管其他服务,还在客户端中托管一些服务,但它们都不需要。

我在 WCF 和客户端之间使用 wsHttpBindings。我该怎么做才能摆脱这个错误?

使用 wsHttpBinding 等的目的是什么...:仅允许此客户端与 MyService 通信.. 不允许其他任何人。客户端应用程序将在域中的多台计算机上运行。您是否建议使用不同的方法?

感谢您的任何想法!

编辑:出现错误的计算机未在域中运行。都不适用于域中的计算机:/

EDIT2:安全模式传输 WCF web.config 绑定:

<wsHttpBinding>
        <binding name="wsHttpEndpointBinding">
          <security mode="Transport">
            <message clientCredentialType="None" />
          </security>
        </binding>
      </wsHttpBinding>

客户端配置绑定:

<bindings>
            <wsHttpBinding>
              <binding name="WSHttpBinding_IMyService">
                <security mode="Transport">
                  <message clientCredentialType="None" />
                </security>
              </binding>
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="https://localhost:8001/MyService.svc"
                binding="wsHttpBinding" contract="WCF.IMyService"
                name="WSHttpBinding_IMyService">
                <identity>
                    <dns value="mydomain.com" />
                </identity>
            </endpoint>
        </client>

IIS:

【问题讨论】:

  • 如果您双击 MMC 中的证书,它会在证书信息标题下显示任何错误消息吗?您是否可以在浏览器中从客户端浏览服务?如果那是通配符证书 (*.mydomain),那么您必须从具有该域的 url 访问您的服务,您可以通过修改 hosts 文件在本地模拟它。
  • @Popo 证书状态为“此证书正常”。我在另一个应用程序中通过 C# 检查它是否有效。证书已针对本地计算机进行验证。我能够从客户端浏览器浏览服务。它不是通配符证书,它完全没有 www,只是“mydomain.com”。
  • 看起来您可能需要更新主机和客户端上的 wsHttpBinding 以使用 mode="TransportWithMessageCredential",因为您在 IIS 中分配证书时,它会期望它是 HTTPS。您可能还需要在客户端中为消息分配证书。根据您的服务行为显示,您使用 customUserNamePasswordValidator 和证书作为凭证。
  • @Popo 好的,我会尝试使用该模式。无论如何,我不使用 customUserNamePasswordValidator.. 这是不同的行为!
  • 啊,你的权利,在这种情况下,你可能只需要使用类似&lt;security mode="Transport"&gt; &lt;message clientCredentialType="None" /&gt; &lt;/security&gt;

标签: c# wcf ssl certificate wshttpbinding


【解决方案1】:

这里有一些资源可供查看,以帮助确定 NetTcpBinding 是否适合您,因为您在内部使用 Web 服务,所以听起来很适合。

NetTcpBinding 当 WCF 服务及其客户端位于 Intranet 基础结构中时,netTcpBinding 是最好的。由于它只支持 TCP 协议,不支持 HTTP,因此无法通过 Internet 访问服务。

这是一种安全绑定,用于在 Intranet 计算机中发送二进制编码的 SOAP 消息。它支持可靠性、事务性和安全性。如果您在 IIS 中使用 netTcpBinding 并托管 WCF 服务,您需要在系统上进行一些设置,IIS this article 将帮助您进行所需的设置。

解决相关问题的一些提示:

  • 在 MMC 中双击证书是否会显示任何错误消息 在证书信息标题下?
  • 您能否在浏览器中从客户端浏览服务?
  • 证书是否在 IIS 中分配
  • 您的绑定是否正确
  • 客户端是否使用与服务主机相同的绑定?
  • 您的端点是否引用了正确的绑定和服务行为

有关 NetTcpBinding 的其他有用信息:

https://stackoverflow.com/a/3375161/2016162

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-20
    • 1970-01-01
    • 1970-01-01
    • 2011-10-29
    • 2010-10-21
    • 2012-03-29
    相关资源
    最近更新 更多