Condividi tramite


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

  1. Nel progetto server creare una classe che deriva da AuthorizationAttribute.

  2. 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 record EmployeePayHistory.

    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. 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);
        }
    }