Condividi tramite


Procedura: creare un gestore autorizzazioni personalizzato per un servizio

L'infrastruttura dei modelli di identità di Windows Communication Foundation (WCF) supporta un modello di autorizzazione basato su attestazioni estensibili. Le attestazioni vengono estratte dai token, elaborate facoltativamente da criteri di autorizzazione personalizzati e quindi inserite in una classe AuthorizationContext. Un gestore autorizzazioni esamina le attestazioni contenute nel contesto AuthorizationContext per prendere decisioni di autorizzazione.

Per impostazione predefinita, le decisioni di autorizzazione sono prese dalla classe ServiceAuthorizationManager. È tuttavia possibile creare un gestore autorizzazioni personalizzato per eseguire l'override di queste decisioni. Per creare un gestore autorizzazioni personalizzato, creare una classe che deriva da ServiceAuthorizationManager e che implementa il metodo CheckAccessCore. Le decisioni di autorizzazione sono prese tramite il metodo CheckAccessCore che restituisce true quando l'accesso è concesso e false quando l'accesso è negato.

Se la decisione di autorizzazione dipende dal contenuto del corpo del messaggio, utilizzare il metodo CheckAccess.

A causa di problemi riguardanti le prestazioni, è consigliabile ridisegnare l'applicazione, se possibile, in modo tale che per la decisione di autorizzazione non sia necessario l'accesso al corpo del messaggio.

La registrazione del gestore autorizzazioni personalizzato per un servizio può essere eseguita in codice o in configurazione.

