Partager via


Guide pratique pour créer un gestionnaire d’autorisation personnalisé pour un service

L’infrastructure Identity Model dans Windows Communication Foundation (WCF) prend en charge un modèle d’autorisation basé sur les revendications extensible. Les affirmations extraites des jetons sont, selon le cas, traitées par des stratégies d’autorisation personnalisées, puis placées dans un AuthorizationContext. Un gestionnaire d’autorisations examine les demandes dans AuthorizationContext pour prendre des décisions d’autorisation.

Par défaut, les décisions d’autorisation sont prises par la ServiceAuthorizationManager classe. Toutefois, ces décisions peuvent être substituées en créant un gestionnaire d’autorisations personnalisé. Pour créer un gestionnaire d’autorisations personnalisé, créez une classe qui dérive de ServiceAuthorizationManager et implémente la méthode CheckAccessCore. Les décisions d’autorisation sont prises dans la CheckAccessCore méthode, qui retourne true lorsque l’accès est accordé et false quand l’accès est refusé.

Si la décision d’autorisation dépend du contenu du corps du message, utilisez la CheckAccess méthode.

En raison de problèmes de performances, si possible, vous devez redéfinir votre application afin que la décision d’autorisation ne nécessite pas l’accès au corps du message.

L’inscription du gestionnaire d’autorisation personnalisé pour un service peut être effectuée dans le code ou la configuration.

Pour créer un gestionnaire d’autorisations personnalisé

  1. Dérivez une classe de la ServiceAuthorizationManager classe.

    public class MyServiceAuthorizationManager : ServiceAuthorizationManager
    {
    
    
    Public Class MyServiceAuthorizationManager
        Inherits ServiceAuthorizationManager
    
    
  2. Remplacez la méthode CheckAccessCore(OperationContext) .

    Utilisez le OperationContext qui est transmis dans la méthode CheckAccessCore(OperationContext) pour prendre des décisions d’autorisation.

    L’exemple de code suivant utilise la FindClaims(String, String) méthode pour rechercher la revendication http://www.contoso.com/claims/allowedoperation personnalisée pour prendre une décision d’autorisation.

    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 "http://www.contoso.com/claims/allowedoperation".
            foreach (Claim c in cs.FindClaims("http://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;
    }
    
    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 "http://www.contoso.com/claims/allowedoperation".
                Dim c As Claim
                For Each c In cs.FindClaims("http://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
    

Pour inscrire un gestionnaire d’autorisations personnalisé à l’aide du code

  1. Créez une instance du gestionnaire d’autorisations personnalisé et affectez-le à la ServiceAuthorizationManager propriété.

    La ServiceAuthorizationBehavior peut être accédée en utilisant la propriété Authorization.

    L’exemple de code suivant inscrit le gestionnaire d’autorisations MyServiceAuthorizationManager personnalisé.

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

Pour inscrire un gestionnaire d’autorisations personnalisé à l’aide de la configuration

  1. Ouvrez le fichier de configuration du service.

  2. Ajoutez un <serviceAuthorization> aux <comportements>.

    Dans serviceAuthorization<>, ajoutez un serviceAuthorizationManagerType attribut et définissez sa valeur sur le type qui représente le gestionnaire d’autorisations personnalisé.

  3. Ajoutez une liaison qui sécurise la communication entre le client et le service.

    La liaison choisie pour cette communication détermine les revendications qui sont ajoutées au AuthorizationContext, que le gestionnaire d’autorisations personnalisé utilise pour prendre des décisions d’autorisation. Pour plus d’informations sur les liaisons fournies par le système, consultez Liaisons fournies par le système.

  4. Associez le comportement à un point de terminaison de service, en ajoutant un <élément de service> et en définissant la valeur de l’attribut behaviorConfiguration sur la valeur de l’attribut de nom pour l’élément <de comportement> .

    Pour plus d’informations sur la configuration d’un point de terminaison de service, consultez Guide pratique pour créer un point de terminaison de service dans configuration.

    L’exemple de code suivant inscrit le gestionnaire Samples.MyServiceAuthorizationManagerd’autorisations personnalisé.

    <configuration>
      <system.serviceModel>
        <services>
          <service
              name="Microsoft.ServiceModel.Samples.CalculatorService"
              behaviorConfiguration="CalculatorServiceBehavior">
            <host>
              <baseAddresses>
                <add baseAddress="http://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,MyAssembly" />
             </behavior>
         </serviceBehaviors>
       </behaviors>
      </system.serviceModel>
    </configuration>
    

    Avertissement

    Notez que lorsque vous spécifiez le serviceAuthorizationManagerType, la chaîne doit contenir le nom de type complet. une virgule et le nom de l’assemblage dans lequel le type est défini. Si vous omettez le nom de l'assembly, WCF essaiera de charger le type à partir de System.ServiceModel.dll.

Exemple

L’exemple de code suivant illustre une implémentation de base d’une ServiceAuthorizationManager classe qui inclut la substitution de la CheckAccessCore méthode. L’exemple de code examine la revendication personnalisée AuthorizationContext et retourne true lorsque la ressource de cette revendication correspond à la valeur de l’action du OperationContext. Pour une implémentation plus complète d’une ServiceAuthorizationManager classe, consultez Stratégie d’autorisation.

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 "http://www.contoso.com/claims/allowedoperation".
          foreach (Claim c in cs.FindClaims("http://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;
  }
}

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 "http://www.contoso.com/claims/allowedoperation".
                Dim c As Claim
                For Each c In cs.FindClaims("http://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

Voir également