Поиск решения WCF для передачи учетных данных пользователя в среде со сбалансированной нагрузкой с настраиваемой привязкой

В настоящее время мы поддерживаем несколько служб WCF, работающих в среде с балансировкой нагрузки. Раньше мы использовали wsHttpBinding и устанавливали для installSecurityContext значение false, чтобы служба могла правильно работать с нашим балансировщиком нагрузки.

Проблема, с которой мы столкнулись, заключается в том, что wsHttpBinding по умолчанию шифрует возвращаемые результаты и, по-видимому, не может быть отключен. Это вызывает проблемы с устройством сжатия Riverbed, которое есть в нашей сети, т. Е. Зашифрованные данные сжимаются не очень хорошо ( или вообще).

Теперь мы пытаемся использовать basicHttpBinding, поскольку по умолчанию он не шифрует данные. У нас есть два требования:

  1. Работа с балансировщиком нагрузки - похоже, это возможно за счет установки для keepAliveEnabled значения false. Это требует использования настраиваемой привязки. Например:

    <customBinding>  
      <binding name="NewBinding0">  
        <httpTransport authenticationScheme="Ntlm" **keepAliveEnabled="false"** />  
      </binding>  
    </customBinding>  
    
  2. Передает учетные данные пользователя - это возможно, если установить режим безопасности на TransportCredentialOnly. Это доступно с помощью basicHttpBinding. Например:

    <basicHttpBinding>  
      <binding name="NewBinding1">  
        <security **mode="TransportCredentialOnly"** />  
      </binding>  
    </basicHttpBinding>  
    

Итак, теперь мой актуальный вопрос: -) ... Как / возможно ли объединить два вышеуказанных требования в одну настраиваемую привязку? Что эквивалентно # 2 выше для пользовательской привязки? Как я могу заставить его передать учетные данные пользователя?

Спасибо!


person Jeff Bramwell    schedule 24.08.2010    source источник


Ответы (1)


Оказывается, я мог делать то, что хотел, с настраиваемой привязкой, используя следующую конфигурацию привязки:

<customBinding>
 <binding name="NewBinding0">
 <httpTransport authenticationScheme="Ntlm" keepAliveEnabled="false" />
 </binding>
</customBinding>

Затем на стороне клиента я мог бы использовать следующий код для получения идентификатора пула приложений, в котором работала служба WCF (в IIS), а также идентификатора пользователя, который фактически вызвал службу WCF:

public string GetData(int value)
{
  var callingUser = string.Empty;
  var appPoolUser = WindowsIdentity.GetCurrent().Name;
  var identities =
    OperationContext.Current.ServiceSecurityContext.AuthorizationContext.Properties["Identities"] as
    IList<IIdentity>;

  if (identities != null)
  {
    var result = from i in identities
            where i.AuthenticationType == "NTLM"
            select new { i.Name };

    if (result.Count() > 0)
    {
      callingUser = result.First().Name;
    }

  }

  return string.Format("Value Entered: {0}; AppPool User: {1}; Calling User: {2}", value,
          appPoolUser, callingUser);
}

Я протестировал приведенный выше код в среде с балансировкой нагрузки на соответствие Требованию №1, и все, казалось, работало нормально. Тесты моделировали нагрузку на 100 пользователей в течение 10 минут в среде с балансировкой нагрузки. Мы отключили один из серверов с балансировкой нагрузки во время теста, и все продолжало работать, как ожидалось (т.е. во время тестов не возникало никаких исключений, и никакие идентификаторы не возвращались некорректно).

Приведенный выше код является ключевым элементом требования № 2, которого мне не хватало, т.е. до этого исследования я не осознавал, что WCF предоставит вам несколько идентификаторов.

Кроме того, при использовании этой конфигурации результаты вызова WCF не шифруются (что мы и хотели). Итак, я думаю, что эта конфигурация отлично подойдет для нашей ситуации.

person Jeff Bramwell    schedule 26.08.2010