Freigeben über


Delegierung und Identitätswechsel mit WCF

Der Identitätswechsel ist eine gängige Technik, mit der Dienste den Clientzugriff auf die Ressourcen einer Dienstdomäne einschränken. Dienstdomänenressourcen können entweder Computerressourcen, wie lokale Dateien (Identitätswechsel), oder eine Ressource auf einem anderen Computer, z. B. eine Dateifreigabe (Delegierung), sein. Sie finden eine Beispielanwendung unter Impersonierung des Clients. Ein Beispiel zur Verwendung von Identitätswechsel finden Sie unter How to: Impersonate a Client on a Service.

Von Bedeutung

Beim Identitätswechsel eines Clients in einem Dienst wird der Dienst mit den Anmeldeinformationen des Clients ausgeführt, die höhere Rechte besitzen können als der Serverprozess.

Überblick

In der Regel rufen Clients einen Dienst auf, damit der Dienst eine Aktion im Auftrag des Clients ausführt. Der Identitätswechsel ermöglicht es dem Dienst, während der Aktion als Client zu fungieren. Delegierung ermöglicht es einem Front-End-Dienst, die Anforderung des Clients an einen Back-End-Dienst so weiterzuleiten, dass der Back-End-Dienst auch die Identität des Clients imitieren kann. Der Identitätswechsel wird am häufigsten als Methode verwendet, um zu überprüfen, ob ein Client berechtigt ist, eine bestimmte Aktion auszuführen, während die Delegierung eine Möglichkeit darstellt, Identitätswechselfunktionen zusammen mit der Identität des Clients an einen Back-End-Dienst zu fließen. Delegierung ist ein Windows-Domänenfeature, das verwendet werden kann, wenn die Kerberos-basierte Authentifizierung ausgeführt wird. Die Delegierung unterscheidet sich vom Identitätsfluss und da die Delegierung die Möglichkeit überträgt, den Client ohne Besitz des Kennworts des Clients zu imitieren, ist es ein wesentlich höher privilegierter Vorgang als der Identitätsfluss.

Sowohl Identitätswechsel als auch Delegierung erfordern, dass der Client über eine Windows-Identität verfügt. Wenn ein Client keine Windows-Identität besitzt, besteht die einzige verfügbare Option darin, die Identität des Clients an den zweiten Dienst zu übergeben.

Grundlagen des Identitätswechsels

Windows Communication Foundation (WCF) unterstützt die Impersonation für eine Vielzahl von Client-Anmeldeinformationen. In diesem Thema wird die Unterstützung des Dienstmodells für die Anrufer-Impersonation während der Implementierung einer Dienstmethode beschrieben. Außerdem werden allgemeine Bereitstellungsszenarien erörtert, die Identitätswechsel und SOAP-Sicherheit sowie WCF-Optionen in diesen Szenarien beinhalten.

Der Schwerpunkt dieses Themas liegt auf dem Identitätswechsel und der Delegierung in WCF bei Verwendung der SOAP-Sicherheit. Sie können den Identitätswechsel und die Delegierung auch mit WCF verwenden, wenn Sie die Transportsicherheit nutzen, wie unter Identitätswechsel und Transportsicherheit beschrieben.

Zwei Methoden

Die WCF SOAP-Sicherheit verfügt über zwei unterschiedliche Methoden zur Durchführung von Impersonation. Die verwendete Methode hängt von der Bindung ab. Die eine Methode besteht im Identitätswechsel von einem Windows-Token aus, das von SSPI (Security Support Provider Interface) oder der Kerberos-Authentifizierung stammt, die dann im Cache des Diensts gespeichert wird. Die zweite Methode besteht im Identitätswechsel von einem Windows-Token aus, das von Kerberos-Erweiterungen stammt, insgesamt als Service-for-User (S4U) bezeichnet.

Identitätswechsel mit im Cache gespeichertem Token

Sie können einen Identitätswechsel mit einem im Cache gespeicherten Token folgendermaßen ausführen:

Auf S4U basierender Identitätswechsel

Sie können S4U-basierte Identitätswechsel mit folgenden Elementen ausführen:

  • WSHttpBinding, WSDualHttpBindingund NetTcpBinding mit zertifikatsbasierten Clientanmeldeinformationen, die der Dienst einem gültigen Windows-Konto zuordnen kann.

  • Mit jeder CustomBinding , die Windows-Clientanmeldeinformationen verwendet, bei denen die requireCancellation -Eigenschaft auf falseeingestellt ist.

  • Mit jeder CustomBinding , die einen Benutzernamen oder Windows-Clientanmeldeinformationen und eine sichere Konversation verwendet, wobei die requireCancellation -Eigenschaft auf falseeingestellt ist.

