2009-08-18 14 views
8

Śledziłem wiele artykułów msdn i wskazówki codeplex, ale nie mogę uzyskać WCF do pracy z uwierzytelnianiem i delegowaniem Kerberos i doceniłbym małą pomoc.Uwierzytelnianie WCF i Kerberos

Konfiguracja

Mam usług WCF w witrynie IIS na komputerze zdalnym

  • IIS 6.0 w systemie Windows 2003 R2 - SP 2
  • SPN dla maszyny został dodany (http/myserver & & http/myserver: 8080)
  • Konto AD zostało utworzone dla puli aplikacji IIS
  • Konto AD ma ustawienia pozwalają na delegację (Kerberos), ustawiony na true

używam Brian Booth's debug site na 8080 a strona przechodzi wszystkie wymagania dotyczące delegowania Kerberos. W debugującej witrynie IIS wyłączono anonimowe uwierzytelnianie i włączone jest uwierzytelnianie systemu Windows.

Udostępniłem dublowanie tych ustawień do witryny obsługującej usługę 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 - Metoda Web

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

Klient 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> 

Application Error

następujący błąd występuje, gdy moja aplikacja testy, aplikacja WinForms, próbuje wywołać metodę WWW:

„Żądanie HTTP jest nieautoryzowany ze klienckiego systemu uwierzytelniania 'Anonymous' . Nagłówek uwierzytelniania otrzymanych od serwera było 'Negocjuj, NTLM' „

dziennik zdarzeń

następujący błąd w dzienniku zdarzeń.

Wyjątek: Systemu .ServiceModel.ServiceActivationException: Usługa "/Service.svc" nie może być aktywowana z powodu wyjątku podczas kompilacji tację. Komunikat wyjątku to: Ustawienia zabezpieczeń dla tej usługi wymagają uwierzytelnienia "Anonimowy", ale nie jest włączone dla aplikacji IIS , która jest hostem tej usługi.

Którego nie rozumiem. Cały punkt tej usługi polega na tym, aby nie zezwalać na anonimowe uwierzytelnianie, każdy użytkownik/żądanie musi być uwierzytelniany przy użyciu biletów Kerberos, a następnie przekazywać je na inne komputery.

Jak skonfigurować tę usługę WCF do uwierzytelniania i delegowania Kerberos?

Przegląd 1

Po przeczytaniu this SO question I usunięte końcowego metadane. To nie rozwiązało problemu.

Revision 2

Po więcej badania znalazłem kilka postów sugerujących zmianę wsHttpBinding do basicHttpBinding. Modyfikacja tej części pliku web.config została zamieszczona poniżej, a punkt końcowy usługi został zaktualizowany w celu odwołania się do tego powiązania. Usługa

WWW - Web Config (poprawiona)

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

Klient App - App Config (poprawiona)

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

Error (Revised)

Prąd Błąd wygląda tak, jakby zawierał autograf Kerberos nagłówek ntication.

Żądanie HTTP jest nieautoryzowany ze schematu uwierzytelniania klienta 'Negocjuj'. Nagłówek uwierzytelniania otrzymanych od serwera było „Negocjuj SOMEHUGESCARYKEYHERE

+1

Uwaga, opublikowałem i usunąłem coś podobnego wczoraj, ten wpis zawiera poprawki oparte na większej ilości badań i powinien być czytelniejszy. – blu

+1

Dodałem zmienioną konfigurację aplikacji na podstawie opinii marc_s. – blu

Odpowiedz

3

coś, co Wskazówka: klient i serwer config nie wydają się zgodni w trybie bezpieczeństwa.

W sekcji oryginalnej masz <security>..... w web.config (pominięto tryb = "wiadomość") i <security mode="Message"> po stronie klienta.

Po edycji wydaje się, że strona klienta pozostała niezmieniona, ale serwer (web.config) zawiera teraz <security mode="TransportCredentialOnly">.

Pytanie brzmi: czy można zagwarantować, że będzie tylko jedna odnoga sieciowa między klientem a serwerem? To znaczy. czy to jest za firmową zaporą ogniową? W takim przypadku, poleciłabym powiązanie netTcp z <security mode="Transport"> na obu końcach.

Jeśli tak nie jest, oznacza to, że możesz korzystać z funkcji wsHttpBinding (która obsługuje więcej funkcji bezpieczeństwa i niezawodności, ale jest wolniejsza i "cięższa") lub basicHttpBinding. W takim przypadku będziesz musiał użyć <security mode="Message"> na obu końcach i uwierzytelnić usługę za pomocą certyfikatu (aby usługa i klient mieli wspólny "tajny" klucz do szyfrowania).

Próbowałbym pominąć części do personifikacji na początek i po prostu najpierw uzyskać podstawową komunikację i wzajemne uwierzytelnianie między usługą a klientem - po jej uruchomieniu można rozpocząć dodawanie do niego bitów podszywania się, i zawsze możesz powrócić do znanej konfiguracji, która działa.

David Sackstein ma great series of blog posts wyjaśniając pięć scenariuszy zabezpieczeń guru przemysł Juval Lowy zidentyfikowała (w jego Programming WCF Book - WCF biblijne) jako najczęściej i najbardziej użyteczne - aby ograniczyć liczbę możliwych kombinacji parametrów możesz zmienić ustawienia. Jednym z nich jest scenariusz "Internetowy", który prawdopodobnie miałby zastosowanie tutaj, jeśli twoja usługa skierowana jest na zewnątrz.

Marc

+1

Dzięki za odpowiedź. Nie uwzględniłem zaktualizowanego kodu klienta, uznałem, że pytanie ma wystarczająco dużo bałaganu, jak jest. Przejdę do podanych przez ciebie informacji, dziękuję. – blu

+1

"uwierzytelnij usługę za pomocą certyfikatu", jest to coś, czego ktoś tutaj próbuje uniknąć. Mieliśmy nadzieję, że będziemy używać prostych biletów Kerberos do uwierzytelniania użytkowników i przekazywania ich do maszyn zaplecza, takich jak SP i SQL. – blu

7

Dla mnie obecna konfiguracja działa:

Na serwerze:

<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> 

Ustaw następujący atrybut wszystkich metod WCF:

[OperationBehavior(Impersonation = ImpersonationOption.Required)] 

Na życzenie klienta:

<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> 

HTH Sven

+1

Co z ustawieniami IIS dla metod uwierzytelniania? Czy dostęp anonimowy jest wyłączony? – Jonathan

+1

Mam włączone uwierzytelnianie systemu Windows i dostęp anonimowy. Ale będziesz potrzebować Anonymous tylko, dodając punkt końcowy mex (IMetadataExchange) dla twojej usługi. –

1

Należy spróbować początkową konfigurację i upewnij się, aby ustawić IIS być anonimowy i okna uwierzytelniania w tej samej przyczyny time.The jest gdy używasz domyślnego wsHttpBinding bezpieczeństwa jest bezpieczeństwo i wiadomość nie zdefiniowano zabezpieczeń transportowych, chyba że chcesz wykonać https. SO Clr stwierdza, że ​​potrzebuje uwierzytelniania anonimowego włączonego w IIS.

2

Musisz określić konfigurację behawioralną w konfiguracji klienta. SVCUtil nie generuje automatycznie. Rozwiązało to mój problem i teraz z powodzeniem używam protokołu Kerberos. To była misja!

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