Quando foi desenvolvido, o System.Web.Mvc.AuthorizeAttribute estava fazendo a coisa certa - as revisões mais antigas da especificação HTTP usavam o código de status 401 para "não autorizado" e "não autenticado".
A partir da especificação original:
Se a solicitação já incluía credenciais de autorização, a resposta 401 indica que a autorização foi recusada para essas credenciais.
De fato, você pode ver a confusão ali - ele usa a palavra "autorização" quando significa "autenticação". Na prática cotidiana, no entanto, faz mais sentido retornar um 403 Proibido quando o usuário é autenticado, mas não autorizado. É improvável que o usuário tenha um segundo conjunto de credenciais que lhes dê acesso - má experiência do usuário.
Considere a maioria dos sistemas operacionais - quando você tenta ler um arquivo que não tem permissão para acessar, não é exibida uma tela de login!
Felizmente, as especificações HTTP foram atualizadas (junho de 2014) para remover a ambiguidade.
Em "Protocolo de transporte de hipertexto (HTTP / 1.1): Autenticação" (RFC 7235):
O código de status 401 (não autorizado) indica que a solicitação não foi aplicada porque não possui credenciais de autenticação válidas para o recurso de destino.
Em "Protocolo de transferência de hipertexto (HTTP / 1.1): Semântica e conteúdo" (RFC 7231):
O código de status 403 (Proibido) indica que o servidor entendeu a solicitação, mas se recusa a autorizá-la.
Curiosamente, no momento em que o ASP.NET MVC 1 foi lançado, o comportamento do AuthorizeAttribute estava correto. Agora, o comportamento está incorreto - a especificação HTTP / 1.1 foi corrigida.
Em vez de tentar alterar os redirecionamentos da página de login do ASP.NET, é mais fácil corrigir o problema na fonte. Você pode criar um novo atributo com o mesmo nome ( AuthorizeAttribute
) no espaço de nome padrão do seu site (isso é muito importante) e o compilador o buscará automaticamente em vez do padrão do MVC. Obviamente, você sempre pode atribuir um novo nome ao atributo se preferir usar essa abordagem.
[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);
}
}
}