Procedura: creare un attributo di autorizzazione personalizzato
In questo argomento viene illustrato come aggiungere un attributo personalizzato per l'autorizzazione. Il framework WCF RIA Services fornisce gli attributi RequiresAuthenticationAttribute e RequiresRoleAttribute. Questi attributi consentono di specificare facilmente le operazioni di dominio disponibili solo agli utenti autenticati o agli utenti in un ruolo specifico. Oltre a questi due attributi, è possibile creare un attributo che rappresenta la logica di autorizzazione personalizzata e quindi applicare l'attributo alle operazioni di dominio.
Quando si espone un servizio del dominio, esso sarà disponibile a tutti gli utenti della rete. Non si può supporre che l'applicazione client utilizzata sia l'unica applicazione che accederà al servizio del dominio. È possibile utilizzare gli attributi di autenticazione personalizzati per limitare l'accesso alle operazioni di dominio anche quando l'accesso all'operazione di dominio viene eseguito al di fuori dell'applicazione client.
In questo argomento viene creato un attributo di autorizzazione personalizzato creando una classe che deriva da AuthorizationAttribute ed eseguendo l'override del metodo IsAuthorized per fornire la logica personalizzata. È possibile utilizzare il parametro IPrincipal e il parametro AuthorizationContext per accedere alle informazioni che possono essere richieste all'interno del codice di autenticazione personalizzato. L'oggetto AuthorizationContext è null sulle operazioni di query.
Per creare un attributo di autorizzazione personalizzato
Nel progetto server creare una classe che deriva da AuthorizationAttribute.
Eseguire l'override del metodo IsAuthorized e aggiungere la logica per determinare l'autorizzazione.
Nell'esempio seguente viene illustrato un attributo personalizzato denominato
RestrictAccessToAssignedManagers
che controlla se l'utente autenticato è il responsabile del dipendente di cui viene modificato il recordEmployeePayHistory
.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."); } } }
Per eseguire la logica di autorizzazione personalizzata, applicare l'attributo di autorizzazione personalizzato all'operazione di dominio.
Nell'esempio seguente viene illustrato l'attributo
RestrictAccessToAssignedManagers
applicato a un'operazione di dominio.<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); } }