Di ASP.NET MVC, Anda dapat menandai metode pengontrol dengan AuthorizeAttribute
, seperti ini:
[Authorize(Roles = "CanDeleteTags")]
public void Delete(string tagName)
{
// ...
}
Ini berarti bahwa, jika pengguna yang saat ini masuk tidak dalam peran "CanDeleteTags", metode pengontrol tidak akan pernah dipanggil.
Sayangnya, untuk kegagalan, AuthorizeAttribute
kembali HttpUnauthorizedResult
, yang selalu mengembalikan kode status HTTP 401. Ini menyebabkan pengalihan ke halaman login.
Jika pengguna tidak masuk, ini masuk akal. Namun, jika pengguna sudah masuk, tetapi tidak dalam peran yang diperlukan, itu membingungkan untuk mengirim mereka kembali ke halaman login.
Tampaknya AuthorizeAttribute
mengonfigurasi otentikasi dan otorisasi.
Ini sepertinya sedikit kekeliruan dalam ASP.NET MVC, atau apakah saya melewatkan sesuatu?
Saya harus memasak DemandRoleAttribute
yang memisahkan keduanya. Ketika pengguna tidak diautentikasi, ia mengembalikan HTTP 401, mengirimkannya ke halaman login. Ketika pengguna masuk, tetapi tidak dalam peran yang diperlukan, itu NotAuthorizedResult
malah menciptakan . Saat ini ini diarahkan ke halaman kesalahan.
Tentunya saya tidak perlu melakukan ini?
sumber
Jawaban:
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:
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):
Dari "Protokol Transfer Hiperteks (HTTP / 1.1): Semantik dan Konten" (RFC 7231):
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.sumber
filterContext.HttpContext.User.Identity.IsAuthenticated
, Anda hanya dapat memeriksafilterContext.HttpContext.Request.IsAuthenticated
, yang disertai dengan pemeriksaan nol bawaan. Lihat stackoverflow.com/questions/1379566/…Tambahkan ini ke fungsi Halaman Login Anda:
Ketika pengguna dialihkan ke sana tetapi sudah masuk, itu menunjukkan halaman yang tidak sah. Jika mereka tidak masuk, itu masuk dan menunjukkan halaman login.
sumber
if (User.Identity != null && User.Identity.IsAuthenticated) return RedirectToRoute("Unauthorized");
mana Unauthorized adalah nama rute yang ditentukan.Saya selalu berpikir ini masuk akal. Jika Anda masuk dan mencoba membuka halaman yang membutuhkan peran yang tidak Anda miliki, Anda akan diteruskan ke layar login meminta Anda untuk masuk dengan pengguna yang memang memiliki peran tersebut.
Anda dapat menambahkan logika ke halaman login yang memeriksa untuk melihat apakah pengguna sudah dikonfirmasi. Anda dapat menambahkan pesan ramah yang menjelaskan mengapa mereka telah dibohongi kembali di sana.
sumber
Sayangnya, Anda berurusan dengan perilaku default otentikasi formulir ASP.NET. Ada solusi (saya belum mencobanya) yang dibahas di sini:
http://www.codeproject.com/KB/aspnet/Custon401Page.aspx
(Ini tidak khusus untuk MVC)
Saya pikir dalam banyak kasus solusi terbaik adalah membatasi akses ke sumber daya yang tidak sah sebelum pengguna mencoba untuk sampai ke sana. Dengan menghapus / memutari tautan atau tombol yang mungkin membawa mereka ke halaman tidak sah ini.
Mungkin akan menyenangkan untuk memiliki parameter tambahan pada atribut untuk menentukan di mana mengarahkan pengguna yang tidak sah. Tetapi sementara itu, saya melihat AuthorizeAttribute sebagai jaring pengaman.
sumber
Coba ini di dalam Anda di Application_EndRequest handler file Global.ascx Anda
sumber
Jika Anda menggunakan aspnetcore 2.0, gunakan ini:
sumber
Dalam kasus saya masalahnya adalah "spesifikasi HTTP menggunakan kode status 401 untuk" tidak sah "dan" tidak diauthentikasi "". Seperti yang dikatakan ShadowChaser.
Solusi ini bekerja untuk saya:
sumber