Gdy został opracowany po raz pierwszy, System.Web.Mvc.AuthorizeAttribute działał dobrze - starsze wersje specyfikacji HTTP używały kodu stanu 401 zarówno dla „nieautoryzowanego”, jak i „nieuwierzytelnionego”.
Z oryginalnej specyfikacji:
Jeśli żądanie zawierało już poświadczenia autoryzacji, wówczas odpowiedź 401 wskazuje, że odmówiono autoryzacji tych poświadczeń.
W rzeczywistości widać zamieszanie - używa słowa „autoryzacja”, gdy oznacza „uwierzytelnianie”. Jednak w codziennej praktyce bardziej sensowne jest zwracanie 403 Zabronione, gdy użytkownik jest uwierzytelniony, ale nie autoryzowany. Jest mało prawdopodobne, że użytkownik będzie miał drugi zestaw poświadczeń, które dadzą mu dostęp - złe wrażenia użytkownika dookoła.
Zastanów się nad większością systemów operacyjnych - gdy próbujesz odczytać plik, do którego nie masz uprawnień, nie wyświetla się ekran logowania!
Na szczęście specyfikacje HTTP zostały zaktualizowane (czerwiec 2014 r.) W celu usunięcia niejasności.
Z „Hyper Text Transport Protocol (HTTP / 1.1): Uwierzytelnianie” (RFC 7235):
Kod stanu 401 (nieautoryzowany) wskazuje, że żądanie nie zostało zastosowane, ponieważ brakuje prawidłowych poświadczeń uwierzytelnienia dla zasobu docelowego.
Z „Hypertext Transfer Protocol (HTTP / 1.1): Semantyka i treść” (RFC 7231):
Kod statusu 403 (Zabroniony) wskazuje, że serwer zrozumiał żądanie, ale odmawia jego autoryzacji.
Co ciekawe, w momencie wydania programu ASP.NET MVC 1 zachowanie funkcji AuthorizeAttribute było prawidłowe. Teraz zachowanie jest nieprawidłowe - poprawiono specyfikację HTTP / 1.1.
Zamiast próby zmiany przekierowań strony logowania ASP.NET, łatwiej jest po prostu naprawić problem u źródła. Możesz utworzyć nowy atrybut o tej samej nazwie ( AuthorizeAttribute
) w domyślnej przestrzeni nazw swojej witryny (jest to bardzo ważne), a następnie kompilator automatycznie wybierze ją zamiast standardowej MVC. Oczywiście zawsze możesz nadać atrybutowi nową nazwę, jeśli wolisz takie podejście.
[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);
}
}
}