WCF transport security: socket connection was aborted

会有一股神秘感。 提交于 2020-08-10 17:42:09

问题


I have a problem in getting transport security to work.

I have 2 services (A & B) running in the same server. service A will call service B to perform some task. Without any security, I can communicate just fine. But when I turn on transport security with the following settings:

  • security mode = transport
  • TransportClientCredentialType = Windows
  • ProtectionLevel = EncryptAndSign

I got error when service A calls service B:

System.ServiceModel.CommunicationException: 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:00:09.7810000'. ---> System.IO.IOException: The read operation failed, see inner exception. ---> System.ServiceModel.CommunicationException: 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:00:09.7810000'. ---> System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host

I tried changing the receive and send timeout to 5 mins but I still get the same error with roughly the same timeout duration. The only difference is I need to wait out the 5 minutes instead of 1 minute.

Can anyone provide an insight to what's the cause and how to resolve this?

Attached is the configuration file for both service:

ServiceA

<?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>

ServiceB

<?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>

回答1:


There is a solution here ...you should try it...

  1. Added these behaviors at both service and client config.

    <behaviors>
     <endpointBehaviors>
      <behavior name="endpointBehavior">
    <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
    </behavior>
     </endpointBehaviors>
    </behaviors>
    
  2. Update these values to maximum size in both Client and Server config.

    <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>
    

Hope it helps.




回答2:


I had that same error and it was caused by the service credentials being wrong or missing. Since you're using tcp binding first create the binding and set the security properly:

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;

Make sure to set the username and password after creating the client:

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

Don't do anything else to the client after that. I've seen weird behavior like setting reader quotas programmatically after assigning the credentials, and the credentials get wiped out.




回答3:


I managed to solve this problem by doing the following in the server where the net.tcp web service was hosted:

  1. Restart NET TCP port sharing service from services.msc
  2. Open command prompt as administrator and run the IIS Reset


来源:https://stackoverflow.com/questions/30614985/wcf-transport-security-socket-connection-was-aborted

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!