Gewusst wie: Erstellen eines benutzerdefinierten Autorisierungsattributs

In diesem Thema wird erläutert, wie ein benutzerdefiniertes Attribut für die Autorisierung hinzugefügt wird. Das WCF RIA Services-Framework stellt die RequiresAuthenticationAttribute- und RequiresRoleAttribute-Attribute bereit. Mit diesen Attributen können Sie mühelos angeben, welche Domänenvorgänge nur für authentifizierte Benutzer oder Benutzer in einer bestimmten Rolle verfügbar sind. Zusätzlich zu diesen zwei Attributen können Sie ein Attribut erstellen, das benutzerdefinierte Autorisierungslogik darstellt, und das Attribut dann auf Domänenvorgänge anwenden.

Wenn Sie einen Domänendienst verfügbar machen, ist er für alle Benutzer im Netzwerk verfügbar. Sie können nicht davon ausgehen, dass die Clientanwendung die einzige Anwendung ist, die auf den Domänendienst zugreift. Der Zugriff auf Domänenvorgänge kann selbst dann mithilfe von benutzerdefinierten Authentifizierungsattributen eingeschränkt werden, wenn außerhalb der Clientanwendung auf den Domänenvorgang zugegriffen wird.

In diesem Thema erstellen Sie ein benutzerdefiniertes Autorisierungsattribut, indem Sie eine von AuthorizationAttribute abgeleitete Klasse erstellen und die IsAuthorized-Methode überschreiben, um die benutzerdefinierte Logik bereitzustellen. Sie können den IPrincipal-Parameter und den AuthorizationContext-Parameter verwenden, um auf Informationen zuzugreifen, die möglicherweise im benutzerdefinierten Authentifizierungscode erforderlich sind. Das AuthorizationContext-Objekt ist bei Abfragevorgängen NULL.

So erstellen Sie ein benutzerdefiniertes Autorisierungsattribut

  1. Erstellen Sie im Serverprojekt eine von AuthorizationAttribute abgeleitete Klasse.

  2. Überschreiben Sie die IsAuthorized-Methode, und fügen Sie Logik zum Bestimmen der Autorisierung hinzu.

    Im folgenden Beispiel wird durch ein benutzerdefiniertes Attribut mit dem Namen RestrictAccessToAssignedManagers überprüft, ob der authentifizierte Benutzer der Manager des Mitarbeiters ist, dessen EmployeePayHistory-Datensatz geändert wird.

    Public Class RestrictAccessToAssignedManagers
        Inherits AuthorizationAttribute
    
        Protected Overrides Function IsAuthorized(ByVal principal As System.Security.Principal.IPrincipal, ByVal authorizationContext As System.ComponentModel.DataAnnotations.AuthorizationContext) As System.ComponentModel.DataAnnotations.AuthorizationResult
            Dim eph As EmployeePayHistory
            Dim selectedEmployee As Employee
            Dim authenticatedUser As Employee
    
            eph = CType(authorizationContext.Instance, EmployeePayHistory)
    
            Using context As New AdventureWorksEntities()
                selectedEmployee = context.Employees.SingleOrDefault(Function(e) e.EmployeeID = eph.EmployeeID)
                authenticatedUser = context.Employees.SingleOrDefault(Function(e) e.LoginID = principal.Identity.Name)
            End Using
    
            If (selectedEmployee.ManagerID = authenticatedUser.EmployeeID) Then
                Return AuthorizationResult.Allowed
            Else
                Return New AuthorizationResult("Only the authenticated manager for the employee can add a new record.")
            End If
        End Function
    End Class
    
    public class RestrictAccessToAssignedManagers : AuthorizationAttribute
    {
        protected override AuthorizationResult IsAuthorized(System.Security.Principal.IPrincipal principal, AuthorizationContext authorizationContext)
        {
            EmployeePayHistory eph = (EmployeePayHistory)authorizationContext.Instance;
            Employee selectedEmployee;
            Employee authenticatedUser;
    
            using (AdventureWorksEntities context = new AdventureWorksEntities())
            {
                selectedEmployee = context.Employees.SingleOrDefault(e => e.EmployeeID == eph.EmployeeID);
                authenticatedUser = context.Employees.SingleOrDefault(e => e.LoginID == principal.Identity.Name);
            }
    
            if (selectedEmployee.ManagerID == authenticatedUser.EmployeeID)
            {
                return AuthorizationResult.Allowed;
            }
            else
            {
                return new AuthorizationResult("Only the authenticated manager for the employee can add a new record.");
            }
        }
    }
    
  3. Wenden Sie das benutzerdefinierte Autorisierungsattribut auf den Domänenvorgang an, um die benutzerdefinierte Autorisierungslogik auszuführen.

    Im folgenden Beispiel wurde das RestrictAccessToAssignedManagers-Attribut auf einen Domänenvorgang angewendet.

    <RestrictAccessToAssignedManagers()> _
    Public Sub InsertEmployeePayHistory(ByVal employeePayHistory As EmployeePayHistory)
        If ((employeePayHistory.EntityState = EntityState.Detached) _
                    = False) Then
            Me.ObjectContext.ObjectStateManager.ChangeObjectState(employeePayHistory, EntityState.Added)
        Else
            Me.ObjectContext.EmployeePayHistories.AddObject(employeePayHistory)
        End If
    End Sub
    
    [RestrictAccessToAssignedManagers]
    public void InsertEmployeePayHistory(EmployeePayHistory employeePayHistory)
    {
        if ((employeePayHistory.EntityState != EntityState.Detached))
        {
            this.ObjectContext.ObjectStateManager.ChangeObjectState(employeePayHistory, EntityState.Added);
        }
        else
        {
            this.ObjectContext.EmployeePayHistories.AddObject(employeePayHistory);
        }
    }