Bagikan melalui


Otorisasi Role-Based (C#)

oleh Scott Mitchell

Catatan

Sejak artikel ini ditulis, penyedia Keanggotaan ASP.NET telah digantikan oleh ASP.NET Identity. Kami sangat menyarankan untuk memperbarui aplikasi untuk menggunakan platform identitas ASP.NET daripada penyedia Keanggotaan yang ditampilkan pada saat artikel ini ditulis. ASP.NET Identity memiliki sejumlah keunggulan dibandingkan sistem Keanggotaan ASP.NET, termasuk :

  • Performa yang lebih baik
  • Peningkatan ekstensibilitas dan kemampuan pengujian
  • Dukungan untuk OAuth, OpenID Connect, dan autentikasi dua faktor
  • Dukungan Identitas berbasis klaim
  • Interoperabilitas yang lebih baik dengan ASP.Net Core

Unduh Kode atau Unduh PDF

Tutorial ini dimulai dengan melihat bagaimana kerangka kerja Peran mengaitkan peran pengguna dengan konteks keamanannya. Kemudian memeriksa cara menerapkan aturan otorisasi URL berbasis peran. Setelah itu, kita akan melihat menggunakan cara deklaratif dan terprogram untuk mengubah data yang ditampilkan dan fungsionalitas yang ditawarkan oleh halaman ASP.NET.

Pengantar

Dalam tutorial Otorisasi Berbasis Pengguna, kami melihat cara menggunakan otorisasi URL untuk menentukan apa yang dapat dikunjungi pengguna pada sekumpulan halaman tertentu. Hanya dengan sedikit markup di Web.config, kami dapat menginstruksikan ASP.NET untuk memungkinkan hanya pengguna yang diautentikasi untuk mengunjungi halaman. Atau kita dapat menentukan bahwa hanya pengguna Tito dan Bob yang diizinkan, atau menunjukkan bahwa semua pengguna yang diautentikasi kecuali Sam diizinkan.

Selain otorisasi URL, kami juga melihat teknik deklaratif dan terprogram untuk mengontrol data yang ditampilkan dan fungsionalitas yang ditawarkan oleh halaman berdasarkan kunjungan pengguna. Secara khusus, kami membuat halaman yang mencantumkan konten direktori saat ini. Siapa pun dapat mengunjungi halaman ini, tetapi hanya pengguna terautentikasi yang dapat melihat isi file dan hanya Tito yang dapat menghapus file.

Menerapkan aturan otorisasi berdasarkan pengguna demi pengguna dapat tumbuh menjadi mimpi buruk pembbukuan. Pendekatan yang lebih dapat dipertahankan adalah menggunakan otorisasi berbasis peran. Kabar baiknya adalah bahwa alat yang kami gunakan untuk menerapkan aturan otorisasi bekerja sama baiknya dengan peran seperti yang mereka lakukan untuk akun pengguna. Aturan otorisasi URL dapat menentukan peran alih-alih pengguna. Kontrol LoginView, yang merender output yang berbeda untuk pengguna yang diautentikasi dan anonim, dapat dikonfigurasi untuk menampilkan konten yang berbeda berdasarkan peran pengguna yang masuk. Dan ROLES API menyertakan metode untuk menentukan peran pengguna yang masuk.

Tutorial ini dimulai dengan melihat bagaimana kerangka kerja Peran mengaitkan peran pengguna dengan konteks keamanannya. Kemudian memeriksa cara menerapkan aturan otorisasi URL berbasis peran. Setelah itu, kita akan melihat menggunakan cara deklaratif dan terprogram untuk mengubah data yang ditampilkan dan fungsionalitas yang ditawarkan oleh halaman ASP.NET. Mari kita mulai!

Memahami Bagaimana Peran Dikaitkan dengan Konteks Keamanan Pengguna

Setiap kali permintaan memasuki alur ASP.NET, permintaan tersebut dikaitkan dengan konteks keamanan, yang mencakup informasi yang mengidentifikasi pemohon. Saat menggunakan autentikasi formulir, tiket autentikasi digunakan sebagai token identitas. Seperti yang kita bahas dalam tutorial Gambaran Umum Autentikasi Formulir, FormsAuthenticationModule bertanggung jawab untuk menentukan identitas pemohon, yang dilakukannya selama AuthenticateRequest acara.

Jika tiket autentikasi yang valid dan tidak kedaluwarsa ditemukan, FormsAuthenticationModule dekodenya untuk memastikan identitas pemohon. Ini membuat objek baru GenericPrincipal dan menetapkan ini ke HttpContext.User objek . Tujuan dari prinsipal, seperti GenericPrincipal, adalah untuk mengidentifikasi nama pengguna yang diautentikasi dan peran apa yang dimilikinya. Tujuan ini terbukti oleh fakta bahwa semua objek utama memiliki Identity properti dan IsInRole(roleName) metode . Namun FormsAuthenticationModule, , tidak tertarik untuk merekam informasi peran dan objek yang GenericPrincipal dibuatnya tidak menentukan peran apa pun.

Jika kerangka kerja Peran diaktifkan, RoleManagerModule Modul HTTP akan masuk setelah FormsAuthenticationModule dan mengidentifikasi peran pengguna yang diautentikasi selama PostAuthenticateRequest peristiwa, yang diaktifkan setelah AuthenticateRequest peristiwa. Jika permintaan berasal dari pengguna yang diautentikasi, RoleManagerModule objek akan ditimpa GenericPrincipal oleh FormsAuthenticationModule dan menggantinya dengan RolePrincipal objek . Kelas RolePrincipal menggunakan Roles API untuk menentukan peran apa yang dimiliki pengguna.

Gambar 1 menggambarkan alur kerja alur ASP.NET saat menggunakan autentikasi formulir dan kerangka kerja Peran. FormsAuthenticationModule Eksekusi pertama, mengidentifikasi pengguna melalui tiket autentikasinya, dan membuat objek baruGenericPrincipal. Selanjutnya, langkah-langkah RoleManagerModule dalam dan menimpa GenericPrincipal objek dengan RolePrincipal objek .

Jika pengguna anonim mengunjungi situs, baik pengguna maupun FormsAuthenticationModule yang RoleManagerModule membuat objek utama.

Peristiwa Alur ASP.NET untuk Pengguna yang Diautentikasi Saat Menggunakan Autentikasi Formulir dan Kerangka Kerja Peran

Gambar 1: Peristiwa Alur ASP.NET untuk Pengguna Terautentikasi Saat Menggunakan Autentikasi Formulir dan Kerangka Kerja Peran (Klik untuk melihat gambar ukuran penuh)

Metode RolePrincipal objek IsInRole(roleName) memanggil Roles.GetRolesForUser untuk mendapatkan peran bagi pengguna untuk menentukan apakah pengguna adalah anggota roleName. Saat menggunakan SqlRoleProvider, ini menghasilkan kueri ke database penyimpanan peran. Saat menggunakan aturan RolePrincipalotorisasi URL berbasis peran, metode akan IsInRole dipanggil pada setiap permintaan ke halaman yang dilindungi oleh aturan otorisasi URL berbasis peran. Daripada harus mencari informasi peran dalam database pada setiap permintaan, kerangka kerja Peran menyertakan opsi untuk menyimpan peran pengguna dalam cookie.

Jika kerangka kerja Peran dikonfigurasi untuk menyimpan peran pengguna dalam cookie, RoleManagerModule membuat cookie selama peristiwa alur EndRequestASP.NET. Cookie ini digunakan dalam permintaan berikutnya dalam PostAuthenticateRequest, yaitu ketika RolePrincipal objek dibuat. Jika cookie valid dan belum kedaluwarsa, data dalam cookie diurai dan digunakan untuk mengisi peran pengguna, sehingga menyimpan RolePrincipal dari keharusan melakukan panggilan ke Roles kelas untuk menentukan peran pengguna. Gambar 2 menggambarkan alur kerja ini.

Informasi Peran Pengguna Dapat Disimpan dalam Cookie untuk Meningkatkan Performa

Gambar 2: Informasi Peran Pengguna Dapat Disimpan dalam Cookie untuk Meningkatkan Performa (Klik untuk melihat gambar ukuran penuh)

Secara default, mekanisme cookie cache peran dinonaktifkan. Ini dapat diaktifkan melalui <roleManager> markup konfigurasi di Web.config. Kami membahas menggunakan <roleManager> elemen untuk menentukan penyedia Peran dalam tutorial Membuat dan Mengelola Peran, jadi Anda harus sudah memiliki elemen ini dalam file aplikasi Web.config Anda. Pengaturan cookie cache peran ditentukan sebagai atribut <roleManager> elemen , dan dirangkum dalam Tabel 1.

Catatan

Pengaturan konfigurasi yang tercantum dalam Tabel 1 menentukan properti cookie cache peran yang dihasilkan. Untuk informasi lebih lanjut tentang cookie, cara kerjanya, dan berbagai propertinya, baca tutorial Cookie ini.

Properti Deskripsi
cacheRolesInCookie Nilai Boolean yang menunjukkan apakah penembolokan cookie digunakan. Default ke false.
cookieName Nama cookie cache peran. Nilai defaultnya adalah ". ASPXROLES".
cookiePath Jalur untuk cookie nama peran. Atribut jalur memungkinkan pengembang untuk membatasi cakupan cookie ke hierarki direktori tertentu. Nilai defaultnya adalah "/", yang menginformasikan browser untuk mengirim cookie tiket autentikasi ke permintaan apa pun yang dibuat ke domain.
cookieProtection Menunjukkan teknik apa yang digunakan untuk melindungi cookie cache peran. Nilai yang diperbolehkan adalah: All (default); Encryption; ; Nonedan Validation.
cookieRequireSSL Nilai Boolean yang menunjukkan apakah koneksi SSL diperlukan untuk mengirimkan cookie autentikasi. Nilai defaultnya adalah false.
cookieSlidingExpiration Nilai Boolean yang menunjukkan apakah batas waktu cookie diatur ulang setiap kali pengguna mengunjungi situs selama satu sesi. Nilai defaultnya adalah false. Nilai ini hanya berkaitan ketika createPersistentCookie diatur ke true.
cookieTimeout Menentukan waktu, dalam hitungan menit, setelah cookie tiket autentikasi kedaluwarsa. Nilai defaultnya adalah 30. Nilai ini hanya berkaitan ketika createPersistentCookie diatur ke true.
createPersistentCookie Nilai Boolean yang menentukan apakah cookie cache peran adalah cookie sesi atau cookie persisten. Jika false (default), cookie sesi digunakan, yang dihapus saat browser ditutup. Jika true, cookie persisten digunakan; cookie kedaluwarsa cookieTimeout jumlah menit setelah dibuat atau setelah kunjungan sebelumnya, tergantung pada nilai cookieSlidingExpiration.
domain Menentukan nilai domain cookie. Nilai default adalah string kosong, yang menyebabkan browser menggunakan domain tempatnya dikeluarkan (seperti www.yourdomain.com). Dalam hal ini, cookie tidak akan dikirim saat membuat permintaan ke subdomain, seperti admin.yourdomain.com. Jika Anda ingin cookie diteruskan ke semua subdomain, Anda perlu menyesuaikan domain atribut, atur ke "yourdomain.com".
maxCachedResults Menentukan jumlah maksimum nama peran yang di-cache dalam cookie. Defaultnya adalah 25. RoleManagerModule tidak membuat cookie untuk pengguna yang termasuk dalam lebih dari maxCachedResults peran. Akibatnya, RolePrincipal metode objek IsInRole akan menggunakan Roles kelas untuk menentukan peran pengguna. Alasannya maxCachedResults ada karena banyak agen pengguna tidak mengizinkan cookie yang lebih besar dari 4.096 byte. Jadi batas ini dimaksudkan untuk mengurangi kemungkinan melebihi batasan ukuran ini. Jika Anda memiliki nama peran yang sangat panjang, Anda mungkin ingin mempertimbangkan untuk menentukan nilai yang lebih maxCachedResults kecil; sebaliknya, jika Anda memiliki nama peran yang sangat pendek, Anda mungkin dapat meningkatkan nilai ini.

Tabel 1: Opsi Konfigurasi Cookie Cache Peran

Mari kita konfigurasikan aplikasi kita untuk menggunakan cookie cache peran yang tidak persisten. Untuk mencapai hal ini, perbarui <roleManager> elemen untuk Web.config menyertakan atribut terkait cookie berikut:

<roleManager enabled="true"    
          defaultProvider="SecurityTutorialsSqlRoleProvider"    
          cacheRolesInCookie="true"    
          createPersistentCookie="false"    
          cookieProtection="All">    

     <providers>    
     ...    
     </providers>    
</roleManager>

Saya memperbarui <roleManager> elemen dengan menambahkan tiga atribut: cacheRolesInCookie, createPersistentCookie, dan cookieProtection. Dengan mengatur cacheRolesInCookie ke true, RoleManagerModule sekarang akan secara otomatis menyimpan peran pengguna dalam cookie daripada harus mencari informasi peran pengguna pada setiap permintaan. Saya secara eksplisit mengatur createPersistentCookie atribut dan cookieProtection ke false dan All, masing-masing. Secara teknis, saya tidak perlu menentukan nilai untuk atribut ini karena saya baru saja menetapkannya ke nilai default mereka, tetapi saya menempatkannya di sini untuk membuatnya secara eksplisit jelas bahwa saya tidak menggunakan cookie persisten dan bahwa cookie dienkripsi dan divalidasi.

Hanya itu saja! Oleh karena itu, kerangka kerja Peran akan menyimpan peran pengguna dalam cookie. Jika browser pengguna tidak mendukung cookie, atau jika cookie mereka dihapus atau hilang, entah bagaimana, itu bukan masalah besar - RolePrincipal objek hanya akan menggunakan Roles kelas jika tidak ada cookie (atau yang tidak valid atau kedaluwarsa) tersedia.

Catatan

Grup Pola & Praktik Microsoft mencegah penggunaan cookie cache peran persisten. Karena kepemilikan cookie cache peran cukup untuk membuktikan keanggotaan peran, jika peretas entah bagaimana bisa mendapatkan akses ke cookie pengguna yang valid, ia dapat meniru pengguna tersebut. Kemungkinan hal ini terjadi meningkat jika cookie tetap ada di browser pengguna. Untuk informasi selengkapnya tentang rekomendasi keamanan ini, serta masalah keamanan lainnya, lihat Daftar Pertanyaan Keamanan untuk ASP.NET 2.0.

Langkah 1: Menentukan Aturan Otorisasi URL Role-Based

Seperti yang dibahas dalam tutorial Otorisasi Berbasis Pengguna, otorisasi URL menawarkan sarana untuk membatasi akses ke sekumpulan halaman berdasarkan pengguna demi pengguna atau peran demi peran. Aturan otorisasi URL dieja dalam Web.config menggunakan <authorization> elemen dengan <allow> elemen turunan dan <deny> . Selain aturan otorisasi terkait pengguna yang dibahas dalam tutorial sebelumnya, masing-masing <allow> dan <deny> elemen anak juga dapat mencakup:

  • Peran tertentu
  • Daftar peran yang dibatasi koma

Misalnya, aturan otorisasi URL memberikan akses ke pengguna tersebut dalam peran Administrator dan Supervisor, tetapi menolak akses ke semua orang lain:

<authorization>
     <allow roles="Administrators, Supervisors" />
     <deny users="*" />
</authorization>

Elemen <allow> dalam markup di atas menyatakan bahwa peran Administrator dan Supervisor diizinkan; <deny> elemen menginstruksikan bahwa semua pengguna ditolak.

Mari kita konfigurasikan aplikasi kita sehingga ManageRoles.aspxhalaman , UsersAndRoles.aspx, dan CreateUserWizardWithRoles.aspx hanya dapat diakses oleh pengguna tersebut dalam peran Administrator, sementara RoleBasedAuthorization.aspx halaman tetap dapat diakses oleh semua pengunjung.

Untuk mencapai hal ini, mulailah dengan menambahkan Web.config file ke Roles folder .

Menambahkan File Web.config ke direktori Peran

Gambar 3: Tambahkan Web.config File ke Roles direktori (Klik untuk melihat gambar ukuran penuh)

Selanjutnya, tambahkan markup konfigurasi berikut ke Web.config:

<?xml version="1.0"?>    

<configuration>    
     <system.web>    
          <authorization>    
               <allow roles="Administrators" />    
               <deny users="*"/>    
          </authorization>    

     </system.web>

     <!-- Allow all users to visit RoleBasedAuthorization.aspx -->    
     <location path="RoleBasedAuthorization.aspx">    
          <system.web>    
               <authorization>    
                    <allow users="*" />    

               </authorization>    
          </system.web>    
     </location>    
</configuration>

Elemen <authorization> di bagian <system.web> menunjukkan bahwa hanya pengguna dalam peran Administrator yang dapat mengakses sumber daya ASP.NET di Roles direktori. Elemen <location> menentukan sekumpulan aturan otorisasi URL alternatif untuk halaman, RoleBasedAuthorization.aspx memungkinkan semua pengguna mengunjungi halaman.

Setelah menyimpan perubahan Anda ke Web.config, masuk sebagai pengguna yang tidak berada dalam peran Administrator lalu coba kunjungi salah satu halaman yang dilindungi. UrlAuthorizationModule akan mendeteksi bahwa Anda tidak memiliki izin untuk mengunjungi sumber daya yang diminta; akibatnya, FormsAuthenticationModule akan mengarahkan Anda ke halaman masuk. Halaman masuk kemudian akan mengarahkan Anda ke UnauthorizedAccess.aspx halaman (lihat Gambar 4). Pengalihan akhir dari halaman masuk ini terjadi UnauthorizedAccess.aspx karena kode yang kami tambahkan ke halaman masuk di Langkah 2 tutorial Otorisasi Berbasis Pengguna . Secara khusus, halaman masuk secara otomatis mengalihkan pengguna yang diautentikasi ke UnauthorizedAccess.aspx jika querystring berisi ReturnUrl parameter, karena parameter ini menunjukkan bahwa pengguna tiba di halaman masuk setelah mencoba melihat halaman yang tidak diizinkan untuk dilihatnya.

Hanya Pengguna dalam Peran Administrator yang Dapat Melihat Halaman yang Dilindungi

Gambar 4: Hanya Pengguna dalam Peran Administrator yang Dapat Melihat Halaman yang Dilindungi (Klik untuk melihat gambar ukuran penuh)

Keluar lalu masuk sebagai pengguna yang berada dalam peran Administrator. Sekarang Anda akan dapat melihat tiga halaman yang dilindungi.

Tito Dapat Mengunjungi Halaman UsersAndRoles.aspx Karena Dia berada dalam Peran Administrator

Gambar 5: Tito Dapat Mengunjungi UsersAndRoles.aspx Halaman Karena Dia berada dalam Peran Administrator (Klik untuk melihat gambar ukuran penuh)

Catatan

Saat menentukan aturan otorisasi URL - untuk peran atau pengguna - penting untuk diingat bahwa aturan dianalisis satu per satu, dari atas ke bawah. Segera setelah kecocokan ditemukan, pengguna diberikan atau ditolak aksesnya, tergantung pada apakah kecocokan ditemukan dalam <allow> elemen atau <deny> . Jika tidak ada kecocokan yang ditemukan, pengguna diberikan akses. Akibatnya, jika Anda ingin membatasi akses ke satu atau beberapa akun pengguna, sangat penting bagi Anda untuk menggunakan <deny> elemen sebagai elemen terakhir dalam konfigurasi otorisasi URL. Jika aturan otorisasi URL Anda tidak menyertakan<deny>elemen, semua pengguna akan diberikan akses. Untuk diskusi yang lebih menyeluruh tentang bagaimana aturan otorisasi URL dianalisis, lihat kembali bagian "Lihat Bagaimana UrlAuthorizationModule Menggunakan Aturan Otorisasi untuk Memberikan atau Menolak Akses" dari tutorial Otorisasi Berbasis Pengguna.

Langkah 2: Membatasi Fungsionalitas Berdasarkan Peran Pengguna yang Saat Ini Masuk

Otorisasi URL memudahkan untuk menentukan aturan otorisasi kasar yang menyatakan identitas apa yang diizinkan dan mana yang ditolak untuk melihat halaman tertentu (atau semua halaman dalam folder dan subfoldernya). Namun, dalam kasus tertentu kami mungkin ingin mengizinkan semua pengguna mengunjungi halaman, tetapi membatasi fungsionalitas halaman berdasarkan peran pengguna yang mengunjungi. Ini mungkin memerlukan untuk menampilkan atau menyembunyikan data berdasarkan peran pengguna, atau menawarkan fungsionalitas tambahan kepada pengguna yang termasuk dalam peran tertentu.

Aturan otorisasi berbasis peran butir halus tersebut dapat diterapkan baik secara deklaratif atau terprogram (atau melalui beberapa kombinasi keduanya). Di bagian berikutnya kita akan melihat cara menerapkan otorisasi butiran halus deklaratif melalui kontrol LoginView. Setelah itu, kita akan mengeksplorasi teknik terprogram. Namun, sebelum kita dapat melihat penerapan aturan otorisasi butir halus, pertama-tama kita perlu membuat halaman yang fungsionalitasnya tergantung pada peran pengguna yang mengunjunginya.

Mari kita buat halaman yang mencantumkan semua akun pengguna dalam sistem di GridView. GridView akan menyertakan nama pengguna, alamat email, tanggal masuk terakhir, dan komentar setiap pengguna. Selain menampilkan informasi setiap pengguna, GridView akan menyertakan kemampuan edit dan hapus. Kami awalnya akan membuat halaman ini dengan fungsi edit dan hapus yang tersedia untuk semua pengguna. Di bagian "Menggunakan Kontrol LoginView" dan "Fungsionalitas Pembatasan Terprogram" kita akan melihat cara mengaktifkan atau menonaktifkan fitur-fitur ini berdasarkan peran pengguna yang mengunjungi.

Catatan

Halaman ASP.NET yang akan kita buat menggunakan kontrol GridView untuk menampilkan akun pengguna. Karena seri tutorial ini berfokus pada autentikasi formulir, otorisasi, akun pengguna, dan peran, saya tidak ingin menghabiskan terlalu banyak waktu untuk membahas pekerjaan dalam kontrol GridView. Meskipun tutorial ini memberikan instruksi langkah demi langkah khusus untuk menyiapkan halaman ini, tutorial ini tidak mempelajari detail mengapa pilihan tertentu dibuat, atau efek apa yang dimiliki properti tertentu pada output yang dirender. Untuk pemeriksaan menyeluruh kontrol GridView, lihat seri tutorial Bekerja dengan Data di ASP.NET 2.0 saya.

Mulailah dengan membuka RoleBasedAuthorization.aspx halaman di Roles folder. Seret GridView dari halaman ke Designer dan atur ID ke UserGrid. Dalam sesaat kita akan menulis kode yang memanggil Membership.GetAllUsers metode dan mengikat objek yang dihasilkan MembershipUserCollection ke GridView. MembershipUserCollection berisi MembershipUser objek untuk setiap akun pengguna dalam sistem; MembershipUser objek memiliki properti seperti UserName, , EmailLastLoginDate, dan sebagainya.

Sebelum kita menulis kode yang mengikat akun pengguna ke kisi, mari kita tentukan bidang GridView terlebih dahulu. Dari Tag Pintar GridView, klik tautan "Edit Kolom" untuk meluncurkan kotak dialog Bidang (lihat Gambar 6). Dari sini, hapus centang pada kotak centang "Buat bidang secara otomatis" di sudut kiri bawah. Karena kami ingin GridView ini menyertakan kemampuan pengeditan dan penghapusan, tambahkan CommandField dan atur properti dan ShowDeleteButton ke ShowEditButton True. Selanjutnya, tambahkan empat bidang untuk menampilkan UserNameproperti , , EmailLastLoginDate, dan Comment . Gunakan BoundField untuk dua properti baca-saja (UserName dan LastLoginDate) dan TemplateFields untuk dua bidang yang dapat diedit (Email dan Comment).

Minta BoundField pertama menampilkan UserName properti; atur properti dan DataField ke HeaderText "UserName". Bidang ini tidak akan dapat diedit, jadi atur propertinya ReadOnly ke True. Konfigurasikan LastLoginDate BoundField dengan mengaturnya HeaderText ke "Masuk Terakhir" dan DataField ke "LastLoginDate". Mari kita format output dari BoundField ini sehingga hanya tanggal yang ditampilkan (bukan tanggal dan waktu). Untuk mencapai hal ini, atur properti BoundField HtmlEncode ini ke False dan propertinya DataFormatString ke "{0:d}". Atur juga ReadOnly properti ke True.

Atur HeaderText properti dari dua TemplateFields ke "Email" dan "Comment".

Bidang GridView Dapat Dikonfigurasi Melalui Kotak Dialog Bidang

Gambar 6: Bidang GridView Dapat Dikonfigurasi Melalui Kotak Dialog Bidang (Klik untuk melihat gambar ukuran penuh)

Kita sekarang perlu mendefinisikan ItemTemplate dan EditItemTemplate untuk TemplateFields "Email" dan "Komentar". Tambahkan kontrol Web Label ke masing-masing ItemTemplate properti dan ikat propertinya Text ke Email properti dan Comment .

Untuk TemplateField "Email", tambahkan TextBox bernama Email ke EditItemTemplate dan ikat propertinya Text ke Email properti menggunakan pengikatan data dua arah. Tambahkan RequiredFieldValidator dan RegularExpressionValidator ke EditItemTemplate untuk memastikan bahwa pengunjung yang mengedit properti Email telah memasukkan alamat email yang valid. Untuk TemplateField "Komentar", tambahkan TextBox multibaris bernama Comment ke EditItemTemplate. Atur properti dan Rows TextBox Columns ke 40 dan 4, masing-masing, lalu ikat propertinya Text ke Comment properti menggunakan pengikatan data dua arah.

Setelah mengonfigurasi TemplateFields ini, markup deklaratifnya akan terlihat mirip dengan yang berikut ini:

<asp:TemplateField HeaderText="Email">    
     <ItemTemplate>    
          <asp:Label runat="server" ID="Label1" Text='<%# Eval("Email") %>'></asp:Label>    

     </ItemTemplate>    
     <EditItemTemplate>    
          <asp:TextBox runat="server" ID="Email" Text='<%# Bind("Email") %>'></asp:TextBox>    

          <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server"    
               ControlToValidate="Email" Display="Dynamic"    
               ErrorMessage="You must provide an email address." 
               SetFocusOnError="True">*</asp:RequiredFieldValidator>    

          <asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server"    
               ControlToValidate="Email" Display="Dynamic"    
               ErrorMessage="The email address you have entered is not valid. Please fix 
               this and try again."    
               SetFocusOnError="True"    

               ValidationExpression="\w+([-+.']\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*">*
          </asp:RegularExpressionValidator>    
     </EditItemTemplate>    
</asp:TemplateField>

<asp:TemplateField HeaderText="Comment">    
     <ItemTemplate>    
          <asp:Label runat="server" ID="Label2" Text='<%# Eval("Comment") %>'></asp:Label>    

     </ItemTemplate>    
     <EditItemTemplate>    
          <asp:TextBox runat="server" ID="Comment" TextMode="MultiLine"
               Columns="40" Rows="4" Text='<%# Bind("Comment") %>'>

          </asp:TextBox>    
     </EditItemTemplate>    
</asp:TemplateField>

Saat mengedit atau menghapus akun pengguna, kita perlu mengetahui nilai properti pengguna tersebut UserName . Atur properti GridView DataKeyNames ke "UserName" sehingga informasi ini tersedia melalui koleksi GridView DataKeys .

Terakhir, tambahkan kontrol ValidationSummary ke halaman dan atur propertinya ShowMessageBox ke True dan propertinya ShowSummary ke False. Dengan pengaturan ini, ValidationSummary akan menampilkan pemberitahuan sisi klien jika pengguna mencoba mengedit akun pengguna dengan alamat email yang hilang atau tidak valid.

<asp:ValidationSummary ID="ValidationSummary1"
               runat="server"
               ShowMessageBox="True"
               ShowSummary="False" />

Kami sekarang telah menyelesaikan markup deklaratif halaman ini. Tugas kami berikutnya adalah mengikat sekumpulan akun pengguna ke GridView. Tambahkan metode bernama BindUserGrid ke RoleBasedAuthorization.aspx kelas code-behind halaman yang mengikat MembershipUserCollection yang dikembalikan oleh Membership.GetAllUsers ke UserGrid GridView. Panggil metode ini dari penanganan Page_Load aktivitas pada kunjungan halaman pertama.

protected void Page_Load(object sender, EventArgs e)    
{    
     if (!Page.IsPostBack)    
          BindUserGrid();    
}

private void BindUserGrid()    
{    
     MembershipUserCollection allUsers = Membership.GetAllUsers();    
     UserGrid.DataSource = allUsers;    
     UserGrid.DataBind();    
}

Dengan kode ini di tempat, kunjungi halaman melalui browser. Seperti yang ditunjukkan Gambar 7, Anda akan melihat informasi daftar GridView tentang setiap akun pengguna dalam sistem.

UserGrid GridView Mencantumkan Informasi Tentang Setiap Pengguna dalam Sistem

Gambar 7: UserGrid GridView Mencantumkan Informasi Tentang Setiap Pengguna dalam Sistem (Klik untuk melihat gambar ukuran penuh)

Catatan

UserGrid GridView mencantumkan semua pengguna dalam antarmuka non-halaman. Antarmuka kisi sederhana ini tidak cocok untuk skenario di mana ada beberapa lusin atau lebih pengguna. Salah satu opsinya adalah mengonfigurasi GridView untuk mengaktifkan halaman. Metode Membership.GetAllUsers ini memiliki dua kelebihan beban: satu yang tidak menerima parameter input dan mengembalikan semua pengguna dan satu yang mengambil nilai bilangan bulat untuk indeks halaman dan ukuran halaman, dan hanya mengembalikan subset pengguna yang ditentukan. Kelebihan beban kedua dapat digunakan untuk halaman yang lebih efisien melalui pengguna karena hanya mengembalikan subset akun pengguna yang tepat daripada semuanya . Jika Anda memiliki ribuan akun pengguna, Anda mungkin ingin mempertimbangkan antarmuka berbasis filter, yang hanya menampilkan pengguna yang UserName-nya dimulai dengan karakter yang dipilih, misalnya. Membership.FindUsersByName method sangat ideal untuk membangun antarmuka pengguna berbasis filter. Kita akan melihat membangun antarmuka seperti itu dalam tutorial di masa mendatang.

Kontrol GridView menawarkan dukungan pengeditan dan penghapusan bawaan saat kontrol terikat ke kontrol sumber data yang dikonfigurasi dengan benar, seperti SqlDataSource atau ObjectDataSource. UserGrid GridView, bagaimanapun, memiliki data yang terikat secara terprogram; oleh karena itu, kita harus menulis kode untuk melakukan dua tugas ini. Secara khusus, kita perlu membuat penanganan aktivitas untuk peristiwa GridViewRowEditing, , RowCancelingEditRowUpdating, danRowDeleting, yang diaktifkan ketika pengunjung mengklik tombol Edit, Batal, Perbarui, atau Hapus GridView.

Mulailah dengan membuat penanganan aktivitas untuk peristiwa GridView RowEditing, , RowCancelingEditdan RowUpdating lalu tambahkan kode berikut:

protected void UserGrid_RowEditing(object sender, GridViewEditEventArgs e)
{
     // Set the grid's EditIndex and rebind the data

     UserGrid.EditIndex = e.NewEditIndex;
     BindUserGrid();
}

protected void UserGrid_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
{
     // Revert the grid's EditIndex to -1 and rebind the data
     UserGrid.EditIndex = -1;
     BindUserGrid();
}

protected void UserGrid_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
     // Exit if the page is not valid
     if (!Page.IsValid)
          return;

     // Determine the username of the user we are editing
     string UserName = UserGrid.DataKeys[e.RowIndex].Value.ToString();

     // Read in the entered information and update the user
     TextBox EmailTextBox = UserGrid.Rows[e.RowIndex].FindControl("Email") as TextBox;
     TextBox CommentTextBox = UserGrid.Rows[e.RowIndex].FindControl("Comment") as TextBox;

     // Return information about the user
     MembershipUser UserInfo = Membership.GetUser(UserName);

     // Update the User account information
     UserInfo.Email = EmailTextBox.Text.Trim();
     UserInfo.Comment = CommentTextBox.Text.Trim();

     Membership.UpdateUser(UserInfo);

     // Revert the grid's EditIndex to -1 and rebind the data
     UserGrid.EditIndex = -1;
     BindUserGrid();
}

Penanganan RowEditing aktivitas dan RowCancelingEdit cukup mengatur properti GridView EditIndex dan kemudian menggabungkan kembali daftar akun pengguna ke kisi. Hal-hal menarik terjadi di RowUpdating penanganan aktivitas. Penanganan aktivitas ini dimulai dengan memastikan bahwa data valid lalu mengambil UserName nilai akun pengguna yang diedit dari DataKeys koleksi. Email TextBox dan Comment dalam dua TemplateFields EditItemTemplate kemudian dirujuk secara terprogram. Propertinya Text berisi alamat email dan komentar yang diedit.

Untuk memperbarui akun pengguna melalui API Keanggotaan, kita harus terlebih dahulu mendapatkan informasi pengguna, yang kita lakukan melalui panggilan ke Membership.GetUser(userName). Properti dan Comment objek Email yang dikembalikan MembershipUser kemudian diperbarui dengan nilai yang dimasukkan ke dalam dua Kotak Teks dari antarmuka pengeditan. Akhirnya, modifikasi ini disimpan dengan panggilan ke Membership.UpdateUser. Penanganan RowUpdating aktivitas selesai dengan mengembalikan GridView ke antarmuka pra-pengeditannya.

Selanjutnya, buat penanganan RowDeleting aktivitas lalu tambahkan kode berikut:

