Как исправить проблему WCF maxClockSkew в контексте приложения HTTPS Silverlight? - PullRequest
6 голосов
/ 19 октября 2010

Ситуация : приложение 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 является basicHttpBinding с 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 минут)?

  • Почему этоПохоже, это приключение, чтобы исправить такую ​​тривиальную конфигурацию?

Любая помощь будет признательна!

Ответы [ 3 ]

5 голосов
/ 06 января 2011

Следующий фрагмент кода позволяет установить maxClockSkew для TransportSecurityBindingElement. Мое решение - надстройка Outlook + WCF, работающая в контексте http и https, поэтому, хотя и не в том же контексте, что и у вас, она похожа.

  • Твои привязки выглядят правильно для меня.
  • Вот фрагмент кода

    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;
    } 
  • Отклонение часов имеет значение только в том случае, если вы используете учетные данные клиента UserName, а некоторым пользователям нравится, что часы их компьютера не являются точными, или им все равно

  • Да, настройка WCF - это всегда приключение, которое вы не хотели бы делать.
0 голосов
/ 23 октября 2010

Вы пробовали перейти на пользовательское связывание в конфигурации (вместо кода) и изменить там maxClockSkew?Смотрите, например, примеры конфигурации в http://social.msdn.microsoft.com/forums/en-US/wcf/thread/0e8c30ab-e5a0-40b1-9722-c1b20a09c8ad/

0 голосов
/ 19 октября 2010

Мы сталкиваемся с той же проблемой здесь !!!Для дальнейшего обсуждения, если этот пост может помочь, код, где он ищет параметр токена, взят с этого сайта

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...