Saya perlu melakukan sesuatu yang cukup sederhana: dalam aplikasi ASP.NET MVC saya, saya ingin menetapkan kebiasaan IIdentity / IPrincipal. Mana yang lebih mudah / lebih cocok. Saya ingin memperpanjang default sehingga saya bisa memanggil sesuatu seperti User.Identity.Id
dan User.Identity.Role
. Tidak ada yang mewah, hanya beberapa properti tambahan.
Saya telah membaca banyak artikel dan pertanyaan, tetapi saya merasa saya membuatnya lebih sulit dari yang sebenarnya. Saya pikir itu akan mudah. Jika pengguna log on, saya ingin mengatur IIdentity kustom. Jadi saya pikir, saya akan menerapkannya Application_PostAuthenticateRequest
di global.asax saya. Namun, itu dipanggil pada setiap permintaan, dan saya tidak ingin melakukan panggilan ke database pada setiap permintaan yang akan meminta semua data dari database dan memasukkan objek IPrincipal kustom. Itu juga tampaknya sangat tidak perlu, lambat, dan di tempat yang salah (melakukan panggilan basis data di sana) tetapi saya bisa saja salah. Atau dari mana lagi data itu berasal?
Jadi saya pikir, setiap kali pengguna login, saya bisa menambahkan beberapa variabel yang diperlukan dalam sesi saya, yang saya tambahkan ke kustom IIdentity di Application_PostAuthenticateRequest
pengendali event. Namun, saya Context.Session
adalah null
ada, sehingga juga tidak cara untuk pergi.
Saya sudah mengerjakan ini selama sehari sekarang dan saya merasa saya kehilangan sesuatu. Ini seharusnya tidak terlalu sulit untuk dilakukan, bukan? Saya juga agak bingung dengan semua hal (semi) terkait yang datang dengan ini. MembershipProvider
, MembershipUser
, RoleProvider
, ProfileProvider
, IPrincipal
, IIdentity
, FormsAuthentication
.... Am saya satu-satunya yang menemukan semua ini sangat membingungkan?
Jika seseorang bisa memberi tahu saya solusi sederhana, elegan, dan efisien untuk menyimpan beberapa data tambahan pada IIdentity tanpa semua fuzz ekstra .. itu akan luar biasa! Saya tahu ada pertanyaan serupa tentang SO, tetapi jika jawaban yang saya butuhkan ada di sana, saya pasti mengabaikannya.
MemberShip...
,Principal
,Identity
. ASP.NET harus membuat ini lebih mudah, lebih sederhana dan paling banyak dua pendekatan untuk menangani otentikasi.Jawaban:
Begini cara saya melakukannya.
Saya memutuskan untuk menggunakan IPrincipal daripada IIdentity karena itu berarti saya tidak harus mengimplementasikan IIdentity dan IPrincipal.
Buat antarmuka
CustomPrincipal
CustomPrincipalSerializeModel - untuk membuat serialisasi informasi khusus ke dalam bidang data pengguna di objek FormsAuthenticationTicket.
Metode LogIn - mengatur cookie dengan informasi khusus
Global.asax.cs - Membaca cookie dan mengganti objek HttpContext.User, ini dilakukan dengan mengganti PostAuthenticateRequest
Akses dalam tampilan Razor
dan dalam kode:
Saya pikir kodenya cukup jelas. Jika tidak, beri tahu saya.
Selain itu untuk membuat akses lebih mudah, Anda dapat membuat pengontrol dasar dan menimpa objek Pengguna yang dikembalikan (HttpContext.User):
dan kemudian, untuk setiap pengontrol:
yang akan memungkinkan Anda untuk mengakses bidang khusus dalam kode seperti ini:
Tapi ini tidak akan berfungsi dalam tampilan. Untuk itu, Anda perlu membuat implementasi WebViewPage khusus:
Jadikan ini tipe halaman default di Views / web.config:
dan dalam tampilan, Anda dapat mengaksesnya seperti ini:
sumber
Thread.CurrentPrincipal
diApplication_PostAuthenticateRequest
untuk itu untuk bekerja karena tidak bergantung padaHttpContext.Current.User
FormsAuthentication.SignOut();
berfungsi dengan baik untuk saya.Saya tidak dapat berbicara secara langsung untuk ASP.NET MVC, tetapi untuk Formulir Web ASP.NET, triknya adalah membuat
FormsAuthenticationTicket
dan mengenkripsinya menjadi cookie setelah pengguna diautentikasi. Dengan cara ini, Anda hanya perlu memanggil database sekali (atau AD atau apa pun yang Anda gunakan untuk melakukan otentikasi Anda), dan setiap permintaan berikutnya akan mengotentikasi berdasarkan tiket yang disimpan dalam cookie.Artikel bagus tentang ini:
http://www.ondotnet.com/pub/a/dotnet/2004/02/02/effectiveformsauth.html(tautan rusak)Edit:
Karena tautan di atas rusak, saya akan merekomendasikan solusi LukeP dalam jawabannya di atas: https://stackoverflow.com/a/10524305 - Saya juga menyarankan agar jawaban yang diterima diubah ke yang itu.
Sunting 2: Alternatif untuk tautan yang rusak: https://web.archive.org/web/20120422011422/http://ondotnet.com/pub/a/dotnet/2004/02/02/effectiveformsauth.html
sumber
Cache
sebagaiSession
pengganti untuk menyimpan data di server. Adakah yang bisa memberi tahu saya jika ini adalah pendekatan yang cacat?Ini adalah contoh untuk menyelesaikan pekerjaan. bool isValid diatur dengan melihat beberapa penyimpanan data (katakanlah basis data pengguna Anda). UserID hanya ID yang saya pertahankan. Anda dapat menambahkan informasi tambahan seperti alamat email ke data pengguna.
di golbal asax tambahkan kode berikut untuk mengambil kembali informasi Anda
Saat Anda akan menggunakan informasi nanti, Anda dapat mengakses kepala sekolah kustom Anda sebagai berikut.
ini akan memungkinkan Anda untuk mengakses informasi pengguna khusus.
sumber
MVC memberi Anda metode OnAuthorize yang tergantung dari kelas controller Anda. Atau, Anda dapat menggunakan filter tindakan khusus untuk melakukan otorisasi. MVC membuatnya sangat mudah dilakukan. Saya memposting posting blog tentang ini di sini. http://www.bradygaster.com/post/custom-authentication-with-mvc-3.0
sumber
Berikut adalah solusi jika Anda perlu menghubungkan beberapa metode ke @User untuk digunakan dalam pandangan Anda. Tidak ada solusi untuk kustomisasi keanggotaan serius, tetapi jika pertanyaan awal diperlukan untuk pandangan saja maka ini mungkin sudah cukup. Di bawah ini digunakan untuk memeriksa variabel yang dikembalikan dari filter otorisasi, digunakan untuk memverifikasi apakah beberapa tautan akan ditampilkan atau tidak (tidak untuk segala jenis logika otorisasi atau pemberian akses).
Kemudian tambahkan saja referensi di area web.config, dan beri nama seperti di bawah ini dalam tampilan.
sumber
Berdasarkan jawaban LukeP , dan menambahkan beberapa metode untuk mengatur
timeout
danrequireSSL
bekerja sama denganWeb.config
.Tautan referensi
Kode-kode LukeP yang Dimodifikasi
1, Set
timeout
berdasarkanWeb.Config
. The FormsAuthentication.Timeout akan mendapatkan nilai timeout, yang didefinisikan dalam web.config. Saya membungkus berikut ini menjadi fungsi, yang mengembalikanticket
punggung.2, Konfigurasikan cookie agar aman atau tidak, berdasarkan pada
RequireSSL
konfigurasi.sumber
Baiklah, jadi saya seorang cryptkeeper serius di sini dengan menyeret pertanyaan yang sangat lama ini, tetapi ada pendekatan yang lebih sederhana untuk ini, yang disentuh oleh @Baserz di atas. Dan itu adalah dengan menggunakan kombinasi metode C # Extension dan caching (JANGAN gunakan sesi).
Bahkan, Microsoft telah menyediakan sejumlah ekstensi seperti itu di
Microsoft.AspNet.Identity.IdentityExtensions
namespace. Misalnya,GetUserId()
adalah metode ekstensi yang mengembalikan ID pengguna. Ada jugaGetUserName()
danFindFirstValue()
, yang mengembalikan klaim berdasarkan IPrincipal.Jadi, Anda hanya perlu menyertakan namespace, dan kemudian menelepon
User.Identity.GetUserName()
untuk mendapatkan nama pengguna yang dikonfigurasi oleh ASP.NET Identity.Saya tidak yakin apakah ini di-cache, karena ASP.NET Identity yang lebih lama tidak bersumber terbuka, dan saya belum repot-repot merekayasa baliknya. Namun, jika tidak maka Anda dapat menulis metode ekstensi Anda sendiri, yang akan menyimpan hasil ini untuk jangka waktu tertentu.
sumber
IsUserAdministrator
atauUserEmail
dll? Kamu berpikirHttpRuntime.Cache
?Sebagai tambahan kode LukeP untuk pengguna Formulir Web (bukan MVC) jika Anda ingin menyederhanakan akses dalam kode di belakang halaman Anda, cukup tambahkan kode di bawah ini ke halaman dasar dan turunkan halaman dasar di semua halaman Anda:
Jadi dalam kode Anda di belakang Anda cukup mengakses:
Apa yang saya lewatkan dalam skenario Formulir Web, adalah bagaimana mendapatkan perilaku yang sama dalam kode yang tidak terikat ke halaman, misalnya dalam httpmodules haruskah saya selalu menambahkan gips di setiap kelas atau apakah ada cara yang lebih cerdas untuk mendapatkan ini?
Terima kasih atas jawaban Anda dan terima kasih kepada LukeP sejak saya menggunakan contoh Anda sebagai dasar untuk pengguna kustom saya (yang sekarang memiliki
User.Roles
,User.Tasks
,User.HasPath(int)
,User.Settings.Timeout
dan banyak hal-hal baik lainnya)sumber
Saya mencoba solusi yang disarankan oleh LukeP dan menemukan bahwa itu tidak mendukung atribut Otorisasi. Jadi, saya memodifikasinya sedikit.
Dan akhirnya di Global.asax.cs
Sekarang saya dapat mengakses data dalam tampilan dan pengontrol hanya dengan menelepon
Untuk keluar saya hanya menelepon
di mana AuthManager berada
sumber