protected void UserGrid_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
     // Determine the username of the user we are editing
     string UserName = UserGrid.DataKeys[e.RowIndex].Value.ToString();

     // Delete the user
     Membership.DeleteUser(UserName);

     // Revert the grid's EditIndex to -1 and rebind the data
     UserGrid.EditIndex = -1;
     BindUserGrid();
}

Penanganan aktivitas di atas dimulai dengan mengambil UserName nilai dari koleksi GridViewDataKeys; nilai ini UserName kemudian diteruskan ke metode kelas DeleteUserKeanggotaan. Metode menghapus DeleteUser akun pengguna dari sistem, termasuk data keanggotaan terkait (seperti peran apa yang dimiliki pengguna ini). Setelah menghapus pengguna, kisi EditIndex diatur ke -1 (jika pengguna mengklik Hapus saat baris lain dalam mode edit) dan BindUserGrid metode dipanggil.

Catatan

Tombol Hapus tidak memerlukan konfirmasi apa pun dari pengguna sebelum menghapus akun pengguna. Saya mendorong Anda untuk menambahkan beberapa bentuk konfirmasi pengguna untuk mengurangi kemungkinan akun dihapus secara tidak sengaja. Salah satu cara termampu untuk mengonfirmasi tindakan adalah melalui kotak dialog konfirmasi pihak klien. Untuk informasi selengkapnya tentang teknik ini, lihat Menambahkan Konfirmasi Client-Side Saat Menghapus.

Verifikasi bahwa halaman ini berfungsi seperti yang diharapkan. Anda harus dapat mengedit alamat email dan komentar pengguna mana pun, serta menghapus akun pengguna apa pun. RoleBasedAuthorization.aspx Karena halaman ini dapat diakses oleh semua pengguna, pengguna mana pun - bahkan pengunjung anonim - dapat mengunjungi halaman ini dan mengedit dan menghapus akun pengguna! Mari kita perbarui halaman ini sehingga hanya pengguna dalam peran Supervisor dan Administrator yang dapat mengedit alamat email dan komentar pengguna, dan hanya Administrator yang dapat menghapus akun pengguna.

Bagian "Menggunakan Kontrol LoginView" melihat penggunaan kontrol LoginView untuk menampilkan instruksi khusus untuk peran pengguna. Jika seseorang dalam peran Administrator mengunjungi halaman ini, kami akan menampilkan instruksi tentang cara mengedit dan menghapus pengguna. Jika pengguna dalam peran Supervisor mencapai halaman ini, kami akan menampilkan instruksi tentang mengedit pengguna. Dan jika pengunjung bersifat anonim atau tidak berada dalam peran Supervisor atau Administrator, kami akan menampilkan pesan yang menjelaskan bahwa mereka tidak dapat mengedit atau menghapus informasi akun pengguna. Di bagian "Fungsionalitas Pembatasan Secara Terprogram" kami akan menulis kode yang secara terprogram menampilkan atau menyembunyikan tombol Edit dan Hapus berdasarkan peran pengguna.

