Pengarang: Willmove && Heath Stewart
Halaman beranda: http://www.amuhouse.com
Email: [email protected]
Catatan: Saya baru mempelajari ASP.NET dua bulan lalu. Saya melihat artikel berjudul Keamanan Berbasis Peran dengan Otentikasi Formulir di codeproject.com dan merasa sangat membantu. Saat itu saya ingin menerjemahkannya ke dalam bahasa Mandarin. Namun, terjemahan langsung sungguh membosankan. Dalam dua hari terakhir, saya merujuk pada artikel Heath Stewart ini, dan berdasarkan pemahaman saya sendiri, saya menulisnya ke dalam bahasa Mandarin sesuai dengan ide dan ekspresi saya sendiri. Terlampir adalah aplikasi web demo yang saya buat untuk artikel ini.
Jika ada kesalahpahaman, silakan tulis untuk menunjukkannya atau tinggalkan komentar.
P.S. Spam sangat mengganggu, harap tunjukkan rasa hormat Anda.
Artikel aslinya ada di http://www.codeproject.com/aspnet/formsroleauth.asp
Penulis asliHeath Stewart
ringkasan:
ASP.NET menyediakan mekanisme otentikasi berbasis peran, namun dukungannya terhadap peran tidak lengkap. Artikel ini mencoba mengilustrasikan cara menerapkan dan menggunakan mekanisme autentikasi berbasis peran ini melalui beberapa contoh.
Pendahuluan:
Otentikasi formulir di ASP.NET adalah fitur yang sangat kuat yang hanya memerlukan sedikit kode untuk mengimplementasikan sistem otentikasi keamanan platform-independen yang sederhana.
Namun, jika Anda memerlukan mekanisme otentikasi yang lebih kompleks dan efisien, maka Anda perlu memanfaatkan fleksibilitasnya dengan membagi banyak pengguna ke dalam kelompok pengguna. Otentikasi Terintegrasi Windows menyediakan mekanisme otentikasi ini, tetapi menggunakan NTLM, Manajer LAN Windows NT, sehingga tidak lintas platform. Sekarang semakin banyak orang yang menggunakan sistem Linux, dan semakin banyak pula pengguna browser Mozilla Forefox. Kami tentu saja tidak dapat mencegah orang-orang ini keluar, jadi kami mencari mekanisme otentikasi lain. Ada dua opsi: yang pertama adalah membagi situs web menjadi beberapa area dan menyediakan beberapa halaman login, memaksa pengguna untuk mendaftar dan login satu per satu; yang lainnya adalah mengelompokkan pengguna dan membatasi hak akses grup pengguna tertentu ke halaman tertentu atau daerah. Yang terakhir tentu saja merupakan pilihan yang lebih baik. Kita dapat mencapai fungsi ini dengan menetapkan peran kepada masing-masing pengguna.
Microsoft meninggalkan mekanisme otentikasi berbasis peran dalam otentikasi formulir untuk platform .NET, tetapi kami harus mengimplementasikannya sendiri. Artikel ini berupaya untuk membahas beberapa hal mendasar tentang mekanisme otentikasi berbasis peran dalam otentikasi formulir, seperti konsepnya, implementasinya, cara menerapkannya dalam aplikasi web, dll.
Persiapan yang diperlukan:
Pertama-tama kita perlu membuat database, proyek aplikasi Web, beberapa direktori rahasia dengan tingkat keamanan berbeda, dan beberapa halaman ASP.NET. Tentu saja Anda juga dapat menambahkan ini ke proyek aplikasi web Anda yang sudah ada.
1. Untuk membuat database,
Anda harus terlebih dahulu memilih DBMS sistem manajemen database yang ingin Anda gunakan. Artikel ini menggunakan SQL Server 2000.
Dalam database proyek aplikasi sebenarnya, biasanya terdapat tabel data pengguna Pengguna, yang mungkin menyertakan tag unik pengguna: UserID, nama pengguna: Nama Pengguna, kata sandi: Kata sandi, alamat email pengguna: Email, kota pengguna: Kota, dan nomor login pengguna LoginCount dll. Anda dapat menetapkan peran kepada pengguna dengan membuat tabel data UserInRoles (umumnya mencakup dua bidang, nama pengguna: Nama Pengguna, peran pengguna: UserRoles).
Untuk mempermudah, saya hanya membuat tabel data Users yang memiliki 3 field, yaitu Username UserName, Password Password, dan User Roles UserRoles. Sebelum membuat tabel, Anda perlu memilih database atau membuat database baru. Untuk membuat database baru bernama WebSolution, hanya diperlukan pernyataan SQL sederhana:
kode program
Buat Solusi Web DATABASE
Untuk memilih database bernama msdb
di GO
, Anda dapat menggunakan pernyataan SQL:
kode program
GUNAKAN msdb
PERGI
Selanjutnya kita buat tabel data Users yang tadi disebutkan. Script SQL-nya adalah sebagai berikut:
Kode program
Buat TABEL Pengguna
(
Nama Pengguna nvarchar(100) KUNCI UTAMA PK_Nama Pengguna,
Kata sandi nvarchar(150),
Peran Pengguna nvarchar(100)
)
dapat membuat Kredensial indeks untuk tabel ini. Pernyataan SQL adalah sebagai berikut:
Kode program
Buat Kredensial INDEX PADA Pengguna
(
Nama belakang,
Kata sandi
)
Membuat indeks bersifat opsional dan terserah Anda. Silakan merujuk ke informasi yang relevan untuk mengetahui manfaat dan kerugian pengindeksan.
Kemudian kami menambahkan data ke database Pengguna ini. Nama karakter adalah pilihan Anda sendiri, tetapi sebaiknya gunakan nama yang bermakna, seperti
"Administrator" (administrator tingkat atas), "Manajer" (administrator), "Anggota" (anggota yang bergabung), "Pengguna" (pengguna biasa), dll. Misalnya:
Nama Pengguna|Kata Sandi|Peran
"akan pindah"|"pwd123"|"Administrator,Pengguna"
"amuhouse"|"pwd123"|"User"
adalah:
kode program
--perhatikan bahwa '45CB41B32DCFB917CCD8614F1536D6DA' adalah string yang dienkripsi oleh md5 menggunakan 'pwd123'
Masukkan KE Pengguna (Nama Pengguna, Kata Sandi, Peran Pengguna) NILAI ('akan bergerak','45CB41B32DCFB917CCD8614F1536D6DA','Administrator, Pengguna')
PERGI
Masukkan KE Pengguna (Nama Pengguna, Kata Sandi, Peran Pengguna) NILAI ('amuhouse','45CB41B32DCFB917CCD8614F1536D6DA','Pengguna')
PERGI
Perhatikan bahwa Peran peka huruf besar-kecil karena peka huruf besar-kecil di file Web.config. Sekarang kami membuat beberapa halaman yang diperlukan untuk menerapkan mekanisme otentikasi keamanan ini.
Yang pertama adalah halaman login pengguna Login.aspx
Jika Anda belum membuat aplikasi web, buatlah sekarang. Tentu saja Anda juga dapat membuat halaman ini di aplikasi web yang sudah ada. Di sini saya berasumsi bahwa aplikasi Web bernama RolebasedAuth telah dibuat (yaitu Proyek di Visual Studio .Net). Saya meletakkan Login.aspx ini di direktori root, yang dapat diakses melalui http://localhost/RolebasedAuth/Login.aspx .
Tidak masalah di mana Login.aspx ini ditempatkan, tetapi harus dapat diakses oleh publik.
Di bawah jalur root aplikasi, kami membuat dua subdirektori rahasia, yaitu Admin dan Pengguna.
Selanjutnya, kita membuat sistem login otentikasi formulir yang mendukung otentikasi peran. Karena Microsoft tidak menyediakan mekanisme implementasi yang sederhana, kami harus meluangkan waktu untuk membuat tiket otentikasi sendiri. Ini perlu menyimpan sejumlah kecil informasi. Tentu saja, beberapa nama harus sama dengan yang dikonfigurasi di Web.config, jika tidak, ASP.NET akan menganggap tiket otentikasi Anda tidak valid dan memaksa Anda untuk mengarahkan ke halaman login. Kami menambahkan dua kontrol TextBox ke Login.aspx di VS.NET dan menamainya UserNameTextBox dan PasswordTextBox. Kami juga menambahkan Button dan beri nama LoginButton. Klik untuk memasukkan kode latar belakang. Tambahkan kode yang diperlukan dalam metode LoginButton_Click. sebagai berikut:
kode program
private void LoginButton_Click(pengirim objek, System.EventArgs e)
{
//Inisialisasi FormsAuthentication
// Perhatikan bahwa ini ada di namespace System.Web.Security
// Jadi tambahkan menggunakan System.Web.Security di awal kode
FormsAuthentication.Initialize();
// Membuat koneksi database dan objek perintah operasi database
// Perhatikan bahwa ini ada di namespace System.Data.SqlClient
// Jadi tambahkan menggunakan System.Data.SqlClient di awal kode
Sambungan SqlConnection =
new SqlConnection("Sumber Data=sun-willmove;keamanan terintegrasi=SSPI;Katalog Awal=WebSolution;");
SqlCommand cmd = samb.CreateCommand();
cmd.CommandText = "Pilih Peran Pengguna DARI Pengguna Dimana Nama Pengguna=@namapengguna " +
"DAN Kata Sandi=@kata sandi ";
// Isi setiap parameter
cmd.Parameters.Add("@nama pengguna", SqlDbType.NVarChar, 100).Nilai =
NamaPenggunaKotakTeks.Teks;
cmd.Parameters.Add("@kata sandi", SqlDbType.NVarChar, 150).Nilai =
FormsAuthentication.HashPasswordForStoringInConfigFile(
PasswordTextBox.Text, "md5"); // atau "sha1"
// Jalankan perintah operasi database
samb.Buka();
Pembaca SqlDataReader = cmd.ExecuteReader();
jika (pembaca.Baca())
{
// Untuk menerapkan otentikasi, buat tiket baru
Tiket FormsAuthenticationTicket = FormsAuthenticationTicket baru(
1, // Nomor versi tiket
UserNameTextBox.Text, // Pemegang tiket
DateTime.Now, //Waktunya mengalokasikan tiket
DateTime.Now.AddMinutes(30), //Waktu habis masa berlaku
benar, //membutuhkan cookie pengguna
reader.GetString(0), // Data pengguna, inilah sebenarnya peran pengguna
FormsAuthentication.FormsCookiePath);//Jalur cookie yang valid
//Gunakan kunci mesin kode mesin untuk mengenkripsi cookie untuk transmisi yang aman
string hash = FormsAuthentication.Encrypt(tiket);
Kue HttpCookie = HttpCookie baru(
FormsAuthentication.FormsCookieName, // Nama cookie otentikasi
hash); //Cookie terenkripsi
//Atur waktu kedaluwarsa cookie agar konsisten dengan waktu kedaluwarsa tiket
if (ticket.IsPersistent) cookie.Expires = ticket.Expiration;
//Tambahkan cookie ke respons permintaan halaman
Response.Cookies.Add(cookie);
//Arahkan pengguna ke halaman yang diminta sebelumnya,
// Jika tidak ada halaman yang diminta sebelumnya, arahkan ke beranda
string returnUrl = Permintaan.QueryString["ReturnUrl"];
if (returnUrl == null) returnUrl = "./";
// Jangan panggil metode FormsAuthentication.RedirectFromLoginPage.
// Karena akan menggantikan tiket (cookie) yang baru saja ditambahkan
Respon.Redirect(returnUrl);
}
kalau tidak
{
// Jangan memberi tahu pengguna "Kata sandi salah", ini sama dengan memberi kesempatan kepada penyusup.
// Karena mereka mengetahui nama pengguna yang mereka masukkan ada
//
ErrorLabel.Text = "Nama pengguna atau kata sandi salah, silakan coba lagi!";
ErrorLabel.Terlihat = benar;
}
pembaca.Tutup();
samb.Tutup();
}
Kode halaman aspx front-end adalah sebagai berikut:
kode program
<%@ Halaman bahasa="c#" Codebehind="Login.aspx.cs" AutoEventWireup="false" Inherits="RolebasedAuth.Login" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transisi//EN" >
<HTML>
<KEPALA>
<judul>Masuk</judul>
<meta name="GENERATOR" Content="Microsoft Visual Studio .NET 7.1">
<meta name="CODE_LANGUAGE" Konten="C#">
<meta name="vs_defaultClientScript" content="JavaScript">
<meta name="vs_targetSchema" content=" http://schemas.microsoft.com/intellisense/ie5 ">
</KEPALA>
<tubuh>
<form id="Form1" metode="posting" runat="server">
<P>
<asp:Label id="Label1" runat="server">Nama pengguna:</asp:Label>
<asp:TextBox id="UserNameTextBox" runat="server"></asp:TextBox></P>
<P><FONT wajah="宋体"> </FONT>
<asp:Label id="Label2" runat="server">Sandi:</asp:Label>
<asp:TextBox id="PasswordTextBox" runat="server" TextMode="Password"></asp:TextBox></P>
<P>
<asp:Label id="ErrorLabel" runat="server" Visible="False"></asp:Label></P>
<P>
<asp:Button id="LoginButton" runat="server" Text="Login"></asp:Button></P>
</bentuk>
</tubuh>
</HTML>
Anda akan melihat apa yang kami lakukan dengan kata sandi di atas: melakukan hashing. Enkripsi hash adalah algoritma satu arah (tidak dapat diubah) yang menghasilkan serangkaian karakter unik. Jadi mengubah huruf besar/kecil satu huruf saja pada kata sandi akan menghasilkan kolom hash yang benar-benar berbeda. Kami menyimpan kata sandi terenkripsi ini di database, yang lebih aman. Dalam aplikasi praktis, Anda mungkin ingin mengambil kata sandi pengguna yang terlupa. Namun hashing tidak dapat diubah, jadi Anda tidak akan dapat memulihkan kata sandi asli. Namun Anda dapat mengubah kata sandi pengguna dan memberi tahu dia kata sandi yang diubah. Jika sebuah situs web dapat memberi Anda kata sandi lama, maka Anda perlu berpikir jernih, data pengguna Anda tidak aman! Faktanya, sebagian besar situs web domestik langsung menyimpan kata sandi pengguna di database tanpa enkripsi. Jika peretas berhasil, akun pengguna ini dalam bahaya!
Tanpa SSL, kata sandi Anda dikirimkan dalam bentuk teks yang jelas melalui jaringan. Ini mungkin dicuri selama transmisi. Mengenkripsi kata sandi di sisi server hanya menjamin keamanan penyimpanan kata sandi. Informasi terkait SSL dapat ditemukan di http://www.versign.com atau http://www.thewte.com .
Jika Anda tidak ingin menyimpan kata sandi di database terenkripsi, Anda dapat mengubah kode di atas menjadi
FormsAuthentication.HashPasswordForStoringInConfigFile(PasswordTextBox.Text, "md5") dapat diubah menjadi PasswordTextBox.Text.
Selanjutnya, kita perlu memodifikasi file Global.asax. Jika aplikasi web Anda tidak memiliki file ini, silakan klik kanan proyek aplikasi web dan pilih "Tambah->Tambahkan Item Baru...->Kelas Aplikasi Global". Di Global.asax atau Global.asax.cs, temukan metode (fungsi) yang disebut Application_AuthenticationRequest. Pertama-tama konfirmasikan bahwa namespace System.Security.Principal dan System.Web.Security telah disertakan atau digunakan, lalu modifikasi kode yang dimodifikasi:
kode program
dilindungi kekosongan Application_AuthenticateRequest(Pengirim objek, EventArgs e)
{
jika (HttpContext.Saat ini.Pengguna != null)
{
if (HttpContext.Current.User.Identity.IsAuthenticated)
{
jika (HttpContext.Current.User.Identity adalah FormsIdentity)
{
Id Identitas Formulir =
(FormsIdentity)HttpContext.Current.User.Identity;
FormsAuthenticationTicket ticket = id.Ticket;
// Dapatkan data pengguna yang tersimpan di tiket, yang sebenarnya merupakan peran pengguna di sini
string data pengguna = tiket.Data Pengguna;
string[] peran = data pengguna.Split(',');
HttpContext.Current.User = GenericPrincipal baru(id, peran);
}
}
}
}
Tiket otentikasi (nama pengguna dan kata sandi) tidak disimpan sebagai bagian dari cookie, dan tidak dapat disimpan karena pengguna dapat mengubah cookie mereka.
Faktanya, FormsAuthentication menggunakan kunci mesin Anda (biasanya di machine.config) untuk mengenkripsi tiket (FormsAuthenticationTicket). Kami menggunakan UserData untuk menyimpan peran pengguna dan menghasilkan kredensial baru. Setelah kredensial dibuat, kredensial tersebut ditambahkan ke konteks saat ini (yaitu HttpContext) sehingga dapat digunakan untuk mengambil peran pengguna.
Selanjutnya, kita menyiapkan direktori rahasia (yaitu, "direktori keamanan", direktori yang hanya boleh diakses oleh pengguna tertentu seperti administrator). Pertama periksa apakah ada file Web.config di direktori root aplikasi web Anda. Anda juga dapat membuat file Web.config di subdirektori Anda. Tentu saja, file Web.config ini dibatasi (beberapa parameter tidak dapat diatur).
Untuk menerapkan otentikasi keamanan, temukankode program
di bawah node <system.web> di file Web.config di direktori root aplikasi Web.
<authentication mode="Windows" />, ubah menjadi
<authentication mode="Forms">
<bentuk nama="AMUHOUSE.ASPXAUTH"
loginUrl="Masuk.aspx"
perlindungan="Semua"
jalur="./" />
</otentikasi>
<otorisasi>
<izinkan pengguna="*"/>
</authorization>
Pada nama="AMUHOUSE.ASPXAUTH" di atas, nama AMUHOUSE.ASPXAUTH bersifat arbitrer. Untuk mengontrol izin pengguna atau grup pengguna, kita dapat memiliki dua metode: Pertama adalah mengkonfigurasi file Web.config di direktori root aplikasi, dan yang lainnya adalah membuat file Web.config independen di direktori rahasia. (Yang terakhir mungkin lebih baik.) Jika yang pertama, Web.config harus berisi konten berikut (atau konten serupa):
kode program
<konfigurasi>
<sistem.web>
<mode autentikasi="Formulir">
<bentuk nama="AMUHOUSE.ASPXAUTH"
loginUrl="login.aspx"
perlindungan="Semua"
jalur="/"/>
</otentikasi>
<otorisasi>
<izinkan pengguna="*"/>
</otorisasi>
</sistem.web>
<jalur lokasi="./Admin">
<sistem.web>
<otorisasi>
<!-- Perhatian! Urutan dan huruf besar/kecil dari baris berikut ini sangat penting! -->
<izinkan peran="Administrator"/>
<menolak pengguna="*"/>
</otorisasi>
</sistem.web>
</lokasi>
<jalur lokasi="./Pengguna">
<sistem.web>
<otorisasi>
<!-- Perhatian! Urutan dan huruf besar/kecil dari baris berikut ini sangat penting! -->
<izinkan peran="Pengguna"/>
<menolak pengguna="*"/>
</otorisasi>
</sistem.web>
</lokasi>
</konfigurasi>
Untuk membuat direktori aplikasi web tidak bergantung satu sama lain sebelumnya dan memudahkan untuk mengganti nama atau memindahkannya, Anda dapat memilih untuk mengonfigurasi file Web.config terpisah di setiap subdirektori keamanan. Ia hanya perlu mengkonfigurasi node <authorization/>, sebagai berikut:
kode program
<konfigurasi>
<sistem.web>
<otorisasi>
<!-- Perhatian! Urutan dan huruf besar/kecil dari baris berikut ini sangat penting! -->
<izinkan peran="Administrator"/>
<menolak pengguna="*"/>
</otorisasi>
</sistem.web>
</konfigurasi>
Perlu diingatkan kembali bahwa peran di atas peka huruf besar-kecil. Untuk kenyamanan, Anda juga dapat memodifikasi peran di atas menjadi:
<izinkan peran="Administrator,administrator" />
Jika Anda ingin mengizinkan atau menolak akses beberapa peran ke direktori ini, Anda dapat memisahkannya dengan koma, seperti:
<izinkan peran="Administrator,Anggota,Pengguna" />
<deny users="*" />
Pada titik ini, kami telah mengonfigurasi mekanisme otentikasi keamanan berbasis peran untuk situs web. Anda dapat mengkompilasi program Anda terlebih dahulu, lalu mencoba mengakses direktori rahasia, seperti http://localhost/RolebasedAuth/Admin , yang pada saat itu Anda akan diarahkan ke halaman login pengguna. Jika Anda berhasil masuk dan peran Anda memiliki hak akses ke direktori ini, Anda akan kembali ke direktori ini. Mungkin ada pengguna (atau penyusup) yang mencoba masuk ke direktori rahasia. Kita dapat menggunakan Sesi untuk menyimpan berapa kali pengguna telah login. Jika jumlahnya melebihi angka tertentu, pengguna tidak akan diizinkan untuk login, dan "Sistem telah menolak permintaan login Anda!"
Di bawah ini, kami membahas cara membuat kontrol web menampilkan konten berbeda berdasarkan peran pengguna.
Terkadang lebih baik menampilkan konten berdasarkan peran pengguna, karena Anda mungkin tidak ingin membuat banyak halaman dengan banyak konten duplikat untuk begitu banyak peran berbeda (grup pengguna). Di situs tersebut, berbagai akun pengguna dapat hidup berdampingan, dan akun pengguna berbayar dapat mengakses konten berbayar tambahan. Contoh lainnya adalah halaman yang akan menampilkan tombol "Masukkan Admin" yang menghubungkan ke halaman Admin jika pengguna saat ini berada dalam peran "Administrator". Kami akan menerapkan halaman ini sekarang.
Kelas GenericPrincipal yang kami gunakan di atas mengimplementasikan antarmuka IPincipal. Antarmuka ini memiliki metode yang disebut IsInRole(), dan parameternya adalah string. Jika kita ingin menampilkan konten kepada pengguna login yang berperan sebagai "Administrator", kita dapat menambahkan kode berikut di Page_Load:
Kode program
if (Pengguna.IsInRole("Administrator"))
AdminLink.Visible = true;
Kode halaman keseluruhannya adalah sebagai berikut (untuk mempermudah, kode background juga ditulis di halaman aspx):
kode program
<html>
<kepala>
<judul>Selamat datang! </judul>
<skrip runat="server">
dilindungi kekosongan Page_Load(Pengirim objek, EventArgs e)
{
if (Pengguna.IsInRole("Administrator"))
AdminLink.Visible = benar;
kalau tidak
AdminLink.Visible = salah;
}
</skrip>
</kepala>
<tubuh>
<h2>Selamat datang! </h2>
<p>Selamat datang di Rumah Amu http://amuhouse.com/ ^_^</p>
<asp:HyperLink id="AdminLink" runat="server"
Text="Halaman Beranda Admin" NavigateUrl="./Admin"/>
</tubuh>
</html>
Dengan cara ini, kontrol HyperLink yang terhubung ke direktori Admin hanya akan ditampilkan kepada pengguna yang berperan sebagai Administrator. Anda juga dapat memberikan link ke halaman login kepada pengguna yang belum login, seperti:
kode program
dilindungi kekosongan Page_Load (pengirim objek, System.EventArgs e)
{
if (Pengguna.IsInRole("Administrator"))
{
AdminLink.Text = "Administrator silakan masuk";
AdminLink.NavigateUrl="./Admin";
}
else if(Pengguna.IsInRole("Pengguna"))
{
AdminLink.Text = "Pengguna terdaftar silakan masuk";
AdminLink.NavigateUrl="./Pengguna";
}
kalau tidak
{
AdminLink.Text = "Silakan masuk";
AdminLink.NavigateUrl="Login.aspx?ReturnUrl=" + Permintaan.Jalur;
}
}
Di sini, dengan menyetel variabel QueryString yang disebut ReturnUrl, kita dapat mengembalikan pengguna ke halaman saat ini setelah login berhasil.
ringkasan:
Artikel ini digunakan untuk membantu Anda memahami pentingnya dan kepraktisan mekanisme keamanan berbasis peran, dan juga menggunakan ASP.NET untuk mengimplementasikan mekanisme keamanan berbasis peran. Ini bukan mekanisme yang sulit untuk diterapkan, namun mungkin memerlukan pengetahuan tentang kredensial pengguna, cara mengautentikasi pengguna, dan cara mengautentikasi pengguna yang berwenang. Saya akan sangat senang jika Anda merasa terbantu. Saya harap ini dapat memandu Anda dalam menerapkan otentikasi keamanan formulir berbasis peran di situs web Anda.
Terlampir:
Contoh kode sumber proyek untuk artikel ini: