Durchführen eines Identitätswechsels für den ClientImpersonating the Client

Das Beispiel für einen Identitätswechsel veranschaulicht, wie die Identität der Aufruferanwendung vom Dienst angenommen wird, sodass der Dienst im Namen des Aufrufers auf Systemressourcen zugreifen kann.The Impersonation sample demonstrates how to impersonate the caller application at the service so that the service can access system resources on behalf of the caller.

Dieses Beispiel basiert auf der Selbsthosting Beispiel.This sample is based on the Self-Host sample. Die Dienst- und Konfigurationsdateien entsprechen, die von der Selbsthosting Beispiel.The service and client configuration files are the same as that of the Self-Host sample.

Hinweis

Die Setupprozedur und die Buildanweisungen für dieses Beispiel befinden sich am Ende dieses Themas.The setup procedure and build instructions for this sample are located at the end of this topic.

Im folgenden Codebeispiel wird gezeigt, dass der Servicecode so geändert wurde, dass die Add-Methode für den Dienst die Identität des Aufrufers mithilfe von OperationBehaviorAttribute annimmt.The service code has been modified such that the Add method on the service impersonates the caller using the OperationBehaviorAttribute as shown in the following sample code.

[OperationBehavior(Impersonation = ImpersonationOption.Required)]  
public double Add(double n1, double n2)  
{  
    double result = n1 + n2;  
    Console.WriteLine("Received Add({0},{1})", n1, n2);  
    Console.WriteLine("Return: {0}", result);  
    DisplayIdentityInformation();  
    return result;  
}  

Demzufolge wird der Sicherheitskontext des ausgeführten Threads so geändert, dass die Identität des Aufrufers angenommen wird, bevor die Add-Methode eingegeben und auf das Beenden der Methode zurückgesetzt wird.As a result, the security context of the executing thread is switched to impersonate the caller before entering the Add method and reverted on exiting the method.

Die im folgenden Codebeispiel veranschaulichte DisplayIdentityInformation-Methode ist eine Hilfsfunktion, mit der die Identität des Aufrufers dargestellt wird.The DisplayIdentityInformation method shown in the following sample code is a utility function that displays the caller's identity.

static void DisplayIdentityInformation()  
{  
    Console.WriteLine("\t\tThread Identity            :{0}",  
         WindowsIdentity.GetCurrent().Name);  
    Console.WriteLine("\t\tThread Identity level  :{0}",   
         WindowsIdentity.GetCurrent().ImpersonationLevel);  
    Console.WriteLine("\t\thToken                     :{0}",  
         WindowsIdentity.GetCurrent().Token.ToString());  
    return;  
}  

Im folgenden Codebeispiel wird gezeigt, dass die Subtract-Methode für den Dienst die Identität des Aufrufers mithilfe von imperativen Aufrufen annimmt.The Subtract method on the service impersonates the caller using imperative calls as shown in the following sample code.

public double Subtract(double n1, double n2)  
{  
    double result = n1 - n2;  
    Console.WriteLine("Received Subtract({0},{1})", n1, n2);  
    Console.WriteLine("Return: {0}", result);  
Console.WriteLine("Before impersonating");  
DisplayIdentityInformation();  

    if (ServiceSecurityContext.Current.WindowsIdentity.ImpersonationLevel == TokenImpersonationLevel.Impersonation ||  
        ServiceSecurityContext.Current.WindowsIdentity.ImpersonationLevel == TokenImpersonationLevel.Delegation)  
    {  
        // Impersonate.  
        using (ServiceSecurityContext.Current.WindowsIdentity.Impersonate())  
        {  
            // Make a system call in the caller's context and ACLs   
            // on the system resource are enforced in the caller's context.   
            Console.WriteLine("Impersonating the caller imperatively");  
            DisplayIdentityInformation();  
        }  
    }  
    else  
    {  
        Console.WriteLine("ImpersonationLevel is not high enough to perform this operation.");  
    }  

Console.WriteLine("After reverting");  
DisplayIdentityInformation();  
    return result;  
}  

Beachten Sie, dass in diesem Fall kein Identitätswechsel für den gesamten Aufruf, sondern nur für einen Teil des Aufrufs vorgenommen wurde.Note that in this case the caller is not impersonated for the entire call but is only impersonated for a portion of the call. Im Allgemeinen empfiehlt es sich, einen Identitätswechsel für den kleinsten Bereich und nicht für den ganzen Vorgang durchzuführen.In general, impersonating for the smallest scope is preferable to impersonating for the entire operation.

Die anderen Methoden nehmen die Identität des Aufrufers nicht an.The other methods do not impersonate the caller.

