Delen via


Delegatie en imitatie met WCF

Imitatie is een veelgebruikte techniek die services gebruiken om clienttoegang tot resources van een servicedomein te beperken. Servicedomeinresources kunnen machineresources zijn, zoals lokale bestanden (imitatie) of een resource op een andere computer, zoals een bestandsshare (delegatie). Zie Imitatie van de client voor een voorbeeldtoepassing. Zie Procedure voor een voorbeeld van het gebruik van imitatie : Een client in een service imiteren.

Belangrijk

Houd er rekening mee dat bij het imiteren van een client op een service de service wordt uitgevoerd met de referenties van de client, die mogelijk hogere bevoegdheden hebben dan het serverproces.

Overzicht

Clients roepen doorgaans een service aan om de service namens de client een actie uit te voeren. Met imitatie kan de service fungeren als de client tijdens het uitvoeren van de actie. Met delegering kan een front-endservice de aanvraag van de client doorsturen naar een back-endservice op een zodanige manier dat de back-endservice ook de client kan imiteren. Imitatie wordt meestal gebruikt als een manier om te controleren of een client gemachtigd is om een bepaalde actie uit te voeren, terwijl delegatie een manier is om imitatiemogelijkheden, samen met de identiteit van de client, naar een back-endservice te sturen. Delegering is een Windows-domeinfunctie die kan worden gebruikt wanneer kerberos-verificatie wordt uitgevoerd. Delegering verschilt van de identiteitsstroom en omdat delegering de mogelijkheid om de client zonder het wachtwoord van de client te imiteren, overdraagt, is het een veel hogere bevoorrechte bewerking dan de identiteitsstroom.

Zowel imitatie als delegatie vereisen dat de client een Windows-identiteit heeft. Als een client geen Windows-identiteit heeft, is de enige optie die beschikbaar is om de identiteit van de client door te geven aan de tweede service.

Basisbeginselen van imitatie

Windows Communication Foundation (WCF) ondersteunt imitatie voor verschillende clientreferenties. In dit onderwerp wordt ondersteuning voor servicemodellen beschreven voor het imiteren van de aanroeper tijdens de implementatie van een servicemethode. Ook besproken zijn veelvoorkomende implementatiescenario's met imitatie en SOAP-beveiliging en WCF-opties in deze scenario's.

Dit onderwerp is gericht op imitatie en delegatie in WCF bij het gebruik van SOAP-beveiliging. U kunt ook imitatie en delegatie met WCF gebruiken bij het gebruik van transportbeveiliging, zoals beschreven in imitatie gebruiken met transportbeveiliging.

Twee methoden

WCF SOAP-beveiliging heeft twee verschillende methoden voor het uitvoeren van imitatie. De gebruikte methode is afhankelijk van de binding. Een is imitatie van een Windows-token dat is verkregen via de SSPI-verificatie (Security Support Provider Interface) of Kerberos, die vervolgens in de cache van de service wordt opgeslagen. De tweede is imitatie van een Windows-token dat is verkregen uit de Kerberos-extensies, gezamenlijk Service-for-User (S4U) genoemd.

Tokenimitatie in cache

U kunt imitatie van een token in de cache uitvoeren met het volgende:

Op S4U gebaseerde imitatie

U kunt op S4U gebaseerde imitatie uitvoeren met het volgende:

  • WSHttpBinding, WSDualHttpBindingen NetTcpBinding met een certificaatclientreferentie die de service kan toewijzen aan een geldig Windows-account.

  • Elke CustomBinding toepassing die gebruikmaakt van een Windows-clientreferentie waarbij de requireCancellation eigenschap is ingesteld op false.

  • Elke CustomBinding gebruiker die gebruikmaakt van een gebruikersnaam of Windows-clientreferentie en beveiligd gesprek met de requireCancellation eigenschap ingesteld op false.

De mate waarin de service de client kan imiteren, is afhankelijk van de bevoegdheden die het serviceaccount heeft wanneer het imitatie probeert uit te voeren, het type imitatie dat wordt gebruikt en mogelijk de mate van imitatie die de client toestaat.

