2009-08-18 5 views
8

Я следил за многочисленными статьями msdn и инструкциями codeplex, но не могу заставить WCF работать с аутентификацией и делегированием Kerberos, и мне очень понравилась бы небольшая помощь.Аутентификация WCF и Kerberos

Настройка

У меня есть службы WCF в качестве веб-сайта IIS на удаленном компьютере

  • IIS 6.0 на Windows 2003 R2 - SP 2
  • был добавлен SPN для машины (http/myserver & & http/myserver: 8080)
  • Учетная запись AD создана для пула приложений IIS
  • Счет AD имеет параметр, позволяющий делегирование (для Kerberos), установите истинного

Я использую Brian Booth's debug site на 8080 и сайт передает все требования для делегирования Kerberos. На веб-сайте отладки IIS отключена анонимная аутентификация и включена встроенная проверка подлинности Windows.

Я отразил эти настройки на сайте, на котором размещается служба WCF.

Web Service - Web Config (Original)

<system.serviceModel> 
    <bindings> 
     <wsHttpBinding> 
      <binding name="WsHttpBindingConfig"> 
       <security> 
        <message negotiateServiceCredential="true" /> 
       </security> 
      </binding> 
     </wsHttpBinding> 
    </bindings> 
    <services> 
     <service behaviorConfiguration="ServiceBehavior" name="Service">  
      <endpoint address="" 
       binding="wsHttpBinding" 
       bindingConfiguration="WsHttpBindingConfig" 
       contract="IService">  
       <identity>  
        <servicePrincipalName value="http/myserver" />  
        <dns value="" />  
       </identity>  
      </endpoint>  
      <endpoint address="mex" 
       binding="mexHttpBinding" 
       contract="IMetadataExchange" />  
     </service>  
    </services>  
    <behaviors>  
     <serviceBehaviors>  
      <behavior name="ServiceBehavior">  
       <serviceMetadata httpGetEnabled="true"/>  
       <serviceDebug includeExceptionDetailInFaults="true"/>  
       <serviceAuthorization 
        impersonateCallerForAllOperations="true" />  
      </behavior>  
     </serviceBehaviors>  
    </behaviors>  
</system.serviceModel> 

Web Service - Web метод

[OperationBehavior(Impersonation = ImpersonationOption.Required)] 
public string GetCurrentUserName() 
{ 
    string name = WindowsIdentity.GetCurrent().Name; 
    return name; 
} 

Client App - App Config

<system.serviceModel> 
    <bindings> 
     <wsHttpBinding> 
      <binding name="WSHttpBinding_IService" 
       ... /> 
       ... 
       <security mode="Message"> 
        <transport clientCredentialType="Windows" 
         proxyCredentialType="None" 
         realm="" /> 
        <message clientCredentialType="Windows" 
         negotiateServiceCredential="true" 
         algorithmSuite="Default" 
         establishSecurityContext="true" /> 
       </security> 
      </binding> 
     </wsHttpBinding> 
    </bindings> 
    <client> 
     <endpoint address="http://myserver/Service.svc" 
      binding="wsHttpBinding" 
      bindingConfiguration="WSHttpBinding_IService" 
      contract="KerberosService.IService" 
      name="WSHttpBinding_IService"> 
      <identity> 
       <servicePrincipalName value="http/myserver" /> 
      </identity> 
     </endpoint> 
    </client> 
</system.serviceModel> 

Ошибка приложения

Следующая ошибка возникает, когда мое тестовое приложение, приложение WinForms, пытается вызвать веб-метод:

«Запрос HTTP является несанкционированным с клиента схемы аутентификации „Anonymous“ , Заголовок проверки подлинности , полученные от сервера был 'Negotiate, NTLM «

Журнал событий

следующее сообщение об ошибке в журнале событий:.

Исключение: системы .ServiceModel.ServiceActivationException: Служба '/Service.svc' не может быть активирована из-за исключения во время compila Тион. Сообщение об исключении : Параметры безопасности для этой службы требуют «анонимной» аутентификации, но не включен для приложения IIS , на котором размещена эта служба.