Der Clientcode wurde geändert, um die Identitätswechselebene auf Impersonation festzulegen.The client code has been modified to set the impersonation level to Impersonation. Der Client gibt die vom Dienst zu verwendende Identitätswechselebene durch die TokenImpersonationLevel-Enumeration an.The client specifies the impersonation level to be used by the service, by using the TokenImpersonationLevel enumeration. Die Enumeration unterstützt die folgenden Werte: None, Anonymous, Identification, Impersonation und Delegation.The enumeration supports the following values: None, Anonymous, Identification, Impersonation and Delegation. Um beim Zugreifen auf die Systemressource auf dem lokalen Rechner, der mit Windows-Zugriffssteuerungslisten geschützt ist, eine Zugriffsprüfung durchzuführen, muss die Identitätswechselebene auf Impersonation festgelegt sein, wie im folgenden Codebeispiel gezeigt.To perform an access check when accessing a system resource on the local machine that is protected using Windows ACLs, the impersonation level must be set to Impersonation, as shown in the following sample code.

// Create a client with given client endpoint configuration  
CalculatorClient client = new CalculatorClient();  

client.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;  

Wenn Sie das Beispiel ausführen, werden die Anforderungen und Antworten für den Vorgang im Dienst- und Clientkonsolenfenster angezeigt.When you run the sample, the operation requests and responses are displayed in both the service and client console windows. Drücken Sie die EINGABETASTE in den einzelnen Konsolenfenstern, um den Dienst und den Client zu schließen.Press ENTER in each console window to shut down the service and client.

Hinweis

Der Dienst muss entweder ausführen unter einem Administratorkonto an, oder das Konto wird, unter wird muss Berechtigungen zum Registrieren der http://localhost:8000/ServiceModelSamples URI mit der HTTP-Ebene.The service must either run under an administrative account or the account it runs under must be granted rights to register the http://localhost:8000/ServiceModelSamples URI with the HTTP layer. Solche Rechte gewährt werden können, durch das Einrichten einer Namespace Reservierung mithilfe der Tools "Httpcfg.exe".Such rights can be granted by setting up a Namespace Reservation using the Httpcfg.exe tool.

Hinweis

Auf Computern mit Windows Server 2003Windows Server 2003 wird der Identitätswechsel nur unterstützt, wenn die Host.exe-Anwendung über eine Berechtigung zum Identitätswechsel verfügt.On computers running Windows Server 2003Windows Server 2003, impersonation is supported only if the Host.exe application has the Impersonation privilege. (Standardmäßig verfügen nur Administratoren über diese Berechtigung.) Um ein Konto mit dieser Berechtigung hinzugefügt haben wie der Dienst ausgeführt wird, wechseln Sie zu Verwaltungöffnen lokale Sicherheitsrichtlinieöffnen lokale Richtlinien, klicken Sie auf Zuweisen von Benutzerrechten, und wählen Sie annehmen der Clientidentität nach Authentifizierung und doppelklicken Sie auf Eigenschaften an einen Benutzer oder Gruppe hinzufügen.(By default, only administrators have this permission.) To add this privilege to an account the service is running as, go to Administrative Tools, open Local Security Policy, open Local Policies, click User Rights Assignment, and select Impersonate a Client after Authentication and double-click Properties to add a user or group.

So können Sie das Beispiel einrichten, erstellen und ausführenTo set up, build, and run the sample

  1. Stellen Sie sicher, dass Sie ausgeführt haben die Setupprozedur für die Windows Communication Foundation-Beispiele zum einmaligen.Ensure that you have performed the One-Time Setup Procedure for the Windows Communication Foundation Samples.

  2. Um die C#- oder Visual Basic .NET-Edition der Projektmappe zu erstellen, befolgen Sie die unter Building the Windows Communication Foundation Samplesaufgeführten Anweisungen.To build the C# or Visual Basic .NET edition of the solution, follow the instructions in Building the Windows Communication Foundation Samples.

  3. Um das Beispiel in einer einzelnen oder computerübergreifenden Konfiguration ausführen möchten, folgen Sie den Anweisungen Ausführen der Windows Communication Foundation-Beispiele.To run the sample in a single- or cross-machine configuration, follow the instructions in Running the Windows Communication Foundation Samples.

  4. Wenn Sie veranschaulichen möchten, dass der Dienst die Identität des Aufrufers annimmt, führen Sie den Client auf einem anderen Konto als dem Konto aus, auf dem der Dienst ausgeführt wird.To demonstrate that the service impersonates the caller, run the client under a different account than the one the service is running under. Geben Sie dazu an der Eingabeaufforderung Folgendes ein:To do so, at the command prompt, type:

    runas /user:<machine-name>\<user-name> client.exe  
    

    Sie werden anschließend zur Eingabe eines Kennworts aufgefordert.You are then prompted for a password. Geben Sie das Kennwort für das Konto ein, das Sie vorher angegeben haben.Enter the password for the account you previously specified.

  5. Wenn Sie den Client ausführen, beachten Sie die Identität vor und nach dem Ausführen mit unterschiedlichen Anmeldeinformationen.When you run the client, note the identity before and after running it with different credentials.

Siehe auchSee Also