Der Umfang, in dem der Dienst den Identitätswechsel des Clients ausführen kann, hängt von den Berechtigungen ab, die das Dienstkonto besitzt, wenn es den Identitätswechsel versucht, vom verwendeten Typ des Identitätswechsels und möglicherweise vom Umfang des Identitätswechsels, den der Client zulässt.

Hinweis

Wenn Client und Dienst auf demselben Computer ausgeführt werden und der Client unter einem Systemkonto (z. B. unter Local System oder Network Service) ausgeführt wird, kann kein Clientidentitätswechsel vorgenommen werden, wenn mit Token für den Sicherheitszustandskontext eine Sicherheitsverbindung hergestellt wird. Eine Windows-Form- oder Konsolenanwendung wird in der Regel unter dem aktuell angemeldeten Konto ausgeführt, sodass dieses Konto standardmäßig imitiert wird. Wenn der Client jedoch eine ASP.NET Seite ist und diese Seite in IIS 6.0 oder IIS 7.0 gehostet wird, wird der Client standardmäßig unter dem Network Service Konto ausgeführt. Alle vom System bereitgestellten Bindungen, die sichere Sitzungen unterstützen, verwenden standardmäßig ein zustandsloses Sicherheitskontexttoken (SCT). Wenn es sich bei dem Client jedoch um eine ASP.NET-Seite handelt und sichere Sitzungen mit zustandsbehafteten SCTs verwendet werden, kann kein Clientidentitätswechsel durchgeführt werden. Weitere Informationen zum Verwenden zustandsbehafteter SCTs in einer sicheren Sitzung finden Sie unter How to: Create a Security Context Token for a Secure Session.

Identitätswechsel in einer Dienstmethode: Deklaratives Modell

Die meisten Identitätswechselszenarien umfassen das Ausführen der Dienstmethode im Aufruferkontext. WCF stellt ein Identitätswechselfeature bereit, das dies erleichtert, indem der Benutzer die Identitätswechselanforderung im OperationBehaviorAttribute Attribut angeben kann. Im folgenden Code nimmt die WCF-Infrastruktur beispielsweise die Identität des Anrufers an, bevor sie die Hello-Methode ausführt. Jeder Versuch, auf systemeigene Ressourcen innerhalb der Hello Methode zuzugreifen, ist nur erfolgreich, wenn die Zugriffssteuerungsliste (Access Control List, ACL) der Ressource die Zugriffsberechtigungen des Aufrufers zulässt. Zum Aktivieren des Identitätswechsels legen Sie die Impersonation -Eigenschaft auf einen der ImpersonationOption -Enumerationswerte fest, entweder auf ImpersonationOption.Required oder auf ImpersonationOption.Allowed, wie im folgenden Beispiel dargestellt.

Hinweis

Wenn ein Dienst über höhere Anmeldeinformationen verfügt als der Remote-Client, werden die Anmeldeinformationen des Dienstes verwendet, wenn die Impersonation-Eigenschaft auf Allowed gesetzt ist. Wenn ein Benutzer mit niedriger Berechtigung seine Anmeldeinformationen bereitstellt, führt ein dienst mit höherer Berechtigung die Methode mit den Anmeldeinformationen des Diensts aus und kann Ressourcen verwenden, die der Benutzer mit niedriger Berechtigung andernfalls nicht verwenden kann.