Который я не понимаю. Весь смысл этой службы заключается в том, чтобы не допускать анонимную аутентификацию, каждый пользователь/запрос должен быть аутентифицирован с использованием билетов Kerberos, а затем передавать их другим машинам.

Как настроить эту службу WCF для аутентификации и делегирования Kerberos?

Редакция 1

После прочтения this SO question я удалил конечную точку метаданных. Это не решило проблему.

Revision 2

После еще исследования я нашел несколько постов, предполагающих, чтобы изменить WsHttpBinding к BasicHttpBinding. Модификация этой части web.config была включена ниже, и конечная точка службы была обновлена, чтобы ссылаться на эту привязку.

Web Service - Web Config (пересмотренная)

<basicHttpBinding> 
    <binding name="basicBindingConfig"> 
     <security mode="TransportCredentialOnly"> 
      <transport clientCredentialType="Windows" 
       proxyCredentialType="Windows" 
       realm="" /> 
     </security> 
    </binding> 
</basicHttpBinding> 

Client App - App Config (пересмотренная)

<!-- ... --> 
<security mode="TransportCredentialOnly"> 
    <transport clientCredentialType="Windows" 
     proxyCredentialType="Windows" 
     realm="" /> 
    <message clientCredentialType="UserName" 
     algorithmSuite="Default" /> 
</security> 
<!-- ... --> 

Ошибка (пересмотренная)

Ток ошибка выглядит так, как будто она содержит Kerberos authe заголовок ntication.

Запрос HTTP является несанкционированным со схемой аутентификации клиента 'Переговоры'. Заголовок проверки подлинности , полученные от сервера был «Обсуди SOMEHUGESCARYKEYHERE

+1

Примечание: я опубликовал и удалил что-то похожее вчера, это сообщение включает в себя ревизии, основанные на большем количестве исследований и должны быть чище читать. – blu

+1

Я добавил обновленную конфигурацию приложения на основе обратной связи marc_s. – blu

ответ

3

Что-то, что я заметил: клиент и сервер конфигурации, кажется, не согласны на режим безопасности.

В исходном разделе у вас есть <security>..... в файле web.config (опущен режим = "сообщение") и <security mode="Message"> на стороне клиента.

После вашего редактирования кажется, что клиентская сторона не изменилась, но сервер (web.config) теперь содержит <security mode="TransportCredentialOnly">.

Вопрос на самом деле: можете ли вы гарантировать, что только один узел сети будет находиться между клиентом и вызываемым сервером? То есть это за корпоративным брандмауэром? В этом случае я рекомендовал бы привязку netTcp с <security mode="Transport"> с обоих концов.

Если это не так, то вы в порядке с wsHttpBinding (который поддерживает больше функций безопасности и надежности, но медленнее и «тяжелее») или basicHttpBinding. В этом случае вам нужно будет использовать <security mode="Message"> с обоих концов и аутентифицировать службу с помощью сертификата (чтобы у службы и клиента был общий «секрет», который должен использоваться для шифрования).

Я попытался бы исключить части олицетворения для начала и просто получить основную связь и взаимную аутентификацию между сервисом и клиентом и запустить его сначала - как только это будет на месте, вы можете начать добавлять к нему биты олицетворения, и вы всегда можете отказаться от известной конфигурации, которая работает.

Дэвид Sackstein имеет great series of blog posts объясняя пять сценариев безопасности, промышленности гуру Юваль Лоуи был идентифицирован (в его Programming WCF книги - WCF Библия), как наиболее распространенные и наиболее полезным - для того, чтобы ограничить количество возможных комбинаций параметров вы можете захотеть настроить. Один из них - это сценарий «Интернет», который, вероятно, применим здесь, если ваша служба обращена наружу.

Марк

+1

Спасибо за ответ. Я не включил обновленный клиентский код, я понял, что у этого вопроса есть достаточно беспорядок, как есть. Я рассмотрю предоставленную вами информацию, спасибо. – blu

+1

