Udostępnij za pośrednictwem


Delegowanie i personifikacja za pomocą programu WCF

Personifikacja jest typową techniką, która używa usług w celu ograniczenia dostępu klienta do zasobów domeny usługi. Zasoby domeny usługi mogą być zasobami komputera, takimi jak pliki lokalne (personifikacja) lub zasób na innym komputerze, taki jak udział plików (delegowanie). Aby zapoznać się z przykładową aplikacją, zobacz Personifikacja klienta. Przykład użycia personifikacji można znaleźć w temacie How to: Impersonate a Client on a Service (Jak personifikować klienta w usłudze).

Ważne

Należy pamiętać, że podczas personifikacji klienta w usłudze usługa jest uruchamiana przy użyciu poświadczeń klienta, które mogą mieć wyższe uprawnienia niż proces serwera.

Omówienie

Zazwyczaj klienci nazywają usługę, aby usługa wykonała jakąś akcję w imieniu klienta. Personifikacja umożliwia usłudze działanie jako klient podczas wykonywania akcji. Delegowanie umożliwia usłudze frontonu przekazywanie żądania klienta do usługi zaplecza w taki sposób, że usługa zaplecza może również personifikować klienta. Personifikacja jest najczęściej używana jako sposób sprawdzania, czy klient jest autoryzowany do wykonania konkretnej akcji, podczas gdy delegowanie jest sposobem przepływu możliwości personifikacji, wraz z tożsamością klienta, do usługi zaplecza. Delegowanie to funkcja domeny systemu Windows, która może być używana podczas uwierzytelniania opartego na protokole Kerberos. Delegowanie różni się od przepływu tożsamości i, ponieważ delegowanie przenosi możliwość personifikacji klienta bez posiadania hasła klienta, jest to znacznie wyższa operacja uprzywilejowana niż przepływ tożsamości.

Zarówno personifikacja, jak i delegowanie wymagają, aby klient miał tożsamość systemu Windows. Jeśli klient nie ma tożsamości systemu Windows, jedyną dostępną opcją jest przepływ tożsamości klienta do drugiej usługi.

Podstawy personifikacji

Program Windows Communication Foundation (WCF) obsługuje personifikację dla różnych poświadczeń klienta. W tym temacie opisano obsługę modelu usług w celu personifikacji obiektu wywołującego podczas implementacji metody usługi. Omówione są również typowe scenariusze wdrażania obejmujące personifikację oraz opcje zabezpieczeń protokołu SOAP i WCF w tych scenariuszach.

Ten temat koncentruje się na personifikacji i delegowaniu w programie WCF podczas korzystania z zabezpieczeń protokołu SOAP. Podczas korzystania z zabezpieczeń transportu można również użyć personifikacji i delegowania w programie WCF, zgodnie z opisem w temacie Using Impersonation with Transport Security (Używanie personifikacji z zabezpieczeniami transportu).

Dwie metody

Zabezpieczenia protokołu WCF SOAP mają dwie odrębne metody personifikacji. Użyta metoda zależy od powiązania. Jednym z nich jest personifikacja z tokenu systemu Windows uzyskanego z uwierzytelniania SSPI (Security Support Provider Interface) lub Kerberos, który jest następnie buforowany w usłudze. Drugi to personifikacja z tokenu systemu Windows uzyskanego z rozszerzeń Protokołu Kerberos, zbiorczo nazywanych service-for-User (S4U).

Personifikacja buforowanego tokenu

Możesz wykonać personifikację buforowanego tokenu przy użyciu następujących elementów:

Personifikacja oparta na protokole S4U

Personifikację opartą na protokole S4U można wykonać przy użyciu następujących elementów:

  • WSHttpBinding, WSDualHttpBindingi NetTcpBinding przy użyciu poświadczeń klienta certyfikatu, które usługa może mapować na prawidłowe konto systemu Windows.

  • Każdy CustomBinding , który używa poświadczeń klienta systemu Windows z właściwością ustawioną requireCancellation na false.

  • Każda CustomBinding , która używa nazwy użytkownika lub poświadczeń klienta systemu Windows i zabezpiecza konwersację z właściwością ustawioną requireCancellation na false.

Zakres, w jakim usługa może personifikować klienta, zależy od uprawnień, które posiada konto usługi podczas próby personifikacji, typu personifikacji użytej i ewentualnie zakresu personifikacji, na którą zezwala klient.

Uwaga