Menggunakan Kontrol LoginView

Seperti yang telah kita lihat di tutorial sebelumnya, kontrol LoginView berguna untuk menampilkan antarmuka yang berbeda untuk pengguna yang diautentikasi dan anonim, tetapi kontrol LoginView juga dapat digunakan untuk menampilkan markup yang berbeda berdasarkan peran pengguna. Mari kita gunakan kontrol LoginView untuk menampilkan instruksi yang berbeda berdasarkan peran pengguna yang mengunjungi.

Mulailah dengan menambahkan LoginView di atas UserGrid GridView. Seperti yang telah kita bahas sebelumnya, kontrol LoginView memiliki dua templat bawaan: AnonymousTemplate dan LoggedInTemplate. Masukkan pesan singkat di kedua templat ini yang memberi tahu pengguna bahwa mereka tidak dapat mengedit atau menghapus informasi pengguna apa pun.

<asp:LoginView ID="LoginView1" runat="server">
     <LoggedInTemplate>
          You are not a member of the Supervisors or Administrators roles. Therefore you
          cannot edit or delete any user information.
     </LoggedInTemplate>
     <AnonymousTemplate>
          You are not logged into the system. Therefore you cannot edit or delete any user

          information.
     </AnonymousTemplate>
</asp:LoginView>

