Ищите решение WCF для передачи учетных данных пользователя в среде с балансировкой нагрузки с помощью пользовательской привязки - PullRequest
0 голосов
/ 24 августа 2010

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

AnПроблема, с которой мы столкнулись, заключается в том, что 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 выше для пользовательской привязки?Как я могу заставить его передать учетные данные пользователя?

Спасибо!

1 Ответ

1 голос
/ 26 августа 2010

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

<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 не шифруются (что мы и хотели).Поэтому я думаю, что эта конфигурация будет хорошо работать для нашей ситуации.

...