Gdy klient i usługa są uruchomione na tym samym komputerze, a klient jest uruchomiony na koncie systemowym (na przykład Local System lub Network Service), klient nie może być personifikowany, gdy zostanie nawiązana bezpieczna sesja z stanowymi tokenami kontekstu zabezpieczeń. Formularz systemu Windows lub aplikacja konsolowa zazwyczaj działa na aktualnie zalogowanym koncie, dzięki czemu konto może być domyślnie personifikowane. Jeśli jednak klient jest stroną ASP.NET, a ta strona jest hostowana w usługach IIS 6.0 lub IIS 7.0, klient działa domyślnie na Network Service koncie. Wszystkie powiązania dostarczone przez system, które obsługują bezpieczne sesje, domyślnie używają bezstanowego tokenu kontekstu zabezpieczeń (SCT). Jeśli jednak klient jest stroną ASP.NET, a używane są bezpieczne sesje ze stanowymi scTs, nie można personifikować klienta. Aby uzyskać więcej informacji na temat używania stanowych scTs w bezpiecznej sesji, zobacz Instrukcje: tworzenie tokenu kontekstu zabezpieczeń na potrzeby bezpiecznej sesji.

Personifikacja w metodzie usługi: model deklaratywny

Większość scenariuszy personifikacji obejmuje wykonywanie metody usługi w kontekście wywołującego. Program WCF udostępnia funkcję personifikacji, która ułatwia wykonanie tej czynności, umożliwiając użytkownikowi określenie wymagania personifikacji w atrybucie OperationBehaviorAttribute . Na przykład w poniższym kodzie infrastruktura WCF personifikuje obiekt wywołujący przed wykonaniem Hello metody. Każda próba uzyskania dostępu do zasobów natywnych wewnątrz Hello metody powiedzie się tylko wtedy, gdy lista kontroli dostępu (ACL) zasobu zezwala na uprawnienia dostępu wywołującego. Aby włączyć personifikację Impersonation , ustaw właściwość na jedną z ImpersonationOption wartości wyliczenia lub ImpersonationOption.RequiredImpersonationOption.Allowed, jak pokazano w poniższym przykładzie.

Uwaga

Jeśli usługa ma wyższe poświadczenia niż klient zdalny, poświadczenia usługi są używane, jeśli Impersonation właściwość jest ustawiona na Allowed. Oznacza to, że jeśli użytkownik o niskich uprawnieniach udostępnia swoje poświadczenia, usługa z wyższymi uprawnieniami wykonuje metodę z poświadczeniami usługi i może używać zasobów, których użytkownik o niskich uprawnieniach w przeciwnym razie nie będzie mógł używać.

[ServiceContract]
public interface IHelloContract
{
    [OperationContract]
    string Hello(string message);
}

public class HelloService : IHelloService
{
    [OperationBehavior(Impersonation = ImpersonationOption.Required)]
    public string Hello(string message)
    {
        return "hello";
    }
}

<ServiceContract()> _
Public Interface IHelloContract
    <OperationContract()> _
    Function Hello(ByVal message As String) As String
End Interface


Public Class HelloService
    Implements IHelloService

    <OperationBehavior(Impersonation:=ImpersonationOption.Required)> _
    Public Function Hello(ByVal message As String) As String Implements IHelloService.Hello
        Return "hello"
    End Function
End Class

Infrastruktura WCF może personifikować obiekt wywołujący tylko wtedy, gdy obiekt wywołujący jest uwierzytelniany przy użyciu poświadczeń, które można zamapować na konto użytkownika systemu Windows. Jeśli usługa jest skonfigurowana do uwierzytelniania przy użyciu poświadczeń, których nie można zamapować na konto systemu Windows, metoda usługi nie jest wykonywana.

Uwaga

W systemie Windows XP personifikacja kończy się niepowodzeniem w przypadku utworzenia stanowego SCT, co powoduje wystąpienie błędu InvalidOperationException. Aby uzyskać więcej informacji, zobacz Nieobsługiwane scenariusze.

Personifikacja w metodzie usługi: Model imperatywne

Czasami obiekt wywołujący nie musi personifikować całej metody usługi do działania, ale tylko dla części. W takim przypadku uzyskaj tożsamość systemu Windows obiektu wywołującego wewnątrz metody usługi i imperatywnie wykonaj personifikację. W tym celu należy użyć WindowsIdentity właściwości , ServiceSecurityContext aby zwrócić wystąpienie WindowsIdentity klasy i wywołać Impersonate metodę przed użyciem wystąpienia.

Uwaga

Pamiętaj, aby automatycznie przywrócić akcję personifikacji przy użyciu instrukcji Visual BasicUsing lub instrukcji języka C# using . Jeśli nie używasz instrukcji lub jeśli używasz języka programowania innego niż Visual Basic lub C#, pamiętaj, aby przywrócić poziom personifikacji. Wykonanie tej czynności może stanowić podstawę ataków typu "odmowa usługi" i "podniesienie uprawnień".

