Ketika pertama kali dikembangkan, System.Web.Mvc.AuthorizeAttribute melakukan hal yang benar - revisi yang lebih lama dari spesifikasi HTTP menggunakan kode status 401 untuk "tidak sah" dan "tidak diauthentikasi".
Dari spesifikasi asli:
Jika permintaan sudah menyertakan kredensial Otorisasi, maka respons 401 menunjukkan bahwa otorisasi telah ditolak untuk kredensial tersebut.
Bahkan, Anda dapat melihat kebingungan di sana - itu menggunakan kata "otorisasi" ketika itu berarti "otentikasi". Namun, dalam praktik sehari-hari, lebih masuk akal untuk mengembalikan 403 Forbidden ketika pengguna diautentikasi tetapi tidak diotorisasi. Tidak mungkin pengguna akan memiliki set kredensial kedua yang akan memberi mereka akses - pengalaman pengguna yang buruk di sekitar.
Pertimbangkan sebagian besar sistem operasi - ketika Anda mencoba membaca file yang tidak memiliki izin untuk diakses, Anda tidak diperlihatkan layar login!
Untungnya, spesifikasi HTTP telah diperbarui (Juni 2014) untuk menghapus ambiguitas.
Dari "Protokol Transport Teks Hiper (HTTP / 1.1): Otentikasi" (RFC 7235):
Kode status 401 (Tidak Diotorisasi) menunjukkan bahwa permintaan belum diterapkan karena tidak memiliki kredensial otentikasi yang valid untuk sumber daya target.
Dari "Protokol Transfer Hiperteks (HTTP / 1.1): Semantik dan Konten" (RFC 7231):
Kode status 403 (Terlarang) menunjukkan bahwa server memahami permintaan tersebut tetapi menolak untuk mengesahkannya.
Cukup menarik, pada saat ASP.NET MVC 1 dirilis perilaku AuthorizeAttribute benar. Sekarang, perilaku salah - spesifikasi HTTP / 1.1 telah diperbaiki.
Daripada mencoba mengubah pengalihan halaman login ASP.NET, lebih mudah hanya untuk memperbaiki masalah di sumbernya. Anda dapat membuat atribut baru dengan nama yang sama ( AuthorizeAttribute) di namespace default situs web Anda (ini sangat penting) maka kompiler akan secara otomatis mengambilnya alih-alih yang standar MVC. Tentu saja, Anda selalu bisa memberi atribut nama baru jika Anda lebih suka mengambil pendekatan itu.
[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);
}
}
}