从另一个 WCF 服务调用一个 WCF 服务

发布于 2024-08-26 12:01:41 字数 3912 浏览 11 评论 0原文

我有一个 WCF 服务托管在我的 Server1 上的 Windows 服务上。这台机器上还有 IIS。我从网络应用程序调用该服务,它工作正常。但在这个服务中,我必须调用位于 Server2 上的另一个 WCF 服务(也托管在 Windows 服务上)。安全凭证设置为“消息”和“用户名”。我遇到类似“SOAP 协议协商失败”的错误。这是我的服务器证书公钥的问题,似乎无法识别。但是,如果我在控制台应用程序中从 Server1 调用 Server2 上的服务,则它工作正常。

我按照本教程设置了我的证书: http://www.codeproject.com/ KB/WCF/wcf_certificates.aspx

这是我在 Server1 上的服务尝试调用第二个服务的配置文件:

    <endpoint address=""
              binding="wsHttpBinding"
              contract="Microsoft.ServiceModel.Samples.ITraitement" />


    <endpoint address="mex"
              binding="mexHttpBinding"
              contract="IMetadataExchange" />
  </service>

</services>

<client>
  <endpoint address="http://Server2:8000/servicemodelsamples/service"
    behaviorConfiguration="myClientBehavior" binding="wsHttpBinding"
    bindingConfiguration="MybindingCon" contract="Microsoft.ServiceModel.Samples.ICalculator"
    name="">
    <identity>
      <dns value="ODWCertificatServeur" />
    </identity>
  </endpoint>
</client>

<bindings>
  <wsHttpBinding>
    <binding name="MybindingCon">
      <security mode="Message">
        <message clientCredentialType="UserName" />
      </security>
    </binding>
  </wsHttpBinding>
</bindings>

<behaviors>
  <serviceBehaviors>
    <behavior name="ServiceTraitementBehavior">
      <serviceMetadata httpGetEnabled="True"/>
      <serviceDebug includeExceptionDetailInFaults="True" />
    </behavior>
  </serviceBehaviors>
  <endpointBehaviors>
    <behavior name="myClientBehavior">
      <clientCredentials>
        <clientCertificate findValue="MachineServiceTraitement" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My" />
        <serviceCertificate>
          <authentication certificateValidationMode="ChainTrust" revocationMode="NoCheck"/>
        </serviceCertificate>
      </clientCredentials>
    </behavior>
  </endpointBehaviors>
</behaviors>

以下是调用 Server1 上的服务的 Web 应用程序的配置文件:

<system.serviceModel>
<bindings>
  <wsHttpBinding>
    <binding name="WSHttpBinding_ITraitement" closeTimeout="00:01:00"
        openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
        bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
        maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
        messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
        allowCookies="false">
      <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
          maxBytesPerRead="4096" maxNameTableCharCount="16384" />
      <reliableSession ordered="true" inactivityTimeout="00:10:00"
          enabled="false" />
      <security mode="Message">
        <transport clientCredentialType="Windows" proxyCredentialType="None"
            realm="" />
        <message clientCredentialType="Windows" negotiateServiceCredential="true"
            algorithmSuite="Default" establishSecurityContext="true" />
      </security>
    </binding>
  </wsHttpBinding>
</bindings>
<client>
  <endpoint address="http://localhost:8020/ServiceTraitementPC"
      binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ITraitement"
      contract="ITraitement" name="WSHttpBinding_ITraitement">
  </endpoint>
</client>

知道如果我在控制台应用程序中调用它而不是从我的服务中调用它为什么它会起作用吗?也许它与certificateValidationMode =“ChainTrust”有关?

I have a WCF service hosted on a windows service on my Server1. It also has IIS on this machine. I call the service from a web app and it works fine. But within this service, I have to call another WCF sevice (also hosted on a windows service) located on Server2. The security credentials are set to "Message" and "Username". I have an error like "SOAP protcol negociation failed". It's a problem with my server certificate public key that doesn't seem to be recognise. However, if I call the service on the Server2 from Server1 in a console app, it works fine.