public class HelloService : IHelloService
{
    [OperationBehavior]
    public string Hello(string message)
    {
        WindowsIdentity callerWindowsIdentity =
        ServiceSecurityContext.Current.WindowsIdentity;
        if (callerWindowsIdentity == null)
        {
            throw new InvalidOperationException
           ("The caller cannot be mapped to a WindowsIdentity");
        }
        using (callerWindowsIdentity.Impersonate())
        {
            // Access a file as the caller.
        }
        return "Hello";
    }
}
Public Class HelloService
    Implements IHelloService

    <OperationBehavior()> _
    Public Function Hello(ByVal message As String) As String _
       Implements IHelloService.Hello
        Dim callerWindowsIdentity As WindowsIdentity = _
            ServiceSecurityContext.Current.WindowsIdentity
        If (callerWindowsIdentity Is Nothing) Then
            Throw New InvalidOperationException( _
              "The caller cannot be mapped to a WindowsIdentity")
        End If
        Dim cxt As WindowsImpersonationContext = callerWindowsIdentity.Impersonate()
        Using (cxt)
            ' Access a file as the caller.
        End Using

        Return "Hello"

    End Function
End Class

Personifikacja dla wszystkich metod usługi

W niektórych przypadkach należy wykonać wszystkie metody usługi w kontekście obiektu wywołującego. Zamiast jawnie włączać tę funkcję dla poszczególnych metod, użyj elementu ServiceAuthorizationBehavior. Jak pokazano w poniższym kodzie, ustaw ImpersonateCallerForAllOperations właściwość na true. Element ServiceAuthorizationBehavior jest pobierany z kolekcji zachowań ServiceHost klasy . Należy również pamiętać, że Impersonation właściwość OperationBehaviorAttribute zastosowana do każdej metody musi być również ustawiona na Allowed wartość lub Required.

// Code to create a ServiceHost not shown.
ServiceAuthorizationBehavior MyServiceAuthorizationBehavior =
    serviceHost.Description.Behaviors.Find<ServiceAuthorizationBehavior>();
MyServiceAuthorizationBehavior.ImpersonateCallerForAllOperations = true;
' Code to create a ServiceHost not shown.
Dim MyServiceAuthorizationBehavior As ServiceAuthorizationBehavior
MyServiceAuthorizationBehavior = serviceHost.Description.Behaviors.Find _
(Of ServiceAuthorizationBehavior)()
MyServiceAuthorizationBehavior.ImpersonateCallerForAllOperations = True

W poniższej tabeli opisano zachowanie WCF dla wszystkich możliwych kombinacji elementów ImpersonationOption i ImpersonateCallerForAllServiceOperations.

ImpersonationOption ImpersonateCallerForAllServiceOperations Zachowanie
Wymagania nie dotyczy Program WCF personifikuje obiekt wywołujący
Dozwolone fałsz Program WCF nie personifikuje elementu wywołującego
Dozwolone prawda Program WCF personifikuje obiekt wywołujący
Notallowed fałsz Program WCF nie personifikuje elementu wywołującego
Notallowed prawda Niedozwolone. (Zgłaszana InvalidOperationException jest wartość).

Poziom personifikacji uzyskany z poświadczeń systemu Windows i personifikacja buforowanego tokenu

W niektórych scenariuszach klient ma częściową kontrolę nad poziomem personifikacji usługi wykonywanej po użyciu poświadczeń klienta systemu Windows. Jeden scenariusz występuje, gdy klient określa poziom personifikacji anonimowej. Drugi występuje podczas personifikacji za pomocą buforowanego tokenu. W tym celu należy ustawić AllowedImpersonationLevel właściwość WindowsClientCredential klasy, która jest dostępna jako właściwość klasy ogólnej ChannelFactory<TChannel> .

Uwaga

Określenie poziomu personifikacji anonimowego powoduje, że klient loguje się anonimowo do usługi. W związku z tym usługa musi zezwalać na logowanie anonimowe, niezależnie od tego, czy jest wykonywane personifikacja.

Klient może określić poziom personifikacji jako Anonymous, , IdentificationImpersonationlub Delegation. Generowany jest tylko token na określonym poziomie, jak pokazano w poniższym kodzie.

ChannelFactory<IEcho> cf = new ChannelFactory<IEcho>("EchoEndpoint");
cf.Credentials.Windows.AllowedImpersonationLevel  =
    System.Security.Principal.TokenImpersonationLevel.Impersonation;
