在 2 台机器边界(3 台机器)上使用模拟时 WCF 失败

发布于 2024-08-31 10:27:10 字数 9066 浏览 5 评论 0原文

这些场景各自发挥作用。当我把它们放在一起时,它就破裂了。

我有一个使用 netTCP 的 WCF 服务,它使用模拟来获取调用者 ID(在此级别将使用基于角色的安全性),

最重要的是使用 basicHTTP 和 TransportCredientialOnly 的 WCF 服务,它也使用模拟,

然后我有一个客户端前端连接到 basicHttp。

游戏的目的是从底部的 netTCP 服务返回客户端用户名 - 所以最终我可以在这里使用基于角色的安全性。

每个服务都位于不同的计算机上 - 当您在本地和远程为它们运行客户端时删除它们对其他服务进行的任何调用时,每个服务都会工作。 IE 问题仅在您跨越多个机器边界时才会出现。

IE 当我将每个部分连接在一起时,设置会中断 - 但它们自己工作得很好。

指定

我还在方法中

[OperationBehavior(Impersonation = ImpersonationOption.Required)]并将 IIS 设置为仅允许 Windows 身份验证(实际上我仍然启用了 ananymous,但禁用没有区别)

这种模拟在我有一个机器 A 上的 netTCP 服务,客户端在机器 B 上有 basicHttp 服务,机器 B 上也有 basicHttp 服务的 clinet ...但是,如果我将该客户端移动到任何机器 C,我会收到以下错误:

例外是“套接字连接被中止。这可能是由于处理消息时出错、远程主机超出接收超时或底层网络资源问题造成的。本地套接字超时为“00:10:00” 内部消息是“现有连接被远程主机强制关闭”

我开始认为这更多是一个网络问题而不是配置问题...但后来我抓住了救命稻草...

配置文件如下(从客户端向下到netTCP层)

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="basicHttpBindingEndpoint" closeTimeout="00:02:00"
                    openTimeout="00:02:00" receiveTimeout="00:10:00" sendTimeout="00:02:00"
                    allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                    useDefaultWebProxy="true">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <security mode="TransportCredentialOnly">
                        <transport clientCredentialType="Windows" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="UserName" algorithmSuite="Default" />
                    </security>
                </binding>
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://panrelease01/WCFTopWindowsTest/Service1.svc"
                binding="basicHttpBinding" bindingConfiguration="basicHttpBindingEndpoint"
                contract="ServiceReference1.IService1" name="basicHttpBindingEndpoint" 
 behaviorConfiguration="ImpersonationBehaviour" />
        </client>
  <behaviors>
   <endpointBehaviors>
    <behavior name="ImpersonationBehaviour">
     <clientCredentials>
      <windows allowedImpersonationLevel="Impersonation"/>
     </clientCredentials>
    </behavior>
   </endpointBehaviors>
  </behaviors>
    </system.serviceModel>
</configuration>

客户端的服务(basicHttp服务和netTCP服务的客户端)

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding name="netTcpBindingEndpoint" closeTimeout="00:01:00"
          openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
          transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
          hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="524288"
          maxBufferSize="65536" maxConnections="10" maxReceivedMessageSize="65536">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
            maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <reliableSession ordered="true" inactivityTimeout="00:10:00"
            enabled="false" />
          <security mode="Transport">
            <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
            <message clientCredentialType="Windows" />
          </security>
        </binding>
      </netTcpBinding>
  <basicHttpBinding>
   <binding name="basicHttpWindows">
    <security mode="TransportCredentialOnly">
     <transport clientCredentialType="Windows"></transport>
    </security>
   </binding>
  </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="net.tcp://5d2x23j.panint.com/netTCPwindows/Service1.svc"
    binding="netTcpBinding" 
    bindingConfiguration="netTcpBindingEndpoint"
    contract="ServiceReference1.IService1" 
    name="netTcpBindingEndpoint"
    behaviorConfiguration="ImpersonationBehaviour">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>
    </client>
    <behaviors>
  <endpointBehaviors>
   <behavior name="ImpersonationBehaviour">
    <clientCredentials>
     <windows allowedImpersonationLevel="Impersonation" allowNtlm="true"/>
    </clientCredentials>
   </behavior>
  </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="WCFTopWindowsTest.basicHttpWindowsBehaviour">
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true" />
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
   <services>
    <service name="WCFTopWindowsTest.Service1"
       behaviorConfiguration="WCFTopWindowsTest.basicHttpWindowsBehaviour">
     <endpoint address=""
      binding="basicHttpBinding"
      bindingConfiguration="basicHttpWindows"
      name ="basicHttpBindingEndpoint"
      contract ="WCFTopWindowsTest.IService1">

     </endpoint>      
   </service>       
   </services>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
        <directoryBrowse enabled="true" />
  </system.webServer>