[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

Die WCF-Infrastruktur kann die Identität des Aufrufers nur dann annehmen, wenn der Aufrufer mit Anmeldeinformationen authentifiziert wird, die einem Windows-Benutzerkonto zugeordnet werden können. Wenn der Dienst für die Authentifizierung mithilfe einer Anmeldeinformation konfiguriert ist, die keinem Windows-Konto zugeordnet werden kann, wird die Dienstmethode nicht ausgeführt.

Hinweis

Unter Windows XP schlägt der Identitätswechsel fehl, wenn ein zustandsbehaftetes Sicherheitskontexttoken erstellt wird, was zu einer InvalidOperationException führt. Weitere Informationen finden Sie unter "Nicht unterstützte Szenarien".

Nachahmung in einer Dienstmethode: Imperatives Modell

Mitunter benötigt ein Aufrufer nicht die gesamte Dienstmethode für den Identitätswechsel, sondern nur einen Teil der Methode. In diesem Fall rufen Sie die Windows-Identität des Aufrufers innerhalb der Dienstmethode ab, und führen Sie den Identitätswechsel imperativ durch. Verwenden Sie dazu die WindowsIdentity Eigenschaft der ServiceSecurityContext Klasse, um eine Instanz der WindowsIdentity Klasse zurückzugeben und die Impersonate Methode aufzurufen, bevor Sie die Instanz verwenden.

Hinweis

Stellen Sie sicher, dass Sie die Visual Basic-AnweisungUsing oder die C# using -Anweisung verwenden, um die Identitätswechselaktion automatisch zurückzugeben. Wenn Sie die Anweisung nicht verwenden oder eine andere Programmiersprache als Visual Basic oder C# verwenden, stellen Sie sicher, dass Sie das Impersonation-Level wiederherstellen. Wenn dies nicht getan wird, kann dies die Grundlage für Denial-of-Service- und Erhöhung der Berechtigungen-Angriffe bilden.

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

Identitätswechsel für alle Dienstmethoden

In einigen Fällen müssen Sie alle Methoden eines Diensts im Kontext des Aufrufers ausführen. Verwenden Sie anstelle der expliziten Aktivierung dieses Features pro Methode die ServiceAuthorizationBehavior. Wie im folgenden Code gezeigt, legen Sie die ImpersonateCallerForAllOperations Eigenschaft auf true. Dies ServiceAuthorizationBehavior wird aus den Auflistungen von Verhaltensweisen der ServiceHost Klasse abgerufen. Beachten Sie außerdem, dass die Impersonation Eigenschaft der auf jede Methode angewendeten OperationBehaviorAttribute auf entweder Allowed oder Required festgelegt werden muss.

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

Die folgende Tabelle beschreibt das WCF-Verhalten für alle möglichen Kombinationen von ImpersonationOption und ImpersonateCallerForAllServiceOperations.

ImpersonationOption ImpersonateCallerForAllServiceOperations Verhalten
Erforderlich n/a WCF imitiert den Aufrufer
Zulässig Falsch WCF nimmt die Identität des Aufrufers nicht an
Zulässig Wahr WCF imitiert den Aufrufer
Nicht erlaubt Falsch WCF nimmt die Identität des Aufrufers nicht an
Nicht erlaubt Wahr Unzulässig (Eine InvalidOperationException wird ausgelöst.)

Identitätswechselebene aus Windows-Anmeldeinformationen und Identitätswechsel mit im Cache gespeichertem Token

In einigen Szenarien besitzt der Client eine Teilkontrolle über die Ebene des Identitätswechsels, den der Dienst bei Verwendung von Windows-Clientanmeldeinformationen ausführt. Ein Szenario tritt auf, wenn der Client die Identitätswechselebene "Anonymous" angibt. Ein weiteres Problem tritt auf, wenn eine Nachahmung mit einem zwischengespeicherten Token ausgeführt wird. Dies geschieht durch Festlegen der AllowedImpersonationLevel Eigenschaft der WindowsClientCredential Klasse, auf die als Eigenschaft der generischen ChannelFactory<TChannel> Klasse zugegriffen wird.

Hinweis

Durch Angeben der Identitätswechselebene "Anonymous" meldet sich der Client anonym beim Dienst an. Der Dienst muss daher anonyme Anmeldungen zulassen, unabhängig davon, ob ein Identitätswechsel durchgeführt wird.

Der Client kann die Identitätswechselebene als Anonymous, Identification, Impersonation oder Delegation festlegen. Es wird nur ein Token auf der angegebenen Ebene erstellt, wie im folgenden Code dargestellt.

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

In der folgenden Tabelle wird die Identitätswechselebene angegeben, die der Dienst bei einem Identitätswechsel mit einem im Cache gespeicherten Token erhält.

AllowedImpersonationLevel-Wert Der Dienst hat das SeImpersonatePrivilege Dienst und Client können delegierungsfähig sein ImpersonationLevel
Anonym Ja n/a Nachahmung
Anonym Nein n/a Identifikation
Identifikation n/a n/a Identifikation
Nachahmung Ja n/a Nachahmung
Nachahmung Nein n/a Identifikation
Delegierung Ja Ja Delegierung
Delegierung Ja Nein Nachahmung
Delegierung Nein n/a Identifikation

Identitätswechselebene aus Benutzernamen-Anmeldeinformationen und Identitätswechsel mit im Cache gespeichertem Token

Durch Weitergabe des Benutzernamens und Kennworts an den Dienst ermöglicht ein Client WCF, sich als dieser Benutzer anzumelden, was dem Festlegen der AllowedImpersonationLevel-Eigenschaft auf Delegation entspricht. (AllowedImpersonationLevel ist in den Klassen WindowsClientCredential und HttpDigestClientCredential verfügbar.) Die folgende Tabelle enthält die Ebene des Identitätswechsels, die abgerufen wird, wenn der Dienst Benutzeranmeldeinformationen empfängt.

AllowedImpersonationLevel Der Dienst hat das SeImpersonatePrivilege Dienst und Client können delegierungsfähig sein ImpersonationLevel
n/a Ja Ja Delegierung
n/a Ja Nein Nachahmung
n/a Nein n/a Identifikation

Identitätswechselebene aus einem auf S4U basierenden Identitätswechsel

Der Dienst hat das SeTcbPrivilege Der Dienst hat das SeImpersonatePrivilege Dienst und Client können delegierungsfähig sein ImpersonationLevel
Ja Ja n/a Nachahmung
Ja Nein n/a Identifikation
Nein n/a n/a Identifikation

Zuordnen eines Clientzertifikats zu einem Windows-Konto

Es ist möglich, dass sich ein Client mit einem Zertifikat bei einem Dienst authentifiziert und der Dienst einem vorhandenen Konto über Active Directory zugeordnet wird. Der folgende XML-Code zeigt, wie der Dienst für die Zuordnung des Zertifikats konfiguriert wird.

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

Der folgende Code zeigt, wie der Dienst konfiguriert wird.

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

Delegierung

Um an einen Back-End-Dienst zu delegieren, muss ein Dienst kerberos multi-leg (SSPI ohne NTLM-Fallback) oder die direkte Kerberos-Authentifizierung mit der Windows-Identität des Clients an den Back-End-Dienst ausführen. Um an einen Back-End-Dienst zu delegieren, erstellen Sie einen ChannelFactory<TChannel> und einen Kanal, und kommunizieren Sie dann über den Kanal, indem Sie den Client imitieren. Bei dieser Form der Delegierung hängt die maximale Entfernung zwischen Back-End-Dienst und Front-End-Dienst von der Identitätswechselebene des Front-End-Diensts ab. Wenn die Identitätswechselebene Impersonationfestgelegt wird, müssen Front-End- und Back-End-Dienst auf dem gleichen Computer ausgeführt werden. Wenn die Impersonierungsstufe Delegation lautet, können sich die Front-End- und Back-End-Dienste entweder auf separaten Computern oder auf demselben Computer befinden. Zum Aktivieren des Identitätswechsels auf Delegierungsebene muss die Windows-Domänenrichtlinie so konfiguriert werden, dass die Delegierung zugelassen wird. Weitere Informationen zum Konfigurieren von Active Directory für die Delegierungsunterstützung finden Sie unter Aktivieren der delegierten Authentifizierung.

Hinweis

Wenn ein Client sich beim Front-End-Dienst mithilfe eines Benutzernamens und kennworts authentifiziert, das einem Windows-Konto im Back-End-Dienst entspricht, kann der Front-End-Dienst sich beim Back-End-Dienst authentifizieren, indem er den Benutzernamen und das Kennwort des Clients erneut verwendet. Dies ist eine besonders leistungsfähige Form des Identitätsflusses, da das Übergeben von Benutzername und Kennwort an den Back-End-Dienst ermöglicht, die Nachahmung auszuführen, aber keine Delegierung darstellt, da Kerberos nicht verwendet wird. Active Directory-Steuerelemente für die Delegierung gelten nicht für die Benutzernamen- und Kennwortauthentifizierung.

Delegationsfähigkeit als Funktion der Imitationsebene

Ebene des Identitätswechsels Der Dienst kann prozessübergreifende Delegierungen durchführen. Der Dienst kann eine computerübergreifende Delegierung durchführen.
Identification Nein Nein
Impersonation Ja Nein
Delegation Ja Ja

Im folgenden Codebeispiel wird die Verwendung der Delegierung veranschaulicht.

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

So konfigurieren Sie eine Anwendung für die Verwendung der eingeschränkten Delegierung

Bevor Sie eingeschränkte Delegierung verwenden können, müssen der Absender, der Empfänger und der Domänencontroller dafür konfiguriert werden. Im folgenden Verfahren werden die Schritte aufgeführt, mit denen eingeschränkte Delegierung aktiviert wird. Ausführliche Informationen zu den Unterschieden zwischen Delegierung und eingeschränkter Delegierung finden Sie im Teil von Windows Server 2003-Kerberos-Erweiterungen , der eingeschränkte Diskussionen erläutert.

  1. Deaktivieren Sie auf dem Domänencontroller das Kontrollkästchen Konto ist vertraulich und kann nicht delegiert werden für das Konto, unter dem die Clientanwendung ausgeführt wird.

  2. Aktivieren Sie auf dem Domänencontroller das Kontrollkästchen "Konto ist vertrauenswürdig für delegierung " für das Konto, unter dem die Clientanwendung ausgeführt wird.

  3. Konfigurieren Sie auf dem Domänencontroller den Computer der mittleren Ebene so, dass er für die Delegierung vertrauenswürdig ist, indem Sie auf den Vertrauenswürdigen Computer für die Delegierung klicken.

  4. Konfigurieren Sie auf dem Domänencontroller den Computer der mittleren Ebene so, dass eine eingeschränkte Delegierung verwendet wird, indem Sie die Option Diesem Computer nur für die Delegierung an bestimmte Dienste vertrauen auswählen.

Ausführlichere Anweisungen zum Konfigurieren der eingeschränkten Delegierung finden Sie unter Kerberos-Protokollübergang und eingeschränkte Delegierung.

Siehe auch