【问题标题】:WCF transport security: socket connection was abortedWCF 传输安全:套接字连接被中止
【发布时间】:2015-08-17 08:40:31
【问题描述】:

我无法让运输安全发挥作用。

我有 2 个服务(A 和 B)在同一台服务器上运行。服务 A 将调用服务 B 来执行某些任务。没有任何安全措施,我可以正常交流。但是当我使用以下设置打开传输安全时:

  • 安全模式 = 传输
  • TransportClientCredentialType = Windows
  • ProtectionLevel = EncryptAndSign

服务 A 调用服务 B 时出现错误:

System.ServiceModel.CommunicationException:套接字连接已中止。这可能是由于处理您的消息时出错或远程主机超出接收超时,或者是潜在的网络资源问题引起的。本地套接字超时为“00:00:09.7810000”。 ---> System.IO.IOException: 读操作失败,见内部异常。 ---> System.ServiceModel.CommunicationException:套接字连接被中止。这可能是由于处理您的消息时出错或远程主机超出接收超时,或者是潜在的网络资源问题引起的。本地套接字超时为“00:00:09.7810000”。 ---> System.Net.Sockets.SocketException: 现有连接被远程主机强行关闭

我尝试将接收和发送超时更改为 5 分钟,但我仍然收到相同的错误,超时持续时间大致相同。唯一的区别是我需要等待 5 分钟而不是 1 分钟。

谁能提供有关原因以及如何解决此问题的见解?

附件是两个服务的配置文件:

服务A

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.web>
    <compilation targetFramework="4.5" debug="true" defaultLanguage="c#" />
  </system.web>
  <system.serviceModel>
    <protocolMapping>
      <remove scheme="net.tcp" />
      <add scheme="net.tcp" binding="netTcpBinding" bindingConfiguration="ReliableTCP" />
    </protocolMapping>
    <client/>
    <behaviors>
      <serviceBehaviors>
        <behavior name="mexTag">
          <serviceMetadata httpGetEnabled="false" />
          <serviceDebug includeExceptionDetailInFaults="false" />
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="tryBehavior">
          <dataContractSerializer maxItemsInObjectGraph="2147483647" />
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <bindings>
      <customBinding>
        <binding name="mexTcp">
          <tcpTransport portSharingEnabled="true" />
        </binding>
      </customBinding>
      <netTcpBinding>
        <binding name="ReliableTCP" portSharingEnabled="true" sendTimeout="00:05:00" receiveTimeout="00:05:00" 
                 maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647">
          <reliableSession enabled="true" />
          <security mode="Transport">
            <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
          </security>
        </binding>
      </netTcpBinding>
    </bindings>
    <services>
      <service behaviorConfiguration="mexTag" name="Test.Service.ServiceAImpl">
        <endpoint address="net.tcp://app-svr:10010/ServiceA/ServiceAImpl/" behaviorConfiguration="tryBehavior"
          binding="netTcpBinding" bindingConfiguration="ReliableTCP" contract="Test.Service.IServiceA" />
        <endpoint address="net.tcp://app-svr:10012/ServiceA/ServiceAImpl/mex"
          binding="customBinding" bindingConfiguration="mexTcp" contract="IMetadataExchange" />
      </service>
    </services>
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
    <!--
        To browse web app root directory during debugging, set the value below to true.
        Set to false before deployment to avoid disclosing web app folder information.
      -->
    <directoryBrowse enabled="true" />
  </system.webServer>
</configuration>

服务B

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.web>
    <compilation targetFramework="4.5" debug="true" defaultLanguage="c#" />
  </system.web>
  <system.serviceModel>
    <client>
      <endpoint address="net.tcp://app-svr:10010/ServiceA/ServiceAImpl/"
        binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IServiceA"
        behaviorConfiguration="tryBehavior"
        contract="ServiceAReference.IServiceA" name="NetTcpBinding_IServiceA" />
    </client>
    <behaviors>
      <serviceBehaviors>
        <behavior name="MEXGET" >
          <!-- Add the following element to your service behavior configuration. -->
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="tryBehavior">
          <dataContractSerializer maxItemsInObjectGraph="2147483647" />
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <bindings>
      <customBinding>
        <binding name="MexTcp">
          <tcpTransport portSharingEnabled="true" />
        </binding>
      </customBinding>
      <netTcpBinding>
        <binding name="ReliableTCP" portSharingEnabled="true">
          <reliableSession enabled="true" />
          <security mode="Transport">
            <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
          </security>
        </binding>
        <binding name="NetTcpBinding_IServiceA" receiveTimeout="00:05:00" sendTimeout="00:05:00" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647">
          <reliableSession enabled="true" />
          <security mode="Transport">
            <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
          </security>
        </binding>
      </netTcpBinding>
      <mexTcpBinding>
        <binding name="MexTcp" />
      </mexTcpBinding>
    </bindings>
    <services>
      <service name="Test.Service.ServiceBImpl" behaviorConfiguration="MEXGET" >

        <endpoint address="mex"
                  binding="customBinding"
      bindingConfiguration="MexTcp"
                  contract="IMetadataExchange" />

        <endpoint address="mex"
                  binding="mexHttpBinding"
                  contract="IMetadataExchange" />
        <endpoint
             address="net.tcp://app-svr:10010/ServiceB/ServiceBImpl"
             binding="netTcpBinding" behaviorConfiguration="tryBehavior"
             bindingConfiguration="ReliableTCP"
             contract="Test.Service.ServiceB" />

        <host>
            <baseAddresses>
              <add baseAddress="http://app-svr:10011/ServiceB/ServiceBImpl" />
              <add baseAddress="net.tcp://app-svr:10010/ServiceB/ServiceBImpl" />
            </baseAddresses>
        </host>
      </service>
    </services>
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
    <!--
        To browse web app root directory during debugging, set the value below to true.
        Set to false before deployment to avoid disclosing web app folder information.
      -->
    <directoryBrowse enabled="true" />
  </system.webServer>