</configuration>

然后最后是netTCP层的服务

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

  <system.web>
   <authentication mode="Windows"></authentication>
   <authorization>
    <allow roles="*"/>
   </authorization>
    <compilation debug="true" targetFramework="4.0" />
        <identity impersonate="true" />
  </system.web>
  <system.serviceModel>
   <bindings>
    <netTcpBinding>
     <binding name="netTCPwindows">
      <security mode="Transport">
       <transport clientCredentialType="Windows"></transport>
      </security>
     </binding>
    </netTcpBinding>
   </bindings>
   <services>
    <service behaviorConfiguration="netTCPwindows.netTCPwindowsBehaviour" name="netTCPwindows.Service1">
     <endpoint address="" bindingConfiguration="netTCPwindows" binding="netTcpBinding" name="netTcpBindingEndpoint" contract="netTCPwindows.IService1">
      <identity>
       <dns value="localhost" />
      </identity>
     </endpoint>  
     <endpoint address="mextcp" binding="mexTcpBinding" contract="IMetadataExchange"/>
     <host>
      <baseAddresses>     
       <add baseAddress="net.tcp://localhost:8721/test2" />
      </baseAddresses>
     </host>
    </service>       
   </services>   
    <behaviors>  
      <serviceBehaviors>
        <behavior name="netTCPwindows.netTCPwindowsBehaviour">  

          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="false" />
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
        <directoryBrowse enabled="true" />
  </system.webServer>

</configuration>

These scenarios work in their pieces. Its when i put it all together that it breaks.

I have a WCF service using netTCP that uses impersonation to get the callers ID (role based security will be used at this level)

on top of this is a WCF service using basicHTTP with TransportCredientialOnly which also uses impersonation

I then have a client front end that connects to the basicHttp.

the aim of the game is to return the clients username from the netTCP service at the bottom - so ultimatley i can use role based security here.

each service is on a different machine - and each service works when you remove any calls they make to other services when you run a client for them both locally and remotley. IE the problem only manifests when you jump accross more than one machine boundary.

IE the setup breaks when i connect each part together - but they work fine on their own.

I also specify

[OperationBehavior(Impersonation = ImpersonationOption.Required)] in the method and

have IIS setup to only allow windows authentication (actually i have ananymous enabled still, but disabling makes no difference)

This impersonation works fine in the scenario where i have a netTCP Service on Machine A with a client with a basicHttp service on machine B with a clinet for the basicHttp service also on machine B ... however if i move that client to any machine C i get the following error:

The exception is 'The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:10:00''
the inner message is 'An existing connection was forcibly closed by the remote host'

Am beginning to think this is more a network issue than config ... but then im grasping at straws ...

the config files are as follows (heading from the client down to the netTCP layer)

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="basicHttpBindingEndpoint" closeTimeout="00:02:00"
                    openTimeout="00:02:00" receiveTimeout="00:10:00" sendTimeout="00:02:00"
                    allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
                    messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                    useDefaultWebProxy="true">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <security mode="TransportCredentialOnly">
                        <transport clientCredentialType="Windows" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="UserName" algorithmSuite="Default" />
                    </security>
                </binding>
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://panrelease01/WCFTopWindowsTest/Service1.svc"
                binding="basicHttpBinding" bindingConfiguration="basicHttpBindingEndpoint"
                contract="ServiceReference1.IService1" name="basicHttpBindingEndpoint" 
 behaviorConfiguration="ImpersonationBehaviour" />
        </client>
  <behaviors>
   <endpointBehaviors>
    <behavior name="ImpersonationBehaviour">
     <clientCredentials>
      <windows allowedImpersonationLevel="Impersonation"/>
     </clientCredentials>
    </behavior>
   </endpointBehaviors>
  </behaviors>
    </system.serviceModel>
</configuration>

