Condividi tramite


Delega e rappresentazione con WCF

La rappresentazione è una tecnica comune utilizzata dai servizi per limitare l'accesso dei client alle risorse del dominio del servizio. Tali risorse possono essere risorse del computer, ad esempio file locali (rappresentazione), o risorse in un'altro computer, ad esempio una condivisione file (delega). Per un'applicazione di esempio, vedere Impersonating the Client. Per un esempio di come utilizzare la rappresentazione, vedere Procedura: rappresentare un client in un servizio.

ms730088.Important(it-it,VS.100).gif Nota:
Tenere presente che, in caso di rappresentazione di un client in un servizio, il servizio viene eseguito con le credenziali client, che potrebbero prevedere privilegi più elevati rispetto al processo server.

Cenni preliminari

In genere, i client chiamano un servizio per l’esecuzione di determinate operazioni da parte del servizio stesso per loro conto. La rappresentazione consente al servizio di eseguire azioni per conto del client. La delega consente a un servizio front end di inoltrare le richieste del client ad un servizio back end in modo tale che quest'ultimo possa anche rappresentare il client. La rappresentazione, in genere, viene utilizzata per controllare se un client è autorizzato ad eseguire una particolare azione, mentre la delega è un modo per propagare ad un servizio back end le funzionalità della rappresentazione insieme all'identità del client. La delega è una funzionalità di dominio Windows che può essere utilizzata quando viene eseguita l'autenticazione basata su Kerberos. La delega si differenzia dal flusso dell'identità ed è un'operazione con privilegi maggiori in quanto trasferisce la possibilità di rappresentare il client senza il possesso della relativa password.

Sia la rappresentazione che la delega richiedono che il client abbia una identità di Windows. Se un client non possiede un'identità di Windows, l'unica opzione disponibile è propagare l'identità del client al secondo servizio.

Nozioni fondamentali sulla rappresentazione

Windows Communication Foundation (WCF) supporta la rappresentazione per varie credenziali client. In questo argomento viene descritto il supporto del modello di servizio per la rappresentazione del chiamante durante l'implementazione di un metodo del servizio. Vengono inoltre descritti gli scenari di distribuzione più frequenti che riguardando la rappresentazione e la sicurezza SOAP, nonché le opzioni WCF in tali scenari.

Questo argomento si incentra sulla rappresentazione e la delega in WCF in caso di utilizzo della sicurezza SOAP. È possibile utilizzare la rappresentazione e la delega con WCF anche in caso di utilizzo della sicurezza del trasporto, come descritto in Utilizzo della rappresentazione con la protezione del trasporto.

Due metodi

La sicurezza SOAP in WCF prevede due metodi distinti per eseguire la rappresentazione. Il metodo utilizzato dipende dall'associazione. Il primo consiste nella rappresentazione da un token di Windows ottenuto dall'autenticazione Security Support Provider Interface (SSPI) o Kerberos, che viene quindi memorizzato nella cache del servizio. Il secondo consiste nella rappresentazione da un token di Windows ottenuto dalle estensioni Kerberos, collettivamente denominate Service-for-User (S4U).

Rappresentazione con un token memorizzato nella cache

È possibile eseguire la rappresentazione con un token memorizzato nella cache con gli elementi seguenti:

Rappresentazione basata su S4U.

È possibile eseguire la rappresentazione basata su S4U con gli elementi seguenti:

  • WSHttpBinding, WSDualHttpBinding e NetTcpBinding con una credenziale client basata su certificato di cui il servizio può eseguire il mapping a un account di Windows valido.

  • Qualsiasi CustomBinding che utilizza una credenziale client di Windows con la proprietà requireCancellation impostata su false

  • Qualsiasi CustomBinding che utilizza una credenziale client di Windows o basata sul nome utente e una conversazione protetta con la proprietà requireCancellation impostata su false.

La misura in cui il servizio può eseguire la rappresentazione del client dipende dai privilegi di cui dispone l'account del servizio quando tenta la rappresentazione, dal tipo di rappresentazione utilizzato ed eventualmente dall'ambito di rappresentazione consentito dal client.