Notitie

Wanneer de client en service worden uitgevoerd op dezelfde computer en de client wordt uitgevoerd onder een systeemaccount (bijvoorbeeld Local System of Network Service), kan de client niet worden geïmiteerd wanneer een beveiligde sessie tot stand wordt gebracht met stateful security context tokens. Een Windows-formulier of -consoletoepassing wordt doorgaans uitgevoerd onder het momenteel aangemelde account, zodat het account standaard kan worden geïmiteerd. Wanneer de client echter een ASP.NET pagina is en die pagina wordt gehost in IIS 6.0 of IIS 7.0, wordt de client standaard uitgevoerd onder het Network Service account. Alle door het systeem geleverde bindingen die beveiligde sessies ondersteunen, maken standaard gebruik van een stateless security contexttoken (SCT). Als de client echter een ASP.NET pagina is en beveiligde sessies met stateful SCT's worden gebruikt, kan de client niet worden geïmiteerd. Zie How to: Create a Security Context Token for a Secure Session(s) voor meer informatie over het gebruik van stateful SCT's in een beveiligde sessie.

Imitatie in een servicemethode: declaratief model

De meeste imitatiescenario's omvatten het uitvoeren van de servicemethode in de context van de aanroeper. WCF biedt een imitatiefunctie waarmee deze eenvoudig te doen is doordat de gebruiker de imitatievereiste in het OperationBehaviorAttribute kenmerk kan opgeven. In de volgende code imiteert de WCF-infrastructuur bijvoorbeeld de aanroeper voordat de Hello methode wordt uitgevoerd. Elke poging om toegang te krijgen tot systeemeigen resources binnen de Hello methode slaagt alleen als de toegangsbeheerlijst (ACL) van de resource de toegangsbevoegdheden van de aanroeper toestaat. Als u imitatie wilt inschakelen, stelt u de Impersonation eigenschap in op een van de ImpersonationOption opsommingswaarden, ofwel ImpersonationOption.RequiredImpersonationOption.Allowed, zoals wordt weergegeven in het volgende voorbeeld.

Notitie

Wanneer een service hogere referenties heeft dan de externe client, worden de referenties van de service gebruikt als de Impersonation eigenschap is ingesteld op Allowed. Als een gebruiker met beperkte bevoegdheden zijn referenties verstrekt, voert een service met hogere bevoegdheden de methode uit met de referenties van de service en kan deze resources gebruiken die de gebruiker met beperkte bevoegdheden anders niet zou kunnen gebruiken.