Selain AnonymousTemplate dan LoggedInTemplate, kontrol LoginView dapat menyertakan RoleGroups, yang merupakan templat khusus peran. Setiap RoleGroup berisi satu properti, Roles, yang menentukan peran apa yang berlaku untuk RoleGroup. Roles Properti dapat diatur ke satu peran (seperti "Administrator") atau ke daftar peran yang dibatasi koma (seperti "Administrator, Supervisor").

Untuk mengelola RoleGroups, klik tautan "Edit RoleGroups" dari Tag Pintar kontrol untuk memunculkan Editor Koleksi RoleGroup. Tambahkan dua RoleGroup baru. Atur properti RoleGroup Roles pertama ke "Administrator" dan yang kedua ke "Supervisor".

Mengelola Templat Role-Specific LoginView Melalui Editor Koleksi RoleGroup

Gambar 8: Mengelola Templat Role-Specific LoginView Melalui Editor Koleksi RoleGroup (Klik untuk melihat gambar ukuran penuh)

Klik OK untuk menutup Editor Koleksi RoleGroup; ini memperbarui markup deklaratif LoginView untuk menyertakan <RoleGroups> bagian dengan <asp:RoleGroup> elemen anak untuk setiap RoleGroup yang ditentukan dalam Editor Koleksi RoleGroup. Selain itu, daftar drop-down "Tampilan" di Tag Pintar LoginView - yang awalnya hanya AnonymousTemplate mencantumkan dan LoggedInTemplate - sekarang juga menyertakan RoleGroups yang ditambahkan.

Edit RoleGroups sehingga pengguna dalam peran Supervisor ditampilkan instruksi tentang cara mengedit akun pengguna, sementara pengguna dalam peran Administrator ditampilkan instruksi untuk mengedit dan menghapus. Setelah membuat perubahan ini, markup deklaratif LoginView Anda akan terlihat mirip dengan yang berikut ini.

<asp:LoginView ID="LoginView1" runat="server">
     <RoleGroups>
          <asp:RoleGroup Roles="Administrators">
               <ContentTemplate>
                    As an Administrator, you may edit and delete user accounts. 
                    Remember: With great power comes great responsibility!

               </ContentTemplate>
          </asp:RoleGroup>
          <asp:RoleGroup Roles="Supervisors">
               <ContentTemplate>
                    As a Supervisor, you may edit users&#39; Email and Comment information. 
                    Simply click the Edit button, make your changes, and then click Update.
               </ContentTemplate>
          </asp:RoleGroup>
     </RoleGroups>

     <LoggedInTemplate>
          You are not a member of the Supervisors or Administrators roles. 
          Therefore you cannot edit or delete any user information.
     </LoggedInTemplate>
     <AnonymousTemplate>
          You are not logged into the system. Therefore you cannot edit or delete any user
          information.
     </AnonymousTemplate>
</asp:LoginView>

Setelah membuat perubahan ini, simpan halaman lalu kunjungi melalui browser. Pertama-tama kunjungi halaman sebagai pengguna anonim. Anda akan ditampilkan pesan, "Anda tidak masuk ke sistem. Oleh karena itu Anda tidak dapat mengedit atau menghapus informasi pengguna apa pun." Kemudian masuk sebagai pengguna yang diautentikasi, tetapi pengguna yang tidak berada dalam peran Supervisor atau Administrator. Kali ini Anda akan melihat pesan, "Anda bukan anggota peran Supervisor atau Administrator. Oleh karena itu Anda tidak dapat mengedit atau menghapus informasi pengguna apa pun."

Selanjutnya, masuk sebagai pengguna yang merupakan anggota peran Supervisor. Kali ini Anda akan melihat pesan khusus peran Supervisor (lihat Gambar 9). Dan jika Anda masuk sebagai pengguna dalam peran Administrator, Anda akan melihat pesan khusus peran Administrator (lihat Gambar 10).

Bruce Ditampilkan Pesan Role-Specific Supervisor

Gambar 9: Bruce Ditampilkan sebagai Supervisor Role-Specific Message (Klik untuk melihat gambar ukuran penuh)

Tito Diperlihatkan Pesan Role-Specific Administrator

Gambar 10: Tito Diperlihatkan Pesan Role-Specific Administrator (Klik untuk melihat gambar ukuran penuh)

Saat cuplikan layar di Gambar 9 dan 10 ditampilkan, LoginView hanya merender satu templat, bahkan jika beberapa templat berlaku. Bruce dan Tito keduanya masuk pengguna, namun LoginView hanya merender RoleGroup yang cocok dan bukan LoggedInTemplate. Selain itu, Tito milik peran Administrator dan Supervisor, namun kontrol LoginView merender templat peran khusus Administrator alih-alih Supervisor satu.

Gambar 11 mengilustrasikan alur kerja yang digunakan oleh kontrol LoginView untuk menentukan templat apa yang akan dirender. Perhatikan bahwa jika ada lebih dari satu RoleGroup yang ditentukan, templat LoginView merender RoleGroup pertama yang cocok. Dengan kata lain, jika kita telah menempatkan Supervisors RoleGroup sebagai RoleGroup pertama dan Administrator sebagai yang kedua, maka ketika Tito mengunjungi halaman ini dia akan melihat pesan Supervisor.