ms730088.note(it-it,VS.100).gifNota:
Quando il client e il servizio sono in esecuzione nello stesso computer e il client è in esecuzione con un account del sistema (ad esempio Local System o Network Service), il client non può essere rappresentato quando viene stabilita una sessione protetta con token del contesto di sicurezza con stato. Un'applicazione Windows Form o console viene in genere eseguita con l'account attualmente connesso e quindi l'account può essere rappresentato per impostazione predefinita. Tuttavia, quando il client è una pagina ASP.NET ospitata in IIS 6.0 o IIS 7.0, il client viene eseguito con l'account Network Service per impostazione predefinita. Tutte le associazioni fornite dal sistema che supportano le sessioni protette utilizzano un token del contesto di sicurezza (SCT) senza stato per impostazione predefinita. Tuttavia, se il client è una pagina ASP.NET e si utilizzano sessioni protette con token SCT con stato, non è possibile eseguire la rappresentazione del client. Per ulteriori informazioni su utilizzo di token SCT con stato in una sessione protetta, vedere Procedura: creare un token di contesto di sicurezza per una sessione sicura.

Rappresentazione in un metodo del servizio: modello dichiarativo

La maggior parte degli scenari di rappresentazione implicano l'esecuzione del metodo del servizio nel contesto del chiamante. WCF fornisce una funzionalità di rappresentazione che semplifica questa operazione consentendo all'utente di specificare il requisito di rappresentazione nell'attributo OperationBehaviorAttribute. Ad esempio, nel codice seguente, l'infrastruttura WCF rappresenta il chiamante prima di eseguire il metodo Hello. Qualsiasi tentativo di accedere a risorse native nel metodo Hello ha esito positivo solo se l'elenco di controllo di accesso (ACL) della risorsa consente al chiamante i privilegi di accesso. Per attivare la rappresentazione, impostare la proprietà Impersonation su uno dei valori dell'enumerazione ImpersonationOption, ovvero System.ServiceModel.ImpersonationOption.Required o System.ServiceModel.ImpersonationOption.Allowed, come illustrato nell'esempio seguente.

ms730088.note(it-it,VS.100).gifNota:
Quando un servizio dispone di credenziali più elevate del client remoto, vengono utilizzate le credenziali del servizio se la proprietà Impersonation è impostata su Allowed. In altri termini, se un utente con privilegi di basso livello fornisce le sue credenziali, un servizio con privilegi di livello più elevato esegue il metodo con le credenziali del servizio e può utilizzare risorse che l'utente con privilegi di basso livello non sarebbe altrimenti in grado di utilizzare.

<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 
[ServiceContract]
public interface IHelloContract
{
    [OperationContract]
    string Hello(string message);
}

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

L'infrastruttura WCF può rappresentare il chiamante solo se il chiamante viene autenticato con credenziali di cui è possibile eseguire il mapping a un account utente di Windows. Se il servizio è configurato per l'autenticazione con una credenziale di cui non è possibile eseguire il mapping a un account di Windows, il metodo del servizio non viene eseguito.

ms730088.note(it-it,VS.100).gifNota:
In Windows XP, se viene creato un token SCT con stato, la rappresentazione ha esito negativo, generando InvalidOperationException. Per ulteriori informazioni, vedere Scenari non supportati.

Rappresentazione in un metodo del servizio: modello imperativo

Talvolta, per funzionare, non è necessario che un chiamante rappresenti l'intero metodo del servizio, ma solo una parte. In questo caso, è possibile ottenere l'identità Windows del chiamante nel metodo del servizio ed eseguire la rappresentazione in modo imperativo. A tale scopo, utilizzare la proprietà WindowsIdentity della classe ServiceSecurityContext per restituire un'istanza della classe WindowsIdentity e chiamare il metodo Impersonate prima di utilizzare l'istanza.

ms730088.note(it-it,VS.100).gifNota:
Accertarsi di utilizzare l'istruzione Visual Basic Using o l'istruzione C# using per ripristinare automaticamente l'azione di rappresentazione. Se non si utilizza l'istruzione o se si utilizza un linguaggio di programmazione diverso da Visual Basic o C#, accertarsi di ripristinare il livello di rappresentazione. In caso contrario, si stabilisce la base per attacchi Denial of service e di elevazione del privilegio.

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 
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";
    }
}

Rappresentazione per tutti i metodi del servizio