</configuration>

【问题讨论】:

    标签: wcf wcf-security


    【解决方案1】:

    有一个解决方案here ...你应该试试...

    1. 在服务和客户端配置中添加了这些行为。

      <behaviors>
       <endpointBehaviors>
        <behavior name="endpointBehavior">
      <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
      </behavior>
       </endpointBehaviors>
      </behaviors>
      
    2. 在客户端和服务器配置中将这些值更新为最大大小。

      <binding name="tcpBinding" receiveTimeout="00:15:00" sendTimeout="00:15:00"  maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647">
        <security mode="None">
          <transport clientCredentialType="None" protectionLevel="None" />
          <message clientCredentialType="None" />
        </security>
      </binding>
      

    希望对你有帮助。

    【讨论】:

    • 感谢您的回复,但上述解决方案对我不起作用。
    【解决方案2】:

    我遇到了同样的错误,它是由服务凭据错误或丢失引起的。由于您使用的是 tcp 绑定,因此首先创建绑定并正确设置安全性:

    NetTcpBinding binding = new NetTcpBinding(SecurityMode.Transport)
            {
                CloseTimeout = TimeSpan.FromSeconds(timeoutInSeconds),
                OpenTimeout = TimeSpan.FromSeconds(timeoutInSeconds),
                SendTimeout = TimeSpan.FromSeconds(timeoutInSeconds),
                ReceiveTimeout = TimeSpan.FromSeconds(timeoutInSeconds)
            };
    
            binding.Security.Transport.ClientCredentialType = 
    TcpClientCredentialType.Windows;
            binding.MaxReceivedMessageSize = int.MaxValue;
            binding.MaxBufferSize = int.MaxValue;
            binding.MaxBufferPoolSize = int.MaxValue;
    

    请务必在创建客户端后设置好用户名和密码:

    var serviceClient = new MyServiceClient(binding, endpointYouDefine);
    serviceClient.ClientCredentials.Windows.ClientCredential = new NetworkCredential("usernameInActiveDirectory", "passwordForTheADUser", "yourdomain.com");
    

    在那之后不要对客户做任何其他事情。我见过一些奇怪的行为,例如在分配凭据后以编程方式设置读取器配额,然后凭据被清除。

    【讨论】:

      【解决方案3】:

      我设法通过在托管 net.tcp Web 服务的服务器中执行以下操作来解决此问题:

      1. 从 services.msc 重新启动 NET TCP 端口共享服务
      2. 以管理员身份打开命令提示符并运行 IIS 重置

      【讨论】:

        【解决方案4】:

        我为此创建了扩展方法。 一种用于 NetTcpBinding,另一种用于 NetNamedPipeBinding。当然只能用于内部服务。计时也是如此,当夜间不使用默认服务时,它会在早上第一次调用时失败。

            public static void ActivateMaxValues(this NetTcpBinding b)
            {
                b.OpenTimeout = TimeSpan.FromHours(10);
                b.CloseTimeout = TimeSpan.FromMinutes(10);
                b.ReceiveTimeout = TimeSpan.FromHours(10);
                b.SendTimeout = TimeSpan.FromHours(10);
        
                b.MaxBufferSize = int.MaxValue;
                b.MaxReceivedMessageSize = int.MaxValue;
        
                b.ReaderQuotas = new System.Xml.XmlDictionaryReaderQuotas()
                {
                    MaxArrayLength = int.MaxValue,
                    MaxBytesPerRead = int.MaxValue,
                    MaxDepth = int.MaxValue,
                    MaxNameTableCharCount = int.MaxValue,
                    MaxStringContentLength = int.MaxValue
                };
            }
        
            public static void ActivateMaxValues(this NetNamedPipeBinding b)
            {
                b.TransactionFlow = true;
        
                b.OpenTimeout = TimeSpan.FromHours(1);
                b.CloseTimeout = TimeSpan.FromMinutes(10);
                b.ReceiveTimeout = TimeSpan.FromHours(1);
                b.SendTimeout = TimeSpan.FromHours(1);
        
                b.MaxBufferSize = int.MaxValue;
                b.MaxReceivedMessageSize = int.MaxValue;
        
                b.ReaderQuotas = new System.Xml.XmlDictionaryReaderQuotas()
                {
                    MaxArrayLength = int.MaxValue,
                    MaxBytesPerRead = int.MaxValue,
                    MaxDepth = int.MaxValue,
                    MaxNameTableCharCount = int.MaxValue,
                    MaxStringContentLength = int.MaxValue
                };
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-12-28
          • 2011-04-28
          • 1970-01-01
          • 2011-07-09
          • 2011-03-27
          • 1970-01-01
          • 2019-05-05
          相关资源
          最近更新 更多