Quand il a été développé pour la première fois, System.Web.Mvc.AuthorizeAttribute faisait la bonne chose - les révisions plus anciennes de la spécification HTTP utilisaient le code d'état 401 pour "non autorisé" et "non authentifié".
De la spécification d'origine:
Si la demande contient déjà des informations d'identification d'autorisation, la réponse 401 indique que l'autorisation a été refusée pour ces informations d'identification.
En fait, vous pouvez voir la confusion ici - il utilise le mot «autorisation» quand il signifie «authentification». Dans la pratique quotidienne, cependant, il est plus logique de renvoyer un 403 Interdit lorsque l'utilisateur est authentifié mais non autorisé. Il est peu probable que l'utilisateur ait un deuxième ensemble d'informations d'identification qui lui donnerait accès - une mauvaise expérience utilisateur tout autour.
Tenez compte de la plupart des systèmes d'exploitation - lorsque vous essayez de lire un fichier auquel vous n'êtes pas autorisé à accéder, aucun écran de connexion ne s'affiche.
Heureusement, les spécifications HTTP ont été mises à jour (juin 2014) pour lever l'ambiguïté.
Extrait de "Hyper Text Transport Protocol (HTTP / 1.1): Authentication" (RFC 7235):
Le code d'état 401 (non autorisé) indique que la demande n'a pas été appliquée car il manque des informations d'identification d'authentification valides pour la ressource cible.
Extrait de "Hypertext Transfer Protocol (HTTP / 1.1): Semantics and Content" (RFC 7231):
Le code d'état 403 (interdit) indique que le serveur a compris la demande mais refuse de l'autoriser.
Chose intéressante, au moment où ASP.NET MVC 1 a été publié, le comportement d'AutorizeAttribute était correct. Maintenant, le comportement est incorrect - la spécification HTTP / 1.1 a été corrigée.
Plutôt que d'essayer de modifier les redirections de la page de connexion d'ASP.NET, il est plus facile de résoudre le problème à la source. Vous pouvez créer un nouvel attribut avec le même nom ( AuthorizeAttribute
) dans l'espace de noms par défaut de votre site Web (c'est très important), puis le compilateur le récupérera automatiquement au lieu de celui standard de MVC. Bien sûr, vous pouvez toujours donner un nouveau nom à l'attribut si vous préférez adopter cette approche.
[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);
}
}
}