In alcuni casi, è necessario eseguire tutti i metodi di un servizio nel contesto del chiamante. Anziché attivare in modo esplicito questa funzionalità sulla base di ciascun metodo, utilizzare la classe ServiceAuthorizationBehavior. Impostare la proprietà ImpersonateCallerForAllOperations su true, come illustrato nel codice seguente. La classe ServiceAuthorizationBehavior viene recuperata dalle raccolte di comportamenti della classe ServiceHost. Si noti inoltre che anche la proprietà Impersonation della classe OperationBehaviorAttribute applicata a ogni metodo deve essere impostata su Allowed o Required.

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

Nella tabella seguente viene descritto il comportamento di WCF per tutte le possibili combinazioni di ImpersonationOption e ImpersonateCallerForAllServiceOperations.

ImpersonationOption ImpersonateCallerForAllServiceOperations Behavior

Required

n/d

WCF rappresenta il chiamante

Allowed

false

WCF non rappresenta il chiamante

Allowed

true

WCF rappresenta il chiamante

NotAllowed

false

WCF non rappresenta il chiamante

NotAllowed

true

Non consentita (verrà generata un'eccezione InvalidOperationException).

Livello di rappresentazione ottenuto dalla rappresentazione con credenziali di Windows e con un token memorizzato nella cache

In alcuni scenari il client dispone di un controllo parziale sul livello di rappresentazione eseguito dal servizio quando si utilizza una credenziale client di Windows. Uno scenario si ha quando il client specifica un livello di rappresentazione anonimo, l'altro quando si esegue la rappresentazione con un token memorizzato nella cache. A tale scopo, impostare la proprietà AllowedImpersonationLevel della classe WindowsClientCredential, a cui si accede come proprietà della classe generica ChannelFactory.

ms730088.note(it-it,VS.100).gifNota:
Quando si specifica un livello di rappresentazione anonimo, il client accede al servizio in modo anonimo. Il servizio deve pertanto consentire gli accessi anonimi, indipendentemente dal fatto che venga eseguita o meno la rappresentazione.

Il client può specificare il livello di rappresentazione come Anonymous, Identification, Impersonation o Delegation. Al livello specificato viene prodotto solo un token, come illustrato nel codice seguente.

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

Nella tabella seguente viene indicato il livello di rappresentazione ottenuto dal servizio in caso di rappresentazione da un token memorizzato nella cache.

Valore di AllowedImpersonationLevel Il servizio dispone di SeImpersonatePrivilege Servizio e client con funzionalità di delega ImpersonationLevel con token memorizzato nella cache

Anonymous

n/d

Impersonation

Anonima

No

n/d

Identification

Identification

n/d

n/d

Identification

Impersonation

n/d

Impersonation

Impersonation

No

n/d

Identification

Delegation

Delegation

Delegation

No

Impersonation

Delegation

No

n/d

Identification

Livello di rappresentazione ottenuto dalla rappresentazione con credenziali basate sul nome utente e con un token memorizzato nella cache

Passando al servizio il nome utente e la password, un client consente a WCF di accedere come tale utente, il che equivale a impostare la proprietà AllowedImpersonationLevel su Delegation (la proprietà AllowedImpersonationLevel è disponibile sulle classi WindowsClientCredential e HttpDigestClientCredential). Nella tabella seguente viene indicato il livello di rappresentazione ottenuto quando il servizio riceve credenziali basate sul nome utente.

AllowedImpersonationLevel Il servizio dispone di SeImpersonatePrivilege Servizio e client con funzionalità di delega ImpersonationLevel con token memorizzato nella cache

n/d

Delegation

n/d

No

Impersonation

n/d

No

n/d

Identification

Livello di rappresentazione ottenuto dalla rappresentazione basata su S4U

Il servizio dispone di SeTcbPrivilege Il servizio dispone di SeImpersonatePrivilege Servizio e client con funzionalità di delega ImpersonationLevel con token memorizzato nella cache

n/d

Impersonation

No

n/d

Identification

No

n/d

n/d

Identification

Mapping di un certificato client a un account di Windows

È possibile effettuare l'autenticazione di un client a un servizio tramite un certificato e fare in modo che il servizio esegua il mapping del client a un account esistente tramite Active Directory. Nel codice XML seguente viene illustrato come configurare il servizio affinché esegua il mapping del certificato.

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

Nel codice seguente viene illustrato come configurare il servizio.

// 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("https://localhost/Calculator");
ServiceHost sh = new ServiceHost(typeof(HelloService), httpUri);
sh.Credentials.ClientCertificate.Authentication.MapClientCertificateToWindowsAccount = true;

Delega

Per delegare ad un servizio back end, è necessario che un servizio esegua l'autenticazione multifase Kerberos (SSPI senza fallback NTLM) o l'autenticazione Kerberos diretta ad un servizio back end utilizzando l'identità Windows del client. Per delegare ad un servizio back-end, creare una classe ChannelFactory e un canale, quindi comunicare tramite il canale durante la rappresentazione del client. Con questo tipo di delega, la distanza con la quale deve essere posizionato il servizio back end dal servizio front end dipende dal livello di rappresentazione raggiunto dal servizio front end. Se il livello di rappresentazione è Impersonation, è necessario che i servizi front end e back end vengano eseguiti nello stesso computer. Se il livello di rappresentazione è Delegation, i servizi front end e back end possono essere eseguiti in computer diversi o nello stesso computer. L'attivazione della rappresentazione a livello di delega richiede che, per consentire la delega, i criteri di dominio di Windows siano configurati. Per ulteriori informazioni sulla configurazione di Active Directory per il supporto alla delega, vedere Enabling Delegated Authentication(la pagina potrebbe contenere informazioni in lingua inglese).

ms730088.note(it-it,VS.100).gifNota:
Se il client esegue l'autenticazione al servizio front end utilizzando un nome utente e una password corrispondenti a un account di Windows nel servizio back end, il servizio front end può autenticarsi al servizio back end riutilizzando il nome utente e la password del client. Questa è una forma di flusso di identità particolarmente utile in quanto il trasferimento del nome utente e della password al servizio back-end consente a quest'ultimo di eseguire la rappresentazione, ma non costituisce una delega perché Kerberos non viene utilizzato. I controlli di Active Directory sulla delega non vengono applicati all'autenticazione del nome utente e della password.

Capacità di delega come funzione del livello di rappresentazione.

Livello di rappresentazione Il servizio può eseguire la delega tra processi. Il servizio può eseguire la delega tra computer.

Identification

No

No

Impersonation

No

Delegation

Nell'esempio di codice riportato di seguito viene illustrato come utilizzare la delega.

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("https://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
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("https://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);
        }
    }
}

