I have a WCF application that is hosted on AWS. To achieve a higher availability, I've created a snapshot of the WCF machine and launched another instance with this image.
Also, I've created an Elastic Load Balance (ELB) that routes requests to those 2 servers.
With my WCF Client, I can successfully connect with both servers if I use the machine public IP address. But if I use the ELB hostname, my connection fails with the following error:
System.ServiceModel.FaultException: The message could not be processed. This is most likely because the action 'http://tempuri.org/IService/GetCustomerData' is incorrect or because the message contains an invalid or expired security context token or because there is a mismatch between bindings. The security context token would be invalid if the service aborted the channel due to inactivity. To prevent the service from aborting idle sessions prematurely increase the Receive timeout on the service endpoint's binding.
The error suggests that I have a invalid or expired security token. So, I've checked the Send and Receive timeout and it is already set to 10 minutes: sendTimeout="00:10:00"
, receiveTimeout="00:10:00"
(requests usually takes 5-15 seconds)
My biding configuration:
<bindings>
<wsHttpBinding>
<binding name="wsHttpBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" useDefaultWebProxy="true">
<reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Basic"/>
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
Also, I've double checked:
I've managed to solve this issue adding the following parameter: establishSecurityContext="false"
.
<bindings>
<wsHttpBinding>
<binding name="wsHttpBinding" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard" useDefaultWebProxy="true">
<reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
<security mode="TransportWithMessageCredential">
<transport clientCredentialType="Basic"/>
<message clientCredentialType="UserName"
establishSecurityContext="false"/> <!-- this line -->
</security>
</binding>
</wsHttpBinding>
</bindings>
Googling, I've learned that:
When this value is set to false, key exchange and validation must be done per call using asymmetric encryption. The default value of this parameter is true and that means that the first call will create a security context with asymmetric encryption, but it will be cached and further calls will use only symmetric encryption, that is faster.
Performance consideration: Yaron Naveh
When the client is expected to make many calls in succession, it is better to set this parameter to true, BUT with a Load Balance, calls are routed to different servers and this breaks the message due to invalid token. So, you must to disable this Security Context feature.
Detailed explanation in Establishing Security Context section: https://msdn.microsoft.com/en-us/library/hh273122(v=vs.100).aspx
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With