«аутентифицировать сервис с сертификатом», это то, что кто-то здесь пытается избежать. Мы надеялись использовать прямые билеты Kerberos для аутентификации пользователей и делегирования всей системы на задние компьютеры, такие как SP и SQL. – blu

7

Для меня текущая настройка делает работы:

На сервере:

<system.serviceModel> 
    <bindings> 
    <wsHttpBinding> 
     <binding name="wsHttpBindingConf" useDefaultWebProxy="true"/> 
    </wsHttpBinding> 
    </bindings> 

    <services> 
    <service behaviorConfiguration="returnFaults" name="Epze.BusinessLayer.ZeitManager"> 
     <endpoint binding="wsHttpBinding" bindingConfiguration="wsHttpBindingConf" contract="Epze.Contract.IZeitManager"/> 
     <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/> 
    </service> 
    </services> 

    <behaviors> 
    <serviceBehaviors> 
     <behavior name="returnFaults"> 
      <serviceMetadata httpGetEnabled="true"/> 
      <serviceDebug includeExceptionDetailInFaults="true"/> 
      <serviceAuthorization impersonateCallerForAllOperations="true"/> 
     </behavior> 
    </serviceBehaviors> 
    </behaviors> 
</system.serviceModel> 

Установить следующий атрибут всех методов WCF:

[OperationBehavior(Impersonation = ImpersonationOption.Required)] 

О клиенте:

<system.serviceModel> 
    <bindings> 
    <wsHttpBinding> 
     <binding name="WSHttpBinding_IZeitManager" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false"> 
      <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/> 
      <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false"/> 
      <security mode="Message"> 
       <transport clientCredentialType="Windows" proxyCredentialType="None" realm=""/> 
       <message clientCredentialType="Windows" negotiateServiceCredential="true" algorithmSuite="Default" establishSecurityContext="true"/> 
      </security> 
     </binding> 
    </wsHttpBinding> 
    </bindings> 

    <behaviors> 
    <endpointBehaviors> 
     <behavior name="Delegation"> 
     <clientCredentials> 
      <windows allowedImpersonationLevel="Delegation" /> 
     </clientCredentials> 
     </behavior> 
    </endpointBehaviors> 
    </behaviors>   

    <client> 
    <endpoint address="http://server.mydomain.net/ePZEsvc/ZeitManager.svc" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IZeitManager" 
       contract="External.Epze.IZeitManager" name="WSHttpBinding_IZeitManager" behaviorConfiguration="Delegation"> 
     <identity> 
      <servicePrincipalName value="HOST/localhost"/> 
     </identity>      
    </endpoint> 
    </client> 
</system.serviceModel> 

НТНЫ, Sven

+1

Как насчет настроек IIS для методов проверки подлинности? Анонимный доступ отключен? – Jonathan

+1

У меня включена аутентификация Windows и анонимный доступ. Но вам понадобится только анонимный, добавив к вашей службе конечную точку mex (IMetadataExchange). –

1

Вы должны попробовать начальную настройку и убедитесь, чтобы установить IIS, чтобы быть анонимной и окно аутентификации в той же полиэтничной причине при использовании безопасности WsHttpBinding по умолчанию безопасности сообщений и нет безопасности транспорта, если вы не хотите делать https. SO Clr утверждает, что для IIS требуется анонимная аутентификация.

2

Необходимо указать поведение конфигурации в конфигурации клиента. SVCUtil не генерирует автоматически. Это решило мою проблему, и теперь я успешно использую Kerberos. Это была миссия!

<client>   
    <endpoint address="..."    
    binding="customBinding" bindingConfiguration="..."    
    contract="..." name="..." behaviorConfiguration="ImpersonationBehavior" />     
    </client>   
    <behaviors> 
     <endpointBehaviors>    
     <behavior name="ImpersonationBehavior">    
       <clientCredentials>     
       <windows allowedImpersonationLevel="Impersonation"/>      </clientCredentials>    
    </behavior>      
    </endpointBehaviors>     
    </behaviors> 

 Смежные вопросы

  • Нет связанных вопросов^_^