[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

De WCF-infrastructuur kan de beller alleen imiteren als de beller is geverifieerd met referenties die kunnen worden toegewezen aan een Windows-gebruikersaccount. Als de service is geconfigureerd voor verificatie met behulp van een referentie die niet kan worden toegewezen aan een Windows-account, wordt de servicemethode niet uitgevoerd.

Notitie

In Windows XP mislukt imitatie als er een stateful SCT wordt gemaakt, wat resulteert in een InvalidOperationException. Zie Niet-ondersteunde scenario's voor meer informatie.

Imitatie in een servicemethode: Imperatief model

Soms hoeft een aanroeper de hele servicemethode niet te imiteren om te functioneren, maar slechts voor een deel ervan. In dit geval verkrijgt u de Windows-identiteit van de aanroeper binnen de servicemethode en voert u de imitatie impersonatie imperatief uit. Gebruik hiervoor de WindowsIdentity eigenschap van de ServiceSecurityContext eigenschap om een exemplaar van de WindowsIdentity klasse te retourneren en de Impersonate methode aan te roepen voordat u het exemplaar gebruikt.

Notitie

Zorg ervoor dat u de Visual Basic-instructieUsing of de C# using -instructie gebruikt om de imitatieactie automatisch terug te zetten. Als u de instructie niet gebruikt of als u een andere programmeertaal dan Visual Basic of C# gebruikt, moet u het imitatieniveau herstellen. Als u dit niet doet, kan dit de basis vormen voor Denial of Service en uitbreiding van bevoegdhedenaanvallen.

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

Imitatie voor alle servicemethoden

In sommige gevallen moet u alle methoden van een service uitvoeren in de context van de aanroeper. Gebruik de ServiceAuthorizationBehaviorfunctie in plaats van deze functie expliciet per methode in te schakelen. Zoals wordt weergegeven in de volgende code, stelt u de ImpersonateCallerForAllOperations eigenschap in op true. De ServiceAuthorizationBehavior gegevens worden opgehaald uit de verzamelingen gedrag van de ServiceHost klasse. Houd er ook rekening mee dat de eigenschap van de ImpersonationOperationBehaviorAttribute toegepaste methode ook moet worden ingesteld op of AllowedRequired.

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

In de volgende tabel wordt het WCF-gedrag voor alle mogelijke combinaties van ImpersonationOption en ImpersonateCallerForAllServiceOperations.

ImpersonationOption ImpersonateCallerForAllServiceOperations Gedrag
Vereist N.v.t. WCF imiteert de beller
Toegestaan false WCF imiteert de beller niet
Toegestaan true WCF imiteert de beller
Niet toegestaan false WCF imiteert de beller niet
Niet toegestaan true Toegestaan. (Er wordt een InvalidOperationException gegenereerd.)

Imitatieniveau verkregen uit Windows-referenties en tokenimitatie in cache

In sommige scenario's heeft de client gedeeltelijke controle over het imitatieniveau dat de service uitvoert wanneer een Windows-clientreferentie wordt gebruikt. Eén scenario treedt op wanneer de client een anoniem imitatieniveau opgeeft. De andere treedt op bij het uitvoeren van imitatie met een token in de cache. Dit wordt gedaan door de AllowedImpersonationLevel eigenschap van de WindowsClientCredential klasse in te stellen, die wordt geopend als een eigenschap van de algemene ChannelFactory<TChannel> klasse.

Notitie

Als u een imitatieniveau van Anoniem opgeeft, wordt de client anoniem aangemeld bij de service. De service moet daarom anonieme aanmeldingen toestaan, ongeacht of imitatie wordt uitgevoerd.

De client kan het imitatieniveau opgeven als Anonymous, Identificationof ImpersonationDelegation. Alleen een token op het opgegeven niveau wordt geproduceerd, zoals wordt weergegeven in de volgende code.

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 de volgende tabel wordt het imitatieniveau opgegeven dat de service verkrijgt bij het imiteren van een token in de cache.

AllowedImpersonationLevel Waarde Service heeft SeImpersonatePrivilege Service en client kunnen delegatie uitvoeren Token in cache ImpersonationLevel
Anoniem Ja N.v.t. Imitatie
Anoniem Nee N.v.t. Kenmerk
Kenmerk N.v.t. N.v.t. Kenmerk
Imitatie Ja N.v.t. Imitatie
Imitatie Nee N.v.t. Kenmerk
Delegering Ja Ja Delegering
Delegering Ja Nr. Imitatie
Delegering Nee N.v.t. Kenmerk

Imitatieniveau verkregen uit gebruikersnaamreferenties en tokenimitatie in cache

Door de gebruikersnaam en het wachtwoord van de service door te geven, kan WCF zich aanmelden als die gebruiker, wat gelijk is aan het instellen van de AllowedImpersonationLevel eigenschap op Delegation. (De AllowedImpersonationLevel is beschikbaar voor de WindowsClientCredential en HttpDigestClientCredential klassen.) De volgende tabel bevat het imitatieniveau dat is verkregen wanneer de service gebruikersnaamreferenties ontvangt.

AllowedImpersonationLevel Service heeft SeImpersonatePrivilege Service en client kunnen delegatie uitvoeren Token in cache ImpersonationLevel
N.v.t. Ja Ja Delegering
N.v.t. Ja Nr. Imitatie
N.v.t. Nee N.v.t. Kenmerk

Imitatieniveau verkregen uit op S4U gebaseerde imitatie

Service heeft SeTcbPrivilege Service heeft SeImpersonatePrivilege Service en client kunnen delegatie uitvoeren Token in cache ImpersonationLevel
Ja Ja N.v.t. Imitatie
Ja Nee N.v.t. Kenmerk
Nee n.v.t. N.v.t. Kenmerk

Een clientcertificaat toewijzen aan een Windows-account

Het is mogelijk dat een client zichzelf verifieert bij een service met behulp van een certificaat en dat de service de client toewijst aan een bestaand account via Active Directory. In de volgende XML ziet u hoe u de service configureert om het certificaat toe te wijzen.

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

De volgende code laat zien hoe u de service configureert.

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

Delegering

Als u wilt delegeren aan een back-endservice, moet een service Kerberos multi-leg (SSPI zonder NTLM fallback) of Kerberos directe verificatie uitvoeren naar de back-endservice met behulp van de Windows-identiteit van de client. Als u wilt delegeren aan een back-endservice, maakt u een ChannelFactory<TChannel> en een kanaal en communiceert u vervolgens via het kanaal tijdens het imiteren van de client. Met deze vorm van delegatie is de afstand tussen de back-endservice en de front-endservice afhankelijk van het imitatieniveau dat wordt bereikt door de front-endservice. Wanneer het imitatieniveau is Impersonation, moeten de front-end- en back-endservices op dezelfde computer worden uitgevoerd. Wanneer het imitatieniveau is Delegation, kunnen de front-end- en back-endservices zich op afzonderlijke computers of op dezelfde computer bevinden. Voor het inschakelen van imitatie op delegatieniveau moet Windows-domeinbeleid worden geconfigureerd om delegatie toe te staan. Zie Gedelegeerde verificatie inschakelen voor meer informatie over het configureren van Active Directory voor delegeringsondersteuning.

Notitie

Wanneer een client wordt geverifieerd bij de front-endservice met behulp van een gebruikersnaam en wachtwoord die overeenkomen met een Windows-account in de back-endservice, kan de front-endservice worden geverifieerd bij de back-endservice door de gebruikersnaam en het wachtwoord van de client opnieuw te gebruiken. Dit is een bijzonder krachtige vorm van identiteitsstroom, omdat het doorgeven van de gebruikersnaam en het wachtwoord aan de back-endservice de back-endservice in staat stelt imitatie uit te voeren, maar het vormt geen delegatie omdat Kerberos niet wordt gebruikt. Active Directory-besturingselementen voor delegering zijn niet van toepassing op gebruikersnaam- en wachtwoordverificatie.

Mogelijkheid van delegatie als een functie van imitatieniveau

Imitatieniveau Service kan overdracht tussen processen uitvoeren Service kan overdracht tussen machines uitvoeren
Identification Nee No
Impersonation Ja No
Delegation Ja Ja

In het volgende codevoorbeeld ziet u hoe u delegatie gebruikt.

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

Een toepassing configureren voor het gebruik van beperkte delegering

Voordat u beperkte delegering kunt gebruiken, moeten de afzender, ontvanger en de domeincontroller hiervoor zijn geconfigureerd. De volgende procedure bevat de stappen voor het inschakelen van beperkte delegering. Zie het gedeelte van Windows Server 2003 Kerberos-extensies met beperkte discussie voor meer informatie over de verschillen tussen delegatie en beperkte delegering.

  1. Schakel op de domeincontroller het account gevoelig uit en kan niet worden gedelegeerd voor het account waaronder de clienttoepassing wordt uitgevoerd.

  2. Schakel op de domeincontroller het selectievakje Account wordt vertrouwd voor delegatie voor het account waaronder de clienttoepassing wordt uitgevoerd.

  3. Configureer op de domeincontroller de computer in de middelste laag zodat deze wordt vertrouwd voor delegering door te klikken op de optie Vertrouwenscomputer voor delegering .

  4. Configureer op de domeincontroller de computer in de middelste laag voor het gebruik van beperkte delegering door te klikken op de optie Deze computer vertrouwen voor delegering aan opgegeven services .

Zie Kerberos-protocolovergang en beperkte delegering voor meer gedetailleerde instructies over het configureren van beperkte delegering.

Zie ook