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
Erstellen Sie im Serverprojekt eine von AuthorizationAttribute abgeleitete Klasse.
Ü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, dessenEmployeePayHistory
-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."); } } }
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); } }