Dim cf As ChannelFactory(Of IEcho) = New ChannelFactory(Of IEcho)("EchoEndpoint")
cf.Credentials.Windows.AllowedImpersonationLevel = _
System.Security.Principal.TokenImpersonationLevel.Impersonation

W poniższej tabeli określono poziom personifikacji, który usługa uzyskuje podczas personifikacji z buforowanego tokenu.

AllowedImpersonationLevel Wartość Usługa ma SeImpersonatePrivilege Usługa i klient mogą delegowanie Token buforowany ImpersonationLevel
Anonimowe Tak nie dotyczy Personifikacja
Anonimowe Nie. nie dotyczy Identyfikator
Identyfikator nie dotyczy nie dotyczy Identyfikator
Personifikacja Tak nie dotyczy Personifikacja
Personifikacja Nie. nie dotyczy Identyfikator
Delegowanie Tak Tak Delegowanie
Delegowanie Tak Nie. Personifikacja
Delegowanie Nie. nie dotyczy Identyfikator

Poziom personifikacji uzyskany z poświadczeń nazwy użytkownika i personifikacji tokenu w pamięci podręcznej

Przekazując usługę jej nazwę użytkownika i hasło, klient umożliwia programowi WCF logowanie się jako ten użytkownik, co jest równoważne ustawieniu AllowedImpersonationLevel właściwości na Delegation. (Parametr AllowedImpersonationLevel jest dostępny w klasach WindowsClientCredential i HttpDigestClientCredential ). W poniższej tabeli przedstawiono poziom personifikacji uzyskany po otrzymaniu poświadczeń nazwy użytkownika przez usługę.

AllowedImpersonationLevel Usługa ma SeImpersonatePrivilege Usługa i klient mogą delegowanie Token buforowany ImpersonationLevel
nie dotyczy Tak Tak Delegowanie
nie dotyczy Tak Nie. Personifikacja
nie dotyczy Nie. nie dotyczy Identyfikator

Poziom personifikacji uzyskany z personifikacji opartej na S4U

Usługa ma SeTcbPrivilege Usługa ma SeImpersonatePrivilege Usługa i klient mogą delegowanie Token buforowany ImpersonationLevel
Tak Tak nie dotyczy Personifikacja
Tak Nie nie dotyczy Identyfikator
Nie. nie dotyczy nie dotyczy Identyfikator

Mapowanie certyfikatu klienta na konto systemu Windows

Klient może uwierzytelnić się w usłudze przy użyciu certyfikatu i zamapować klienta na istniejące konto za pośrednictwem usługi Active Directory. Poniższy kod XML pokazuje, jak skonfigurować usługę do mapowania certyfikatu.

<behaviors>  
  <serviceBehaviors>  
    <behavior name="MapToWindowsAccount">  
      <serviceCredentials>  
        <clientCertificate>  
          <authentication mapClientCertificateToWindowsAccount="true" />  
        </clientCertificate>  
      </serviceCredentials>  
    </behavior>  
  </serviceBehaviors>  
</behaviors>  

Poniższy kod pokazuje, jak skonfigurować usługę.

// Create a binding that sets a certificate as the client credential type.  
WSHttpBinding b = new WSHttpBinding();  
b.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;  
  
// Create a service host that maps the certificate to a Windows account.  
Uri httpUri = new Uri("http://localhost/Calculator");  
ServiceHost sh = new ServiceHost(typeof(HelloService), httpUri);  
sh.Credentials.ClientCertificate.Authentication.MapClientCertificateToWindowsAccount = true;  

Delegowanie

Aby delegować do usługi zaplecza, usługa musi wykonać uwierzytelnianie wieloczęściowe Protokołu Kerberos (SSPI bez rezerwowego protokołu NTLM) lub bezpośrednie uwierzytelnianie Kerberos w usłudze zaplecza przy użyciu tożsamości klienta systemu Windows. Aby delegować do usługi zaplecza, utwórz ChannelFactory<TChannel> kanał i, a następnie przekaż za pośrednictwem kanału podczas personifikacji klienta. W przypadku tej formy delegowania odległość, od której można znaleźć usługę zaplecza z usługi frontonu, zależy od poziomu personifikacji osiągniętego przez usługę frontonu. Gdy poziom personifikacji to Impersonation, usługi frontonu i zaplecza muszą być uruchomione na tej samej maszynie. Gdy poziom personifikacji to Delegation, usługi frontonu i zaplecza mogą znajdować się na oddzielnych maszynach lub na tym samym komputerze. Włączenie personifikacji na poziomie delegowania wymaga skonfigurowania zasad domeny systemu Windows w celu zezwolenia na delegowanie. Aby uzyskać więcej informacji na temat konfigurowania usługi Active Directory na potrzeby obsługi delegowania, zobacz Włączanie uwierzytelniania delegowanego.