the service for the client (basicHttp service and the client for the netTCP service)

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <bindings>
      <netTcpBinding>
        <binding name="netTcpBindingEndpoint" closeTimeout="00:01:00"
          openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
          transactionFlow="false" transferMode="Buffered" transactionProtocol="OleTransactions"
          hostNameComparisonMode="StrongWildcard" listenBacklog="10" maxBufferPoolSize="524288"
          maxBufferSize="65536" maxConnections="10" maxReceivedMessageSize="65536">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
            maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <reliableSession ordered="true" inactivityTimeout="00:10:00"
            enabled="false" />
          <security mode="Transport">
            <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
            <message clientCredentialType="Windows" />
          </security>
        </binding>
      </netTcpBinding>
  <basicHttpBinding>
   <binding name="basicHttpWindows">
    <security mode="TransportCredentialOnly">
     <transport clientCredentialType="Windows"></transport>
    </security>
   </binding>
  </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="net.tcp://5d2x23j.panint.com/netTCPwindows/Service1.svc"
    binding="netTcpBinding" 
    bindingConfiguration="netTcpBindingEndpoint"
    contract="ServiceReference1.IService1" 
    name="netTcpBindingEndpoint"
    behaviorConfiguration="ImpersonationBehaviour">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>
    </client>
    <behaviors>
  <endpointBehaviors>
   <behavior name="ImpersonationBehaviour">
    <clientCredentials>
     <windows allowedImpersonationLevel="Impersonation" allowNtlm="true"/>
    </clientCredentials>
   </behavior>
  </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="WCFTopWindowsTest.basicHttpWindowsBehaviour">
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true" />
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
   <services>
    <service name="WCFTopWindowsTest.Service1"
       behaviorConfiguration="WCFTopWindowsTest.basicHttpWindowsBehaviour">
     <endpoint address=""
      binding="basicHttpBinding"
      bindingConfiguration="basicHttpWindows"
      name ="basicHttpBindingEndpoint"
      contract ="WCFTopWindowsTest.IService1">

     </endpoint>      
   </service>       
   </services>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
        <directoryBrowse enabled="true" />
  </system.webServer>

</configuration>

then finally the service for the netTCP layer

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

  <system.web>
   <authentication mode="Windows"></authentication>
   <authorization>
    <allow roles="*"/>
   </authorization>
    <compilation debug="true" targetFramework="4.0" />
        <identity impersonate="true" />
  </system.web>
  <system.serviceModel>
   <bindings>
    <netTcpBinding>
     <binding name="netTCPwindows">
      <security mode="Transport">
       <transport clientCredentialType="Windows"></transport>
      </security>
     </binding>
    </netTcpBinding>
   </bindings>
   <services>
    <service behaviorConfiguration="netTCPwindows.netTCPwindowsBehaviour" name="netTCPwindows.Service1">
     <endpoint address="" bindingConfiguration="netTCPwindows" binding="netTcpBinding" name="netTcpBindingEndpoint" contract="netTCPwindows.IService1">
      <identity>
       <dns value="localhost" />
      </identity>
     </endpoint>  
     <endpoint address="mextcp" binding="mexTcpBinding" contract="IMetadataExchange"/>
     <host>
      <baseAddresses>     
       <add baseAddress="net.tcp://localhost:8721/test2" />
      </baseAddresses>
     </host>
    </service>       
   </services>   
    <behaviors>  
      <serviceBehaviors>
        <behavior name="netTCPwindows.netTCPwindowsBehaviour">  

          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="false" />
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" />
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
        <directoryBrowse enabled="true" />
  </system.webServer>

</configuration>

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

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

发布评论

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

评论(1

离线来电— 2024-09-07 10:27:10

如果您需要进行不止一跳,则需要为此启用委派。您可以在此处获取更多信息。

话虽这么说,如果您需要做的只是确定调用后端服务 (netTcp) 的用户的角色,则不一定需要模拟,因为 WindowsIdentity 的 TokenImpersonationLevel 只需要为信息即可确定角色会员资格。在这种情况下,您只需确保模拟发生在中间层 (basicHttp)。

If you need to make a more than one hop, you're going to need to enable delegation for that occur. You can get more information on that here.

That being said, if all you need to do is determine the role of a user that calls the backend service (netTcp), you don't necessarily need impersonation as the TokenImpersonationLevel of the WindowsIdentity should only need to be Information in order to determine role membership. In this case, you would only need to ensure impersonation was taking place in the middle-tier (basicHttp).

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