Alur Kerja Kontrol LoginView untuk Menentukan Templat apa yang akan Dirender

Gambar 11: Alur Kerja Kontrol LoginView untuk Menentukan Templat Apa yang akan Dirender (Klik untuk melihat gambar ukuran penuh)

Fungsionalitas Pembatasan Terprogram

Meskipun kontrol LoginView menampilkan instruksi yang berbeda berdasarkan peran pengguna yang mengunjungi halaman, tombol Edit dan Batalkan tetap terlihat oleh semua. Kita perlu secara terprogram menyembunyikan tombol Edit dan Hapus untuk pengunjung dan pengguna anonim yang tidak berada dalam peran Supervisor atau Administrator. Kita perlu menyembunyikan tombol Hapus untuk semua orang yang bukan Administrator. Untuk mencapai hal ini, kami akan menulis sedikit kode yang secara terprogram mereferensikan CommandField's Edit dan Delete LinkButtons dan mengatur propertinya Visible ke false, jika perlu.

Cara termudah untuk mereferensikan kontrol secara terprogram di CommandField adalah dengan terlebih dahulu mengonversinya menjadi templat. Untuk mencapai hal ini, klik tautan "Edit Kolom" dari Tag Pintar GridView, pilih CommandField dari daftar bidang saat ini, dan klik tautan "Konversi bidang ini menjadi Bidang Templat". Ini mengubah CommandField menjadi TemplateField dengan ItemTemplate dan EditItemTemplate. ItemTemplate berisi Edit dan Hapus LinkButtons saat EditItemTemplate rumah LinkButtons Pembaruan dan Batalkan.

Mengonversi CommandField Menjadi TemplateField

Gambar 12: Mengonversi CommandField Menjadi Bidang Templat (Klik untuk melihat gambar ukuran penuh)

Perbarui Edit dan Hapus LinkButtons di ItemTemplate, mengatur propertinya ID ke nilai EditButton dan DeleteButton, masing-masing.

<asp:TemplateField ShowHeader="False">
     <EditItemTemplate>
          <asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="True"
               CommandName="Update" Text="Update"></asp:LinkButton>

           <asp:LinkButton ID="LinkButton2" runat="server" CausesValidation="False"
                CommandName="Cancel" Text="Cancel"></asp:LinkButton>

     </EditItemTemplate>
     <ItemTemplate>
          <asp:LinkButton ID="EditButton" runat="server" CausesValidation="False"
               CommandName="Edit" Text="Edit"></asp:LinkButton>

           <asp:LinkButton ID="DeleteButton" runat="server" CausesValidation="False"
               CommandName="Delete" Text="Delete"></asp:LinkButton>

     </ItemTemplate>
</asp:TemplateField>

Setiap kali data terikat ke GridView, GridView menghitung rekaman dalam propertinya DataSource dan menghasilkan objek yang sesuai GridViewRow . Saat setiap GridViewRow objek dibuat, RowCreated peristiwa diaktifkan. Untuk menyembunyikan tombol Edit dan Hapus untuk pengguna yang tidak sah, kita perlu membuat penanganan aktivitas untuk peristiwa ini dan secara terprogram mereferensikan Edit dan Hapus LinkButtons, mengatur properti mereka Visible .

Buat penanganan aktivitas peristiwa RowCreated lalu tambahkan kode berikut:

protected void UserGrid_RowCreated(object sender, GridViewRowEventArgs e)
{
     if (e.Row.RowType == DataControlRowType.DataRow && e.Row.RowIndex != UserGrid.EditIndex)
     {
          // Programmatically reference the Edit and Delete LinkButtons
          LinkButton EditButton = e.Row.FindControl("EditButton") as LinkButton;

          LinkButton DeleteButton = e.Row.FindControl("DeleteButton") as LinkButton;

          EditButton.Visible = (User.IsInRole("Administrators") || User.IsInRole("Supervisors"));
          DeleteButton.Visible = User.IsInRole("Administrators");
     }
}

Perlu diingat bahwa RowCreated peristiwa diaktifkan untuk semua baris GridView, termasuk header, footer, antarmuka pager, dan sebagainya. Kami hanya ingin mereferensikan LinkButtons Edit dan Hapus secara terprogram jika kami berhadapan dengan baris data yang tidak dalam mode edit (karena baris dalam mode edit memiliki tombol Perbarui dan Batalkan alih-alih Edit dan Hapus). Pemeriksaan ini ditangani oleh if pernyataan .

Jika kita berurusan dengan baris data yang tidak dalam mode edit, Edit dan Hapus LinkButtons direferensikan dan propertinya Visible diatur berdasarkan nilai Boolean yang dikembalikan oleh User metode objek IsInRole(roleName) . Objek Pengguna mereferensikan prinsipal yang dibuat oleh RoleManagerModule; akibatnya, IsInRole(roleName) metode menggunakan API Peran untuk menentukan apakah pengunjung saat ini milik roleName.

Catatan

Kita bisa menggunakan kelas Peran secara langsung, mengganti panggilan ke User.IsInRole(roleName) dengan panggilan ke Roles.IsUserInRole(roleName) metode . Saya memutuskan untuk menggunakan metode objek IsInRole(roleName) utama dalam contoh ini karena lebih efisien daripada menggunakan API Peran secara langsung. Sebelumnya dalam tutorial ini kami mengonfigurasi manajer peran untuk menyimpan peran pengguna dalam cookie. Data cookie yang di-cache ini hanya digunakan ketika metode utama IsInRole(roleName) dipanggil; panggilan langsung ke Roles API selalu melibatkan perjalanan ke penyimpanan peran. Bahkan jika peran tidak di-cache dalam cookie, memanggil metode objek IsInRole(roleName) utama biasanya lebih efisien karena ketika dipanggil untuk pertama kalinya selama permintaan, ia menyimpan hasilnya. Api Peran, di sisi lain, tidak melakukan penembolokan apa pun. RowCreated Karena peristiwa ini diaktifkan sekali untuk setiap baris di GridView, menggunakan User.IsInRole(roleName) hanya melibatkan satu perjalanan ke toko peran sedangkan Roles.IsUserInRole(roleName) memerlukan perjalanan N, di mana N adalah jumlah akun pengguna yang ditampilkan di kisi.

Properti tombol Visible Edit diatur ke true jika pengguna yang mengunjungi halaman ini berada dalam peran Administrator atau Supervisor; jika tidak, itu diatur ke false. Properti tombol Visible Hapus diatur ke true hanya jika pengguna berada dalam peran Administrator.

Uji halaman ini melalui browser. Jika Anda mengunjungi halaman sebagai pengunjung anonim atau sebagai pengguna yang bukan Supervisor atau Administrator, CommandField kosong; masih ada, tetapi sebagai sliver tipis tanpa tombol Edit atau Hapus.

Catatan

Dimungkinkan untuk menyembunyikan CommandField sama sekali ketika non-Supervisor dan non-Administrator mengunjungi halaman. Saya meninggalkan ini sebagai latihan untuk pembaca.

Tombol Edit dan Hapus Disembunyikan untuk Non-Supervisor dan Non-Administrator

