Procédure : Créer un attribut d'autorisation personnalisé
Cette rubrique montre comment ajouter un attribut personnalisé pour l'autorisation. L'infrastructure des Services RIA WCF fournit les attributs RequiresAuthenticationAttribute et RequiresRoleAttribute. Ces attributs vous permettent de spécifier facilement les opérations de domaine disponibles uniquement aux utilisateurs authentifiés ou aux utilisateurs d'un rôle particulier. En plus des ces deux attributs, vous pouvez créer un attribut qui représente une logique d'autorisation personnalisée, puis appliquer cet attribut aux opérations de domaine.
Quand vous exposez un service de domaine, celui-ci est disponible à tout le monde sur le réseau. Vous ne pouvez pas supposer que votre application cliente sera la seule à accéder au service de domaine. Vous pouvez utiliser des attributs d'authentification personnalisés pour limiter l'accès aux opérations de domaine même si l'opération de domaine est accessible en dehors de votre application cliente.
Dans cette rubrique, vous allez créer un attribut d'autorisation personnalisé en créant une classe qui dérive de AuthorizationAttribute et en substituant la méthode IsAuthorized pour fournir votre logique personnalisée. Vous pouvez utiliser le paramètre IPrincipal et le paramètre AuthorizationContext pour accéder aux informations d'accès exigées, le cas échéant, par votre code d'authentification personnalisé. L'objet AuthorizationContext est Null sur les opérations de requête.
Pour créer un attribut d'autorisation personnalisé
Dans le projet serveur, créez une classe qui dérive de AuthorizationAttribute.
Substituez la méthode IsAuthorized et ajoutez la logique de détermination de l'autorisation.
L'exemple suivant montre un attribut personnalisé nommé
RestrictAccessToAssignedManagers
qui vérifie si l'utilisateur authentifié est le directeur de l'employé dont l'enregistrementEmployeePayHistory
est modifié.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."); } } }
Pour effectuer la logique d'autorisation personnalisée, appliquez l'attribut d'autorisation personnalisé à l'opération de domaine.
L'exemple suivant montre l'attribut
RestrictAccessToAssignedManagers
appliqué à une opération de domaine.<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); } }