Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Autenticazione e protezione a portata di attributo

Sfruttare al meglio e in modo semplice le Membership API
Sfruttare al meglio e in modo semplice le Membership API
Link copiato negli appunti

Probabilmente la feature più famosa di Asp.Net Web Form è il supporto integrato per l'autenticazione degli utenti mediante le Membership API. Naturalmente anche in Asp.NET MVC è possibile utilizzare la stessa libreria e la struttura del framework rende il suo utilizzo molto semplice, o come mi piace dire spesso, a portata di attributo!

Il template di Visual Studio 2010 per le applicazioni ASP.NET MVC 2.0 fornisce già tutto il necessario per l'autenticazione, comprese le view e i controller per le operazioni più comuni, dal login al cambio della password, utilizzando i provider e il database di default per la gestione delle operazioni.

Figura 12. L'autenticazione nel template di ASP.NET MVC 2.0 di Visual Studio 2010
(clic per ingrandire)


Figura 12. L'autenticazione nel template di ASP.NET MVC 2.0 di Visual Studio 2010

Una volta autenticato l'utente, la gestione dei permessi ad associati all'account viene limitata all'invocazione delle action decorate con l'attributo Authorize, come mostrato nell'Account Controller, ad esempio, per il cambio della password:

[Authorize]
public ActionResult ChangePassword()
{
    ViewData["PasswordLength"] = MembershipService.MinPasswordLength;
    return View();
}

Naturalmente è possibile, valorizzando le opportune proprietà, specificare anche il livello di autorizzazione, ad esempio per ruolo:

[Authorize(Roles="Administrator")]
public ActionResult Metodo()
{
    // Logica del metodo
}

O, in maniera altrettanto semplice, per utente:

[Authorize(Users="DotNetCampania")]
public ActionResult Metodo()
{
    // Logica del metodo
}

AuthorizeAttribute è un ActionFilter, infatti estende FilterAttribute oltre ad implementare l'interfaccia IAuthorizationFilter:

public class AuthorizeAttribute : FilterAttribute, IAuthorizationFilter { … }

Estendendo questa classe possiamo implementare dei comportamenti particolari che non riusciamo ad ottenere con le proprietà esistenti: ci basta eseguire l'override del metodo OnAuthorization per implementare la nostra logica di autorizzazione:
public virtual void OnAuthorization(AuthorizationContext filterContext);

Grazie all'AuthorizationContext che ci viene passato possiamo decidere se l'autorizzazione è stata concessa o meno utilizzando la proprietà Result di tipo ActionResult settandola ad esempio con un'istanza della classe HttpUnauthorizedResult:

filterContext.Result = new HttpUnauthorizedResult();
 

Se poi come me siete allergici alle stringhe possiamo decidere di enumerare ad esempio i ruoli dell'applicazione, personalizzando di conseguenza o l'OnAuthorization o per fare un esempio diverso eseguendo l'override del metodo AuthorizeCore:

public enum Roles
{ 
    Admin,
    Customer,
    Provider,
    SalesManager
}
public class RolesAuthorizeAttribute : AuthorizeAttribute
{
    public Roles Role { get; set; }
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        if (httpContext.User.Identity.IsAuthenticated)
        {
            bool authorized = false;
            switch(Role)
            {
                case Roles.Admin:
                    authorized = httpContext.User.IsInRole("Administrator");
                    break;
                case Roles.Customer:
                    authorized = httpContext.User.IsInRole("Customer");
                    break;
                case Roles.Provider:
                    authorized = httpContext.User.IsInRole("Provider");
                    break;
                case Roles.SalesManager:
                    authorized = httpContext.User.IsInRole("SalesManager");
                    break;
                default:
                    authorized = false;
                    break;
            }
            return authorized;
        }
        return false;
    }
}

Il che rende la gestione delle autorizzazioni un po' meno esposta ad errori:

[RolesAuthorizeAttribute(Role=Roles.Admin)]
public ActionResult MioMetodo()
{
    // Logica
}

Chiaramente tutto il meccanismo che è dietro alle Membership API e la loro personalizzazione mediante lo sviluppo di provider specifici per il proprio strato dati rimane invariato.

Ti consigliamo anche