Как исправить проблему WCF maxClockSkew в контексте приложения HTTPS Silverlight?
ситуация: Приложение Silverlight 4, связывающееся с серверным компонентом через WCF с использованием basicHttpBinding и HTTPS.
Вот привязка, используемая на стороне сервера:
<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>
Обратите внимание, что мы используемTransportWithMessageCredential в качестве режима безопасности. Сертификат правильно установлен на IIS.
Приложение работает без сбоев при локальном запуске.
Однако теперь у нас есть внешние пользователи, подключающиеся к нашему приложению. Некоторые из них испытывают трудности, и, просматривая журналы сервера, мы обнаружили эту ошибку:
"MessageSecurityException" Отметка времени безопасности устарела, поскольку время ее истечения ('2010-10-18T22: 37: 58.198Z') прошло. Текущее время - «2010-10-18T22: 43: 18.850Z», а допустимый перекос часов - «00: 05: 00».
Мы провели обычное исследование по темам в Интернете (StackoverFlow & Google ... и Bing), чтобы узнать больше об этой теме. Мы связались с пользователями, чтобы убедиться, что они были смещены во времени на нашем сервере, что позже было подтверждено.
Эта статья MSDN была началом:http://msdn.microsoft.com/en-us/library/aa738468.aspx
Который использует CustomBinding поверх существующей привязки и устанавливает свойство MaxClockSkew в SecurityBindingElement пользовательской привязки. Мы внедрили это решение, заменив, однако, SymmetricSecurityBindingElement на TransportSecurityBindingElement, поскольку наша привязка для безопасной связи с Silverlight является базовой HttpBinding с HTTPS.
В нескольких статьях в Интернете (в том числе в вышеприведенной статье MSDN) показаны фрагменты кода, которые дополнительно устанавливают для свойства maxClockSkew элементы начальной загрузки, взятые изProtectionTokenParameters, Мне никогда не удавалось применить эту часть в нашем коде, так какTransportSecurityBindingElement кажется, не имеетProtectionTokenParameters.
Вот наш код для обвязки привязки с 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» может быть здесь бесполезен, поскольку этот код предназначен для серверной части.
Этот кодне Сделайте, у нас все еще было то же сообщение об ошибке на сервере, когда у нас было больше 5 минут разницы с сервером. Я все еще имел в виду, что мы не применили прием начальной загрузки фрагмента кода MSDN ... поэтому мы продолжили наш веб-поиск по этой теме.
Мы нашли аккуратное поведение wcf, которое, как мы думали, решило бы нашу проблему.
Это выглядело так, как будто оно решает проблемы с Bootstrap!
Вот часть, где он ищетПараметры токена в контексте TransportSecurityBindingElement:
//If the securityBindingElement's 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;
}
}
}
Обратите внимание'SecurityBindingElement.EndpointSupportingTokenParameters.Endorsing'... В нашей ситуации (basicHttpBinding, TransportWithMessageCredential, Https ...) эта коллекция, однако, пуста!
Таким образом, нет способа получить securityTokenParameters, поэтому невозможно установить maxClockSkew.
Вопросы:
Являются ли наши привязки неправильными в контексте SL + WCF + HTTPS?
Это нормально, чтобы не найти способ установить maxClockSkew на элемент начальной загрузки в TransportSecurityBindingElement?
Являемся ли мы единственной компанией, использующей приложение HTTPS Silverlight для клиентов, которые могут не работать в одно и то же время (со смещением + - 5 минут)?
Почему исправление такой тривиальной конфигурации кажется довольно сложным?
Любая помощь будет оценена!