WCF & clock skew -- custom binding configuration ignored?
Our clients are facing the same clock skew problems that are haunting so many other people as well.
The an开发者_C百科swers in those pages and further web searching helped quite a bit, but I faced with a different problem.
When debugging on my local machine, I can see that the properties on the bindings are set correctly.
But as I can not test the code locally (I only have one clock), i have to publish the service to a test server. Yet when I connect to the service with a skewed clock, I still receive MessageSecurityException
s.
My first thought was that the binding gets modified after creation, but both I and a coworker on this project confirmed that the bindings are created once and not touched after.
I am obviously Doing It Wrong [TM]. I would be very grateful if someone could shed light on the matter. Thank you in advance.
This is the code that creates the binding:
WSHttpBinding binding = new WSHttpBinding();
binding.Security.Mode = SecurityMode.TransportWithMessageCredential;
binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
// ... blah blah ...
// fix ongoing security
sbe.LocalClientSettings.DetectReplays = false;
sbe.LocalClientSettings.MaxClockSkew = TimeSpan.MaxValue;
sbe.LocalClientSettings.SessionKeyRenewalInterval = TimeSpan.MaxValue;
sbe.LocalServiceSettings.DetectReplays = false;
sbe.LocalServiceSettings.MaxClockSkew = TimeSpan.MaxValue;
sbe.LocalServiceSettings.SessionKeyRenewalInterval = TimeSpan.MaxValue;
// fix bootstrap security
SecureConversationSecurityTokenParameters sct = null;
if (sbe is SymmetricSecurityBindingElement)
{
SecurityTokenParameters tokenParameters =
((SymmetricSecurityBindingElement)sbe).ProtectionTokenParameters;
if (tokenParameters is SecureConversationSecurityTokenParameters)
{
sct = tokenParameters as SecureConversationSecurityTokenParameters;
}
}
else if (sbe is TransportSecurityBindingElement)
{
sct = sbe.EndpointSupportingTokenParameters
.Endorsing
.OfType<SecureConversationSecurityTokenParameters>()
.FirstOrDefault();
}
else
{
throw new ArgumentException("Binding has neiter a " +
"SymmetricSecurityBindingElement nor " +
"TransportSecurityBindingElement");
}
SecurityBindingElement bootbe = sct.BootstrapSecurityBindingElement;
bootbe.LocalClientSettings.DetectReplays = false;
bootbe.LocalClientSettings.MaxClockSkew = TimeSpan.MaxValue;
bootbe.LocalClientSettings.SessionKeyRenewalInterval = TimeSpan.MaxValue;
bootbe.LocalServiceSettings.DetectReplays = false;
bootbe.LocalServiceSettings.MaxClockSkew = TimeSpan.MaxValue;
bootbe.LocalServiceSettings.SessionKeyRenewalInterval = TimeSpan.MaxValue;
This is a call stack of the exception I receive in the service trace log:
System.ServiceModel.Security.MessageSecurityException, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
System.ServiceModel.Security.TransportSecurityProtocol.VerifyIncomingMessage(Message& message, TimeSpan timeout)
System.ServiceModel.Security.SecurityProtocol.VerifyIncomingMessage(Message& message, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationStates)
System.ServiceModel.Channels.SecurityChannelListener`1.ServerSecurityChannel`1.VerifyIncomingMessage(Message& message, TimeSpan timeout, SecurityProtocolCorrelationState[] correlationState)
System.ServiceModel.Channels.SecurityChannelListener`1.SecurityReplyChannel.ProcessReceivedRequest(RequestContext requestContext, TimeSpan timeout)
System.ServiceModel.Channels.SecurityChannelListener`1.ReceiveItemAndVerifySecurityAsyncResult`2.OnInnerReceiveDone()
System.ServiceModel.Channels.SecurityChannelListener`1.ReceiveItemAndVerifySecurityAsyncResult`2.InnerTryReceiveCompletedCallback(IAsyncResult result)
System.Runtime.Fx.AsyncThunk.UnhandledExceptionFrame(IAsyncResult result)
System.Runtime.AsyncResult.Complete(Boolean completedSynchronously)
System.Runtime.InputQueue`1.AsyncQueueReader.Set(Item item)
System.Runtime.InputQueue`1.Dispatch()
System.Runtime.ActionItem.DefaultActionItem.Invoke()
System.Runtime.ActionItem.CallbackHelper.InvokeWithoutContext(Object state)
System.Runtime.IOThreadScheduler.ScheduledOverlapped.IOCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
System.Runtime.Fx.IOCompletionThunk.UnhandledExceptionFrame(UInt32 error, UInt32 bytesRead, NativeOverlapped* nativeOverlapped)
System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
You should receive a MessageSecurityException
if your message is rejected due to the times on the server and client differing by more than the clock skew setting. Given your description I think what you're seeing is what is expected.
According to Microsoft, the reason a MessageSecurityException
is returned instead of something more specific is because
Security exceptions can expose some very sensitive information and due to this we decided not to expose any details from the security layer. For example, the clock skew issue that you have mentioned, when exposed in the fault exception, would provide an attacker the clock skew settings of the service and gives information to craft a more specific attack.
精彩评论