Uwaga

Gdy klient uwierzytelnia się w usłudze frontonu przy użyciu nazwy użytkownika i hasła odpowiadającego kontu systemu Windows w usłudze zaplecza, usługa frontonu może uwierzytelniać się w usłudze zaplecza, ponownie używając nazwy użytkownika i hasła klienta. Jest to szczególnie zaawansowana forma przepływu tożsamości, ponieważ przekazywanie nazwy użytkownika i hasła do usługi zaplecza umożliwia usłudze zaplecza wykonywanie personifikacji, ale nie stanowi delegowania, ponieważ protokół Kerberos nie jest używany. Kontrolki usługi Active Directory dotyczące delegowania nie mają zastosowania do nazwy użytkownika i uwierzytelniania haseł.

Umiejętność delegowania jako funkcja poziomu personifikacji

Poziom personifikacji Usługa może wykonywać delegowanie między procesami Usługa może wykonywać delegowanie między maszynami
Identification Nie Nie.
Impersonation Tak Nie
Delegation Tak Tak

W poniższym przykładzie kodu pokazano, jak używać delegowania.

public class HelloService : IHelloService
{
    [OperationBehavior(Impersonation = ImpersonationOption.Required)]
    public string Hello(string message)
    {
        WindowsIdentity callerWindowsIdentity = ServiceSecurityContext.Current.WindowsIdentity;
        if (callerWindowsIdentity == null)
        {
            throw new InvalidOperationException
             ("The caller cannot be mapped to a Windows identity.");
        }
        using (callerWindowsIdentity.Impersonate())
        {
            EndpointAddress backendServiceAddress = new EndpointAddress("http://localhost:8000/ChannelApp");
            // Any binding that performs Windows authentication of the client can be used.
            ChannelFactory<IHelloService> channelFactory = new ChannelFactory<IHelloService>(new NetTcpBinding(), backendServiceAddress);
            IHelloService channel = channelFactory.CreateChannel();
            return channel.Hello(message);
        }
    }
}
Public Class HelloService
    Implements IHelloService

    <OperationBehavior(Impersonation:=ImpersonationOption.Required)> _
    Public Function Hello(ByVal message As String) As String Implements IHelloService.Hello
        Dim callerWindowsIdentity As WindowsIdentity = ServiceSecurityContext.Current.WindowsIdentity
        If (callerWindowsIdentity Is Nothing) Then
            Throw New InvalidOperationException("The caller cannot be mapped to a Windows identity.")
        End If

        Dim backendServiceAddress As EndpointAddress = New EndpointAddress("http://localhost:8000/ChannelApp")
        ' Any binding that performs Windows authentication of the client can be used.
        Dim channelFactory As ChannelFactory(Of IHelloService) = _
          New ChannelFactory(Of IHelloService)(New NetTcpBinding(), backendServiceAddress)
        Dim channel As IHelloService = channelFactory.CreateChannel()
        Return channel.Hello(message)
    End Function
End Class

Jak skonfigurować aplikację do używania ograniczonego delegowania

Aby można było użyć ograniczonego delegowania, nadawca, odbiornik i kontroler domeny muszą być skonfigurowane w tym celu. Poniższa procedura zawiera listę kroków, które umożliwiają ograniczone delegowanie. Aby uzyskać szczegółowe informacje na temat różnic między delegowaniem a delegowaniem ograniczonym, zobacz część rozszerzeń Protokołu Kerberos systemu Windows Server 2003, które omawiają ograniczone dyskusje.

  1. Na kontrolerze domeny wyczyść pole wyboru Konto jest poufne i nie można go delegować dla konta, w którym działa aplikacja kliencka.

  2. Na kontrolerze domeny zaznacz pole wyboru Konto jest zaufane dla delegowania dla konta, w którym działa aplikacja kliencka.

  3. Na kontrolerze domeny skonfiguruj komputer warstwy środkowej, aby był zaufany dla delegowania, klikając opcję Ufaj komputerowi na potrzeby delegowania .

  4. Na kontrolerze domeny skonfiguruj komputer warstwy środkowej tak, aby używał ograniczonego delegowania, klikając opcję Ufaj temu komputerowi dla delegowania tylko do określonych usług.

Aby uzyskać bardziej szczegółowe instrukcje dotyczące konfigurowania ograniczonego delegowania, zobacz Przejście protokołu Kerberos i ograniczone delegowanie.

Zobacz też