How to fix WCF maxClockSkew in the context of an HTTPS Silverlight application?

Situation : A Silverlight 4 application interacts with a server component through WCF using basicHttpBinding and HTTPS.

Here is the binding of the server side used:

<basicHttpBinding> <binding name="DefaultSecuredBinding" maxReceivedMessageSize="2147483647" maxBufferSize="2147483647"> <readerQuotas maxDepth="50" maxArrayLength="2147483647" maxStringContentLength="2147483647" /> <security mode="TransportWithMessageCredential"> <message clientCredentialType="UserName"/> <transport clientCredentialType="None" proxyCredentialType="None"/> </security> </binding> </basicHttpBinding> 

Please note that we use TransportWithMessageCredential as a security mode. The certificate is correctly installed on IIS.

The application runs smoothly when run locally.

However, we now have external users connecting to our application. Some of them have difficulties and look at the server logs, we found this error:

"MessageSecurityException" The security timestamp is expired because its expiration time ('2010-10-18T22: 37: 58.198Z') is in the past. The current time is "2010-10-18T22: 43: 18.850Z" and the permitted deviation of the hours is "00: 05: 00".

We did a regular study on topics on the Internet (StackoverFlow and Google ... and Bing) to learn more about the topic. We contacted users to ensure that they were time-compensated by our server, which was later confirmed.

This MSDN article was the beginning: http://msdn.microsoft.com/en-us/library/aa738468.aspx

Why use CustomBinding on an existing binding and set the MaxClockSkew property in the SecurityBindingElement of a custom binding. We implemented this solution, however, changing the SymmetricSecurityBindingElement element to TransportSecurityBindingElement, since our binding for secure communication with Silverlight is basicHttpBinding with HTTPS.

Several articles on the Internet (including this MSDN article above) show code snippets that additionally set the maxClockSkew property for bootstrap items taken from ProtectionTokenParameters . I never managed to apply this part in our code, as TransportSecurityBindingElement has no ProtectionTokenParameters.

Here is our code to wrap the binding using maxClockSkew:

 protected virtual System.ServiceModel.Channels.Binding WrapClockSkew(System.ServiceModel.Channels.Binding currentBinding) { // Set the maximum difference in minutes int maxDifference = 300; // Create a custom binding based on an existing binding CustomBinding myCustomBinding = new CustomBinding(currentBinding); // Set the maxClockSkew var security = myCustomBinding.Elements.Find<TransportSecurityBindingElement>(); if (security != null) { security.LocalClientSettings.MaxClockSkew = TimeSpan.FromMinutes(maxDifference); security.LocalServiceSettings.MaxClockSkew = TimeSpan.FromMinutes(maxDifference); } return myCustomBinding; } 

"security.LocalClientSettings" may not be useful here, as this code is for the server side.

This code did not execute , we still had the same error message on the server when we had more than 5 minutes with the server. I still meant that we did not apply the bootstrap trick from the MSDN code snippet .. so we continued our web search on this topic.

We found neat wcf behavior that we thought could solve our problem.

It looks like it handles issues related to Bootstrap!

Here is the part where it looks for token parameters in the context of the TransportSecurityBindingElement object:

 //If the securityBindingElement type is TransportSecurityBindingElement if (securityBindingElement is TransportSecurityBindingElement) { foreach (SecurityTokenParameters securityTokenParameters in securityBindingElement.EndpointSupportingTokenParameters.Endorsing) { //Gets it from the EndpointSupportingTokenParameters.Endorsing property if (securityTokenParameters is SecureConversationSecurityTokenParameters) { secureConversationSecurityTokenParameters = securityTokenParameters as SecureConversationSecurityTokenParameters; break; } } } 

Note the "securityBindingElement.EndpointSupportingTokenParameters.Endorsing" ... In our situation (basicHttpBinding, TransportWithMessageCredential, Https ...) this collection, however, is empty!

So, there is no way to get securityTokenParameters, so it is not possible to set maxClockSkew.

Questions:

  • Are our bindings incorrect in the context of SL + WCF + HTTPS?

  • Isn’t it normal to find a way to set maxClockSkew in the bootstrap element in the TransportSecurityBindingElement element?

  • We are the only company that makes the HTTPS Silverlight application with clients that may not be at the same time (with an offset of + 5 minutes)?

  • Why does it seem like a pretty adventure to fix such a trivial configuration?

Any help would be appreciated!

+6
security silverlight binding wcf
source share
3 answers

The following code snippet allows you to set maxClockSkew in the TransportSecurityBindingElement element. My solution is an Outlook + WCF add-in, working in the context of http and https, therefore, although this is not the same context as yours, it is similar.

  • Your bindings look right to me.
  • Here is a snippet of code

     WSHttpBinding wsSecureBinding = new WSHttpBinding(SecurityMode.TransportWithMessageCredential, false); wsSecureBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName; wsSecureBinding.Security.Message.EstablishSecurityContext = true; wsSecureBinding.Security.Message.NegotiateServiceCredential = true; wsSecureBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate; wsSecureBinding.ReaderQuotas.MaxStringContentLength = 500000; wsSecureBinding.ReceiveTimeout = wsSecureBinding.SendTimeout = new TimeSpan(0, 5, 0); CustomBinding secureCustomBinding = new CustomBinding(wsSecureBinding); TimeSpan clockSkew = new TimeSpan(0, 15, 0); TransportSecurityBindingElement tsecurity = secureCustomBinding.Elements.Find(); SecureConversationSecurityTokenParameters secureTokenParams = (SecureConversationSecurityTokenParameters)tsecurity.EndpointSupportingTokenParameters.Endorsing.OfType().FirstOrDefault(); if (secureTokenParams != null) { SecurityBindingElement bootstrap = secureTokenParams.BootstrapSecurityBindingElement; // Set the MaxClockSkew on the bootstrap element. bootstrap.LocalClientSettings.MaxClockSkew = clockSkew; bootstrap.LocalServiceSettings.MaxClockSkew = clockSkew; } 
  • The clock skew only depends on how you use the UserName client credentials, and some users either like their computer clocks to not match the time, or they don’t care

  • Yes, WCF configuration is always an adventure that you don't need to do.
+5
source

We are facing the same problem here !!! For further discussion, if this message can help, the code where it searches for the token parameter is taken from this site

http://issues.castleproject.org/_persistent/MaxClockSkewBehavior.cs?file=44-1075&v=0&c=true

0
source

Have you tried switching to user binding in config (instead of code) and changing maxClockSkew? See config at http://social.msdn.microsoft.com/forums/en-US/wcf/thread/0e8c30ab-e5a0-40b1-9722-c1b20a09c8ad/

0
source

All Articles