I followed this tutorial to set up my certificates : http://www.codeproject.com/KB/WCF/wcf_certificates.aspx

Here's the config file from my service on Server1 that tries to call the second one :

    <endpoint address=""
              binding="wsHttpBinding"
              contract="Microsoft.ServiceModel.Samples.ITraitement" />


    <endpoint address="mex"
              binding="mexHttpBinding"
              contract="IMetadataExchange" />
  </service>

</services>

<client>
  <endpoint address="http://Server2:8000/servicemodelsamples/service"
    behaviorConfiguration="myClientBehavior" binding="wsHttpBinding"
    bindingConfiguration="MybindingCon" contract="Microsoft.ServiceModel.Samples.ICalculator"
    name="">
    <identity>
      <dns value="ODWCertificatServeur" />
    </identity>
  </endpoint>
</client>

<bindings>
  <wsHttpBinding>
    <binding name="MybindingCon">
      <security mode="Message">
        <message clientCredentialType="UserName" />
      </security>
    </binding>
  </wsHttpBinding>
</bindings>

<behaviors>
  <serviceBehaviors>
    <behavior name="ServiceTraitementBehavior">
      <serviceMetadata httpGetEnabled="True"/>
      <serviceDebug includeExceptionDetailInFaults="True" />
    </behavior>
  </serviceBehaviors>
  <endpointBehaviors>
    <behavior name="myClientBehavior">
      <clientCredentials>
        <clientCertificate findValue="MachineServiceTraitement" x509FindType="FindBySubjectName" storeLocation="LocalMachine" storeName="My" />
        <serviceCertificate>
          <authentication certificateValidationMode="ChainTrust" revocationMode="NoCheck"/>
        </serviceCertificate>
      </clientCredentials>
    </behavior>
  </endpointBehaviors>
</behaviors>

And here's the config file from the web app that calls the service on Server1 :

<system.serviceModel>
<bindings>
  <wsHttpBinding>
    <binding name="WSHttpBinding_ITraitement" closeTimeout="00:01:00"
        openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
        bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"
        maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
        messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"
        allowCookies="false">
      <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
          maxBytesPerRead="4096" maxNameTableCharCount="16384" />
      <reliableSession ordered="true" inactivityTimeout="00:10:00"
          enabled="false" />
      <security mode="Message">
        <transport clientCredentialType="Windows" proxyCredentialType="None"
            realm="" />
        <message clientCredentialType="Windows" negotiateServiceCredential="true"
            algorithmSuite="Default" establishSecurityContext="true" />
      </security>
    </binding>
  </wsHttpBinding>
</bindings>
<client>
  <endpoint address="http://localhost:8020/ServiceTraitementPC"
      binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_ITraitement"
      contract="ITraitement" name="WSHttpBinding_ITraitement">
  </endpoint>
</client>

Any idea why it works if if I call it in a console app and not from my service ? Maybe it has something to do with the certificateValidationMode="ChainTrust" ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

江城子 2024-09-02 12:01:41

好吧,最后只需信任客户端计算机上的证书颁发者即可。教程中提到了这一点,我一定错过了这一步。仍然想知道为什么它在从控制台应用程序调用时有效,但是......无论如何,它现在工作正常。

谢谢 !

Well, finally it was just a matter of trusting the issuer of the certificate on the client machine. It was mentioned in the tutorial and I must have missed that step. Still wonder why it worked when calling from a console app, but... anyway, it works fine now.

Thanks !

别闹i 2024-09-02 12:01:41

当您从控制台应用程序调用该服务时,您位于已登录用户的安全上下文中。

当您从 IIS 中运行的服务调用该服务时,使用默认设置,您将处于本地帐户 NETWORK SERVICE 的安全上下文中。

修复它的方法可能是在 web.config 的 system.web 部分中设置 impersonate=true 。

When you call the service from the console app you are in the security context of the logged in user.

When you call the service from a service running in IIS, with default settings, you are in the security context of a local account NETWORK SERVICE.

The way to fix it is probably to set impersonate=true in the system.web section of your web.config.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文