Saya membuat situs web multi-tenancy yang menghosting halaman untuk klien. Segmen pertama URL akan menjadi string yang mengidentifikasi klien, ditentukan di Global.asax menggunakan skema perutean URL berikut:
"{client}/{controller}/{action}/{id}"
Ini berfungsi dengan baik, dengan URL seperti / foo / Home / Index.
Namun, saat menggunakan atribut [Otorisasi], saya ingin mengalihkan ke halaman login yang juga menggunakan skema pemetaan yang sama. Jadi jika klien adalah foo, halaman login akan menjadi / foo / Akun / Login alih-alih pengalihan tetap / Akun / Login yang ditentukan di web.config.
MVC menggunakan HttpUnauthorizedResult untuk mengembalikan status tidak sah 401, yang saya anggap menyebabkan ASP.NET mengalihkan ke halaman yang ditentukan di web.config.
Jadi, apakah ada yang tahu cara menimpa perilaku pengalihan login ASP.NET? Atau akankah lebih baik untuk mengalihkan di MVC dengan membuat atribut otorisasi khusus?
EDIT - Jawaban: setelah menggali sumber .Net, saya memutuskan bahwa atribut otentikasi khusus adalah solusi terbaik:
public class ClientAuthorizeAttribute: AuthorizeAttribute
{
public override void OnAuthorization( AuthorizationContext filterContext )
{
base.OnAuthorization( filterContext );
if (filterContext.Cancel && filterContext.Result is HttpUnauthorizedResult )
{
filterContext.Result = new RedirectToRouteResult(
new RouteValueDictionary
{
{ "client", filterContext.RouteData.Values[ "client" ] },
{ "controller", "Account" },
{ "action", "Login" },
{ "ReturnUrl", filterContext.HttpContext.Request.RawUrl }
});
}
}
}
Jawaban:
Saya pikir masalah utamanya adalah bahwa jika Anda akan membonceng kelas ASP.NET FormsAuthentication built-in (dan tidak ada alasan bagus untuk tidak melakukannya), sesuatu pada akhirnya akan memanggil
FormsAuthentication.RedirectToLoginPage()
yang akan terjadi untuk melihat satu URL yang dikonfigurasi. Hanya ada satu URL login, dan begitulah cara mereka mendesainnya.Masalah saya (mungkin implementasi Rube Goldberg) adalah membiarkannya dialihkan ke satu halaman login di root yang dibagikan oleh semua klien, misalnya / account / login. Halaman login ini sebenarnya tidak akan menampilkan apa pun; itu memeriksa baik parameter ReturnUrl atau beberapa nilai yang saya dapatkan dalam sesi atau cookie yang mengidentifikasi klien dan menggunakannya untuk mengeluarkan pengalihan 302 langsung ke halaman / klien / akun / login tertentu. Ini adalah pengalihan tambahan, tetapi kemungkinan tidak terlihat dan memungkinkan Anda menggunakan mekanisme pengalihan bawaan.
Opsi lainnya adalah membuat atribut khusus Anda sendiri saat Anda mendeskripsikan dan menghindari apa pun yang memanggil
RedirectToLoginPage()
metode diFormsAuthentication
kelas, karena Anda akan menggantinya dengan logika pengalihan Anda sendiri. (Anda dapat membuat kelas Anda sendiri yang serupa.) Karena ini adalah kelas statis, saya tidak mengetahui mekanisme apa pun yang dapat Anda gunakan untuk memasukkan antarmuka alternatif Anda sendiri dan membuatnya bekerja secara ajaib dengan atribut [Otorisasi] yang ada, yang mana pukulan, tetapi orang telah melakukan hal serupa sebelumnya .Semoga membantu!
sumber
Application_AuthenticateRequest
(lihat jawaban saya di bawah).Dalam versi RTM ASP.NET MVC, properti Batal hilang. Kode ini bekerja dengan ASP.NET MVC RTM:
Sunting: Anda mungkin ingin menonaktifkan bentuk default otentikasi loginUrl di web.config - jika seseorang lupa Anda memiliki atribut khusus dan menggunakan atribut bawaan [Otorisasi] karena kesalahan.
Ubah nilai di web.config:
Kemudian buat metode tindakan 'ERROR' yang mencatat kesalahan dan mengarahkan pengguna ke halaman login paling umum yang Anda miliki.
sumber
Solusi saya untuk masalah ini adalah
ActionResult
kelas khusus :sumber
Namun, jika seseorang memutuskan untuk menggunakan built-in ASP.NET FormsAuthentication, satu dapat overide
Application_AuthenticateRequest
diGlobal.asax.cs
sebagai berikut:sumber