Quando è stato sviluppato per la prima volta, System.Web.Mvc.AuthorizeAttribute stava facendo la cosa giusta: le versioni precedenti della specifica HTTP utilizzavano il codice di stato 401 sia per "non autorizzato" che per "non autenticato".
Dalla specifica originale:
Se la richiesta includeva già le credenziali di autorizzazione, la risposta 401 indica che l'autorizzazione è stata rifiutata per tali credenziali.
In effetti, puoi vedere la confusione proprio lì: usa la parola "autorizzazione" quando significa "autenticazione". Nella pratica quotidiana, tuttavia, ha più senso restituire un 403 Forbidden quando l'utente è autenticato ma non autorizzato. È improbabile che l'utente disponga di un secondo set di credenziali che gli dia accesso: un'esperienza utente negativa tutto intorno.
Considera la maggior parte dei sistemi operativi: quando tenti di leggere un file a cui non sei autorizzato ad accedere, non ti viene mostrata una schermata di accesso!
Per fortuna, le specifiche HTTP sono state aggiornate (giugno 2014) per rimuovere l'ambiguità.
Da "Hyper Text Transport Protocol (HTTP / 1.1): autenticazione" (RFC 7235):
Il codice di stato 401 (Non autorizzato) indica che la richiesta non è stata applicata perché manca di credenziali di autenticazione valide per la risorsa di destinazione.
Da "Hypertext Transfer Protocol (HTTP / 1.1): Semantics and Content" (RFC 7231):
Il codice di stato 403 (Forbidden) indica che il server ha compreso la richiesta ma rifiuta di autorizzarla.
È interessante notare che al momento del rilascio di ASP.NET MVC 1 il comportamento di AuthorizeAttribute era corretto. Ora, il comportamento non è corretto: la specifica HTTP / 1.1 è stata corretta.
Piuttosto che tentare di modificare i reindirizzamenti della pagina di accesso di ASP.NET, è più semplice risolvere il problema alla fonte. Puoi creare un nuovo attributo con lo stesso nome ( AuthorizeAttribute
) nello spazio dei nomi predefinito del tuo sito web (questo è molto importante), quindi il compilatore lo raccoglierà automaticamente al posto di quello standard di MVC. Ovviamente, potresti sempre dare all'attributo un nuovo nome se preferisci adottare questo approccio.
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class AuthorizeAttribute : System.Web.Mvc.AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(System.Web.Mvc.AuthorizationContext filterContext)
{
if (filterContext.HttpContext.Request.IsAuthenticated)
{
filterContext.Result = new System.Web.Mvc.HttpStatusCodeResult((int)System.Net.HttpStatusCode.Forbidden);
}
else
{
base.HandleUnauthorizedRequest(filterContext);
}
}
}