Передавать учетные данные Windows при вызове службы wcf из другой службы wcf

#c# #wcf #wcf-security

#c# #wcf #wcf-безопасность

Вопрос:

У меня следующая проблема:

У меня есть две службы WCF, обе использующие basicHttpBinging, определенные как:

     <binding name="DefaultBasicBinding" closeTimeout="01:00:00" openTimeout="01:00:00"
      receiveTimeout="01:00:00" sendTimeout="01:00:00" maxReceivedMessageSize="2147483647">
      <readerQuotas maxStringContentLength="2147483647" maxArrayLength="2147483647" />
      <security mode="TransportCredentialOnly">
        <transport clientCredentialType="Windows"/>
      </security>
    </binding>
  

В web.config у меня также есть эти строки:

 < authentication mode="Windows"/>
< serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
  

Затем у меня есть приложение silverlight, которое вызывает ServiceNo1.
На стороне сервера выполняется метод service. В ее теле ServiceNo1 и ServiceNo2 вызываются как клиент.

 ServiceNo1 client1 = new ServiceNo1();
client1.ExecuteNextMethod1();


ServiceNo2 client2 = new ServiceNo2();
client2.ExecuteNextMethod2();    
  

И это отлично работает на locahost. Когда это публикуется в dev — начинаются проблемы.

Когда методы службы выполняются в методе, вызываемом приложением silverlight, генерируется исключение:

 Exception type: 
System.ServiceModel.Security.MessageSecurityException  

Message: 
The HTTP request is unauthorized with client authentication scheme 'Negotiate'. 
The authentication header received from the server was 'Negotiate,NTLM'. 
  

Похоже, что учетные данные Windows не передаются.

Настройки, которые перечислены выше, также находятся в dev. Оба сервера (localhost amp; dev) установили «Только проверку подлинности Windows» в IIS.

Кто-нибудь не может мне помочь?

Ответ №1:

Скорее всего, происходит то, что на локальном хостинге ваш веб-сервер работает под вашими учетными данными. На сервере разработки веб-сервер будет запущен под другой учетной записью службы (например, служба пула приложений IIS для вашего приложения).

Лучшим решением будет получить учетную запись службы, под которой выполняется ваше приложение, авторизованную для второй службы.

Есть альтернативы — используйте свои учетные данные пользователя в качестве учетной записи службы в dev (я предполагаю, что это не вариант в контролируемой среде) или выдавайте себя за свои учетные данные на стороне сервера (опять же — это вряд ли будет уместно в контролируемой среде).

РЕДАКТИРОВАТЬ Лучшим вариантом для вас может быть выдача себя за учетные данные пользователя. Смотрите эту статью MSDN о реализации. Я не слишком знаком с Silverlight, но вы должны быть в состоянии сделать что-то вроде:

 using System.Security.Principal;

------------------------

WindowsImpersonationContext impersonationContext;
impersonationContext = 
    ((.WindowsIdentity)HttpContext.User.Identity).Impersonate();

//Call your service here.

impersonationContext.Undo();
  

Обратите внимание, что вы можете столкнуться с проблемой двойного перехода, когда Windows не позволит вам передавать учетные данные пользователей с одного сервера на другой — я бы прочитал связанную статью для справки.

Комментарии:

1. Я думал об этой причине и этом решении, но в моем коде методы служб используют пользовательские данные. Это не имеет решающего значения, но было бы неплохо, если бы учетные данные Windows можно было передавать по наследству.

2. Я пытался использовать Impersonate в своей проблеме, но без результата. Возможно, я делал что-то плохое. Но я использовал метод, который вы публикуете в инструкции using. Затем я попробовал ‘client1. Учетные данные клиента. Windows. Разрешенный уровень персонализации = System. Безопасность. Принципал. TokenImpersonationLevel. Олицетворение;’ а также настройка OperationBehavior в методе example с помощью ‘Олицетворять =…’. Все завершилось неудачей, но я не знаю почему. Я впервые сталкиваюсь с олицетворением ;/

3. Обе службы WCF находятся на ОДНОМ сервере, несколько в одном приложении и каталоге.