Gambar 13: Tombol Edit dan Hapus Disembunyikan untuk Non-Supervisor dan Non-Administrator (Klik untuk melihat gambar ukuran penuh)

Jika pengguna yang termasuk dalam peran Supervisor (tetapi tidak untuk peran Administrator) yang dikunjungi, ia hanya melihat tombol Edit.

Saat Tombol Edit Tersedia untuk Supervisor, Tombol Hapus Disembunyikan

Gambar 14: Meskipun Tombol Edit Tersedia untuk Supervisor, Tombol Hapus Disembunyikan (Klik untuk melihat gambar ukuran penuh)

Dan jika Administrator mengunjungi, dia memiliki akses ke tombol Edit dan Hapus.

Tombol Edit dan Hapus Hanya Tersedia untuk Administrator

Gambar 15: Tombol Edit dan Hapus Hanya Tersedia untuk Administrator (Klik untuk melihat gambar ukuran penuh)

Langkah 3: Menerapkan Aturan Otorisasi Role-Based ke Kelas dan Metode

Di Langkah 2, kami membatasi kemampuan edit kepada pengguna dalam peran Supervisor dan Administrator dan menghapus kemampuan hanya untuk Administrator. Ini dicapai dengan menyembunyikan elemen antarmuka pengguna terkait untuk pengguna yang tidak sah melalui teknik terprogram. Langkah-langkah tersebut tidak menjamin bahwa pengguna yang tidak sah tidak akan dapat melakukan tindakan istimewa. Mungkin ada elemen antarmuka pengguna yang ditambahkan nanti atau yang lupa kami sembunyikan untuk pengguna yang tidak sah. Atau peretas mungkin menemukan beberapa cara lain untuk mendapatkan halaman ASP.NET untuk menjalankan metode yang diinginkan.

Cara mudah untuk memastikan bahwa fungsionalitas tertentu tidak dapat diakses oleh pengguna yang tidak sah adalah dengan menghias kelas atau metode tersebut PrincipalPermission dengan atribut . Ketika runtime .NET menggunakan kelas atau menjalankan salah satu metodenya, runtime tersebut memeriksa untuk memastikan bahwa konteks keamanan saat ini memiliki izin. Atribut PrincipalPermission menyediakan mekanisme di mana kita dapat menentukan aturan ini.

Kami melihat menggunakan PrincipalPermission atribut kembali dalam tutorial Otorisasi Berbasis Pengguna. Secara khusus, kami melihat cara menghias gridView SelectedIndexChanged dan RowDeleting penanganan aktivitas sehingga mereka hanya dapat dieksekusi oleh pengguna yang diautentikasi dan Tito, masing-masing. Atribut juga PrincipalPermission berfungsi dengan peran.

Mari kita tunjukkan menggunakan PrincipalPermission atribut pada GridView RowUpdating dan RowDeleting penanganan aktivitas untuk melarang eksekusi bagi pengguna yang tidak berwenang. Yang perlu kita lakukan adalah menambahkan atribut yang sesuai di atas setiap definisi fungsi:

[PrincipalPermission(SecurityAction.Demand, Role = "Administrators")]
[PrincipalPermission(SecurityAction.Demand, Role = "Supervisors")]
protected void UserGrid_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
     ...
}

[PrincipalPermission(SecurityAction.Demand, Role = "Administrators")]
protected void UserGrid_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
     ...
}

Atribut untuk RowUpdating penanganan aktivitas menentukan bahwa hanya pengguna dalam peran Administrator atau Supervisor yang dapat menjalankan penanganan aktivitas, di mana sebagai atribut pada RowDeleting penanganan aktivitas membatasi eksekusi kepada pengguna dalam peran Administrator.

Catatan

Atribut PrincipalPermission direpresentasikan sebagai kelas di System.Security.Permissions namespace layanan. Pastikan untuk menambahkan using System.Security.Permissions pernyataan di bagian atas file kelas code-behind Anda untuk mengimpor namespace layanan ini.

Jika, entah bagaimana, non-Administrator mencoba menjalankan RowDeleting penanganan aktivitas atau jika non-Supervisor atau non-Administrator mencoba menjalankan RowUpdating penanganan aktivitas, runtime .NET akan menaikkan SecurityException.

Jika Konteks Keamanan tidak Berwenang untuk Menjalankan Metode, SecurityException akan Dilemparkan

Gambar 16: Jika Konteks Keamanan tidak Diizinkan untuk Menjalankan Metode, dilemparkan SecurityException (Klik untuk melihat gambar ukuran penuh)

Selain halaman ASP.NET, banyak aplikasi juga memiliki arsitektur yang mencakup berbagai lapisan, seperti Logika Bisnis dan Lapisan Akses Data. Lapisan-lapisan ini biasanya diimplementasikan sebagai Pustaka Kelas dan menawarkan kelas dan metode untuk melakukan logika bisnis dan fungsionalitas terkait data. Atribut PrincipalPermission ini juga berguna untuk menerapkan aturan otorisasi ke lapisan ini.

Untuk informasi selengkapnya tentang menggunakan PrincipalPermission atribut untuk menentukan aturan otorisasi pada kelas dan metode, lihat entri blog Scott GuthrieMenambahkan Aturan Otorisasi ke Lapisan Bisnis dan Data Menggunakan PrincipalPermissionAttributes.

Ringkasan

Dalam tutorial ini kita melihat cara menentukan aturan otorisasi kasar dan halus berdasarkan peran pengguna. ASP. Fitur otorisasi URL NET memungkinkan pengembang halaman menentukan identitas apa yang diizinkan atau ditolak aksesnya ke halaman apa. Seperti yang kita lihat kembali dalam tutorial Otorisasi Berbasis Pengguna, aturan otorisasi URL dapat diterapkan berdasarkan pengguna demi pengguna. Mereka juga dapat diterapkan berdasarkan peran demi peran, seperti yang kita lihat di Langkah 1 tutorial ini.

Aturan otorisasi biji-bijian halus dapat diterapkan secara deklaratif atau terprogram. Pada Langkah 2 kita melihat menggunakan fitur RoleGroups kontrol LoginView untuk merender output yang berbeda berdasarkan peran pengguna yang mengunjungi. Kami juga melihat cara untuk menentukan secara terprogram apakah pengguna termasuk dalam peran tertentu dan cara menyesuaikan fungsionalitas halaman yang sesuai.

Selamat Pemrograman!

Bacaan lebih lanjut

Untuk informasi selengkapnya tentang topik yang dibahas dalam tutorial ini, lihat sumber daya berikut:

Tentang Penulis

Scott Mitchell, penulis beberapa buku ASP/ASP.NET dan pendiri 4GuysFromRolla.com, telah bekerja dengan teknologi Microsoft Web sejak 1998. Scott bekerja sebagai konsultan, pelatih, dan penulis independen. Buku terbarunya adalah Sams Teach Yourself ASP.NET 2.0 dalam 24 Jam. Scott dapat dijangkau di mitchell@4guysfromrolla.com atau melalui blognya di http://ScottOnWriting.NET.

Terima kasih khusus untuk...

Seri tutorial ini ditinjau oleh banyak peninjau yang bermanfaat. Peninjau prospek untuk tutorial ini termasuk Suchi Banerjee dan Teresa Murphy. Tertarik untuk meninjau artikel MSDN saya yang akan datang? Jika demikian, letakkan saya antrean di mitchell@4GuysFromRolla.com