Cuando se desarrolló por primera vez, System.Web.Mvc.AuthorizeAttribute estaba haciendo lo correcto: las revisiones anteriores de la especificación HTTP usaban el código de estado 401 tanto para "no autorizado" como "no autenticado".
De la especificación original:
Si la solicitud ya incluía credenciales de autorización, la respuesta 401 indica que se ha rechazado la autorización para esas credenciales.
De hecho, puede ver la confusión allí mismo: utiliza la palabra "autorización" cuando significa "autenticación". Sin embargo, en la práctica diaria, tiene más sentido devolver un 403 Prohibido cuando el usuario está autenticado pero no autorizado. Es poco probable que el usuario tenga un segundo conjunto de credenciales que les otorgue acceso, mala experiencia del usuario en general.
Considere la mayoría de los sistemas operativos: cuando intenta leer un archivo al que no tiene permiso de acceso, no se le muestra una pantalla de inicio de sesión.
Afortunadamente, las especificaciones HTTP se actualizaron (junio de 2014) para eliminar la ambigüedad.
Desde "Protocolo de transporte de hipertexto (HTTP / 1.1): Autenticación" (RFC 7235):
El código de estado 401 (no autorizado) indica que la solicitud no se ha aplicado porque carece de credenciales de autenticación válidas para el recurso de destino.
Del "Protocolo de transferencia de hipertexto (HTTP / 1.1): semántica y contenido" (RFC 7231):
El código de estado 403 (Prohibido) indica que el servidor entendió la solicitud pero se niega a autorizarla.
Curiosamente, en el momento en que se lanzó ASP.NET MVC 1, el comportamiento de AuthorizeAttribute era correcto. Ahora, el comportamiento es incorrecto: se corrigió la especificación HTTP / 1.1.
En lugar de intentar cambiar las redirecciones de la página de inicio de sesión de ASP.NET, es más fácil solucionar el problema en la fuente. Puede crear un nuevo atributo con el mismo nombre ( AuthorizeAttribute
) en el espacio de nombres predeterminado de su sitio web (esto es muy importante), luego el compilador lo recogerá automáticamente en lugar del estándar de MVC. Por supuesto, siempre podría darle un nuevo nombre al atributo si prefiere adoptar ese enfoque.
[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);
}
}
}