Vorgehensweise: Erstellen eines benutzerdefinierten Autorisierungs-Managers für einen Dienst

Die Identitätsmodellinfrastruktur in Windows Communication Foundation (WCF) unterstützt ein erweiterbares anspruchsbasiertes Autorisierungsmodell.Ansprüche werden aus Token extrahiert, wahlweise mit benutzerdefinierten Autorisierungsrichtlinien verarbeitet und dann in einem AuthorizationContext platziert.Die Ansprüche im AuthorizationContext werden von einem Autorisierungs-Manager geprüft und als Grundlage für Autorisierungsentscheidungen herangezogen.

Standardmäßig werden Autorisierungsentscheidungen von der ServiceAuthorizationManager-Klasse getroffen. Diese Entscheidungen können jedoch durch die Erstellung eines benutzerdefinierten Autorisierungs-Managers außer Kraft gesetzt werden.Wenn Sie Ihren eigenen Autorisierungs-Manager erstellen möchten, erstellen Sie eine Klasse, die von ServiceAuthorizationManager ableitet, und implementieren die CheckAccessCore-Methode.Autorisierungsentscheidungen werden in der CheckAccessCore-Methode getroffen, von der true zurückgegeben wird, wenn Zugriff gewährt wurde, und false, wenn der Zugriff verweigert wurde.

Wenn die Autorisierungsentscheidung vom Inhalt des Nachrichtentexts abhängt, verwenden Sie die CheckAccess-Methode.

Um Leistungseinbußen zu vermeiden, sollten Sie soweit möglich Ihre Anwendung neu entwerfen, sodass für die Autorisierungsentscheidung kein Zugriff auf den Nachrichtentext erforderlich ist.

Die Registrierung des benutzerdefinierten Autorisierungs-Managers für einen Dienst kann im Code oder in der Konfiguration erfolgen.

So erstellen Sie einen benutzerdefinierten Autorisierungs-Manager

  1. Leiten Sie eine Klasse von der ServiceAuthorizationManager-Klasse ab.

    public class MyServiceAuthorizationManager : ServiceAuthorizationManager
    {
    
    
    Public Class MyServiceAuthorizationManager
        Inherits ServiceAuthorizationManager
        
    
  2. Überschreiben Sie die CheckAccessCore(OperationContext)-Methode.

    Verwenden Sie den an die CheckAccessCore(OperationContext)-Methode übergebenen OperationContext, um Autorisierungsentscheidungen zu fällen.

    Im folgenden Codebeispiel wird mit der FindClaims(String, String)-Methode der benutzerdefinierte Anspruch http://www.contoso.com/claims/allowedoperation gesucht, um eine Autorisierungsentscheidung zu treffen.

    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 
    

So registrieren Sie einen benutzerdefinierten Autorisierungs-Manager im Code

  1. Erstellen Sie eine Instanz des benutzerdefinierten Autorisierungs-Managers, und weisen Sie sie der ServiceAuthorizationManager-Eigenschaft zu.

    Auf ServiceAuthorizationBehavior kann mit der Authorization-Eigenschaft zugegriffen werden.

    Im folgenden Codebeispiel wird der benutzerdefinierte MyServiceAuthorizationManager-Autorisierungs-Manager registriert.

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

So registrieren Sie einen benutzerdefinierten Autorisierungs-Manager in der Konfiguration

  1. Öffnen Sie die Konfigurationsdatei für den Dienst.

  2. Fügen Sie ein <serviceAuthorization> zum <Verhalten> hinzu.

    Fügen Sie dem <serviceAuthorization> ein serviceAuthorizationManagerType-Attribut hinzu, und legen Sie als Wert für das Attribut den Typ fest, der den benutzerdefinierten Autorisierungs-Manager repräsentiert.

  3. Fügen Sie eine Bindung hinzu, durch die die Kommunikation zwischen Client und Dienst gesichert wird.

    Die für diese Kommunikation gewählte Bindung bestimmt die Ansprüche, die zum AuthorizationContext hinzugefügt werden, der vom benutzerdefinierten Autorisierungs-Manager verwendet wird, um Autorisierungsentscheidungen zu treffen.Ausführliche Informationen zu systemeigenen Bindungen finden Sie unter Vom System bereitgestellte Bindungen.

  4. Ordnen Sie das Verhalten einem Dienstendpunkt zu, indem Sie ein <service>behaviorConfiguration-Element hinzufügen, und legen Sie als Wert des <Verhalten>-Element fest.

    Weitere Informationen zum Konfigurieren eines Dienstendpunkts finden Sie unter Gewusst wie: Erstellen eines Dienstendpunkts in einer Konfiguration.

    Im folgenden Codebeispiel wird der benutzerdefinierte Autorisierungs-Manager Samples.MyServiceAuthorizationManager registriert.

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

    Beachten Sie, dass die Zeichenfolge den vollqualifizierten Typnamen enthalten muss, wenn Sie serviceAuthorizationManagerType angeben.Kommas und der Name der Assembly, in der der Typ definiert ist.Wenn Sie den Assemblynamen auslassen, versucht WCF, den Typ aus System.ServiceModel.dll zu laden.

Beispiel

Das folgende Codebeispiel zeigt eine grundlegende Implementierung einer ServiceAuthorizationManager-Klasse, bei der auch die CheckAccessCore-Methode außer Kraft gesetzt (überschrieben) wird.Im Beispielcode wird der AuthorizationContext auf einen benutzerspezifischen Anspruch hin überprüft und true zurückgegeben, wenn die Ressource für diesen benutzerspezifischen Anspruch zum Aktionswert aus dem OperationContext passt.Eine umfassendere Implementierung einer ServiceAuthorizationManager-Klasse finden Sie unter Autorisierungsrichtlinie.

 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 

Siehe auch

ServiceAuthorizationManager
Autorisierungsrichtlinie
Autorisierungsrichtlinie