Per creare un gestore autorizzazioni personalizzato

  1. Derivare una classe dalla classe ServiceAuthorizationManager.

    Public Class MyServiceAuthorizationManager
        Inherits ServiceAuthorizationManager
    
    
    public class MyServiceAuthorizationManager : ServiceAuthorizationManager
    {
    
  2. Eseguire l'override del metodo CheckAccessCore.

    Utilizzare il contesto OperationContext passato al metodo CheckAccessCore per prendere decisioni di autorizzazione.

    Nell'esempio di codice seguente il metodo FindClaims viene utilizzato per individuare l'attestazione personalizzata https://www.contoso.com/claims/allowedoperation allo scopo di prendere una decisione di autorizzazione.

    Protected Overrides Function CheckAccessCore(ByVal operationContext As OperationContext) As Boolean 
        ' Extract the action URI from the OperationContext. Match this against the claims.
        ' in the AuthorizationContext.
        Dim action As String = operationContext.RequestContext.RequestMessage.Headers.Action
    
        ' Iterate through the various claimsets in the AuthorizationContext.
        Dim cs As ClaimSet
        For Each cs In  operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets
            ' Examine only those claim sets issued by System.
            If cs.Issuer Is ClaimSet.System Then
                ' Iterate through claims of type "https://www.contoso.com/claims/allowedoperation".
                Dim c As Claim
                For Each c In  cs.FindClaims("https://www.contoso.com/claims/allowedoperation", _
                     Rights.PossessProperty)
                    ' If the Claim resource matches the action URI then return true to allow access.
                    If action = c.Resource.ToString() Then
                        Return True
                    End If
                Next c
            End If
        Next cs 
        ' If this point is reached, return false to deny access.
        Return False
    
    End Function 
    
    protected override bool CheckAccessCore(OperationContext operationContext)
    {                
      // Extract the action URI from the OperationContext. Match this against the claims
      // in the AuthorizationContext.
      string action = operationContext.RequestContext.RequestMessage.Headers.Action;
    
      // Iterate through the various claim sets in the AuthorizationContext.
      foreach(ClaimSet cs in operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets)
      {
        // Examine only those claim sets issued by System.
        if (cs.Issuer == ClaimSet.System)
        {
          // Iterate through claims of type "https://www.contoso.com/claims/allowedoperation".
            foreach (Claim c in cs.FindClaims("https://www.contoso.com/claims/allowedoperation", Rights.PossessProperty))
          {
            // If the Claim resource matches the action URI then return true to allow access.
            if (action == c.Resource.ToString())
              return true;
          }
        }
      }
    
      // If this point is reached, return false to deny access.
      return false;                 
    }
    

Per registrare un gestore autorizzazioni personalizzato in codice

  1. Creare un'istanza del gestore autorizzazioni personalizzato e assegnarla alla proprietà ServiceAuthorizationManager.

    Per accedere al comportamento ServiceAuthorizationBehavior è possibile utilizzare la proprietà Authorization.

    Nell'esempio di codice seguente viene illustrato come registrare il gestore autorizzazioni personalizzato MyServiceAuthorizationManager.

    ' Add a custom authorization manager to the service authorization behavior.
    serviceHost.Authorization.ServiceAuthorizationManager = _
        New MyServiceAuthorizationManager()
    
    // Add a custom authorization manager to the service authorization behavior.
    serviceHost.Authorization.ServiceAuthorizationManager = 
               new MyServiceAuthorizationManager();
    

Per registrare un gestore autorizzazioni personalizzato in configurazione

  1. Aprire il file di configurazione del servizio.

  2. Aggiungere un serviceAuthorization element all'Behaviors element.

    Aggiungere un attributo serviceAuthorizationManagerType all'serviceAuthorization element e quindi impostare il valore di tale attributo sul tipo che rappresenta il gestore autorizzazioni personalizzato.

  3. Aggiungere un'associazione in grado di proteggere la comunicazione tra client e servizio.

    L'associazione scelta per questa comunicazione determina le attestazioni aggiunte al contesto AuthorizationContext utilizzate dal gestore autorizzazioni personalizzato per prendere le decisioni di autorizzazione. Per ulteriori dettagli sulle associazioni fornite dal sistema, vedere Associazioni fornite dal sistema.

  4. Associare il comportamento a un endpoint di servizio aggiungendo un elemento <service>behaviorConfiguration e quindi impostare il valore dell'attributo <behavior> of <serviceBehaviors> sul valore dell'attributo nome dell'elemento.

    Per ulteriori informazioni sulla configurazione di un endpoint di servizio, vedere Procedura: creare un endpoint di servizio nella configurazione.

    Nell'esempio di codice seguente viene illustrato come registrare il gestore autorizzazioni personalizzato Samples.MyServiceAuthorizationManager.

    <configuration>
      <system.serviceModel>
        <services>
          <service 
              name="Microsoft.ServiceModel.Samples.CalculatorService"
              behaviorConfiguration="CalculatorServiceBehavior">
            <host>
              <baseAddresses>
                <add baseAddress="https://localhost:8000/ServiceModelSamples/service"/>
              </baseAddresses>
            </host>
            <endpoint address=""
                      binding="wsHttpBinding_Calculator"
                      contract="Microsoft.ServiceModel.Samples.ICalculator" />
          </service>
        </services>
        <bindings>
          <WSHttpBinding>
           <binding name = "wsHttpBinding_Calculator">
             <security mode="Message">
               <message clientCredentialType="Windows"/>
             </security>
            </binding>
          </WSHttpBinding>
    </bindings>
        <behaviors>
          <serviceBehaviors>
            <behavior name="CalculatorServiceBehavior">
              <serviceAuthorization serviceAuthorizationManagerType="Samples.MyServiceAuthorizationManager" />
            </behaviors>
          </serviceBehaviors>
        </behaviors>
      </system.serviceModel>
    </configuration>
    

Esempio

Nell'esempio di codice seguente viene descritta un'implementazione di base di una classe ServiceAuthorizationManager che prevede l'override del metodo CheckAccessCore. Nell'esempio di codice viene eseguita una ricerca all'interno del contesto AuthorizationContext allo scopo di individuare un'attestazione personalizzata e quindi viene restituito true quando la risorsa relativa a tale attestazione personalizzata corrisponde al valore di azione indicato nel contesto OperationContext. Per un'implementazione più completa di una classe ServiceAuthorizationManager, vedere Criteri di autorizzazione.

Public Class MyServiceAuthorizationManager
    Inherits ServiceAuthorizationManager
    
    Protected Overrides Function CheckAccessCore(ByVal operationContext As OperationContext) As Boolean 
        ' Extract the action URI from the OperationContext. Match this against the claims.
        ' in the AuthorizationContext.
        Dim action As String = operationContext.RequestContext.RequestMessage.Headers.Action
        
        ' Iterate through the various claimsets in the AuthorizationContext.
        Dim cs As ClaimSet
        For Each cs In  operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets
            ' Examine only those claim sets issued by System.
            If cs.Issuer Is ClaimSet.System Then
                ' Iterate through claims of type "https://www.contoso.com/claims/allowedoperation".
                Dim c As Claim
                For Each c In  cs.FindClaims("https://www.contoso.com/claims/allowedoperation", _
                     Rights.PossessProperty)
                    ' If the Claim resource matches the action URI then return true to allow access.
                    If action = c.Resource.ToString() Then
                        Return True
                    End If
                Next c
            End If
        Next cs 
        ' If this point is reached, return false to deny access.
        Return False
    
    End Function 
End Class 
public class MyServiceAuthorizationManager : ServiceAuthorizationManager
{
  protected override bool CheckAccessCore(OperationContext operationContext)
  {                
    // Extract the action URI from the OperationContext. Match this against the claims
    // in the AuthorizationContext.
    string action = operationContext.RequestContext.RequestMessage.Headers.Action;
    
    // Iterate through the various claim sets in the AuthorizationContext.
    foreach(ClaimSet cs in operationContext.ServiceSecurityContext.AuthorizationContext.ClaimSets)
    {
      // Examine only those claim sets issued by System.
      if (cs.Issuer == ClaimSet.System)
      {
        // Iterate through claims of type "https://www.contoso.com/claims/allowedoperation".
          foreach (Claim c in cs.FindClaims("https://www.contoso.com/claims/allowedoperation", Rights.PossessProperty))
        {
          // If the Claim resource matches the action URI then return true to allow access.
          if (action == c.Resource.ToString())
            return true;
        }
      }
    }
    
    // If this point is reached, return false to deny access.
    return false;                 
  }
}

Vedere anche

Attività

Criteri di autorizzazione
Criteri di autorizzazione

Riferimento

ServiceAuthorizationManager