Procedura: configurare un'applicazione per utilizzare una delega vincolata.

Prima di utilizzare una delega vincolata, è necessario che il mittente, il destinatario e il controller di dominio siano configurati per raggiungere tale obiettivo. La procedura riportata di seguito elenca i passaggi che consentono la delega vincolata. Per ulteriori informazioni sulle differenze tra la delega e la delega vincolata, vedere la parte di Windows Server 2003 Kerberos Extensions che illustra gli argomenti vincolati. (la pagina potrebbe contenere informazioni in lingua inglese).

  1. Nel controller di dominio, cancellare la casella di controllo L'account è sensibile e non può essere delegato selezionata per l'account nel quale viene eseguita l'applicazione del client.

  2. Nel controller di dominio, selezionare la casella di controllo L'account è attendibile per la delega selezionata per l'account nel quale viene eseguita l'applicazione del client.

  3. Nel controller di dominio, configurare il computer di livello intermedio in modo che sia attendibile per la delega facendo clic sull'opzione Computer attendibili per la delega.

  4. Nel controller di dominio, configurare il computer di livello intermedio per l'utilizzo della delega vincolata facendo clic sull'opzione Computer attendibili per la delega solo ai servizi specificati.

Per ulteriori dettagli sulla configurazione della delega vincolata, vedere gli argomenti seguenti su MSDN:

Vedere anche

Attività

Impersonating the Client
Procedura: rappresentare un client in un servizio

Riferimento

OperationBehaviorAttribute
Impersonation
ImpersonationOption
WindowsIdentity
ServiceSecurityContext
WindowsIdentity
ServiceAuthorizationBehavior
ImpersonateCallerForAllOperations
ServiceHost
AllowedImpersonationLevel
WindowsClientCredential
ChannelFactory
Identification

Concetti

Utilizzo della rappresentazione con la protezione del trasporto
Strumento ServiceModel Metadata Utility Tool (Svcutil.exe)