Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
oleh Mike Volodarsky
Pengantar
IIS 7.0 ke atas memungkinkan untuk memperluas server berdasarkan modul yang dikembangkan dengan dua cara:
- Menggunakan kode terkelola, dan API ekstensibilitas server ASP.NET
- Menggunakan kode asli, dan API ekstensibilitas server asli IIS
Di masa lalu, modul ASP.NET dibatasi dalam fungsionalitas, karena alur pemrosesan permintaan ASP.NET terpisah dari alur permintaan server utama.
Di IIS, modul terkelola menjadi hampir sama kuatnya dengan modul asli dengan arsitektur Alur Terintegrasi. Yang paling penting, layanan yang disediakan modul terkelola sekarang dapat diterapkan ke semua permintaan ke server, bukan hanya permintaan untuk ASP.NET konten seperti halaman ASPX. Modul terkelola dikonfigurasi dan dikelola secara konsisten dengan modul asli, dan dapat dijalankan dalam tahap pemrosesan dan urutan yang sama dengan modul asli. Terakhir, modul terkelola dapat melakukan serangkaian operasi yang lebih luas untuk memanipulasi pemrosesan permintaan melalui beberapa API ASP.NET yang ditambahkan dan ditingkatkan.
Artikel ini menggambarkan perluasan server dengan modul terkelola untuk menambahkan kemampuan untuk melakukan autentikasi dasar terhadap penyimpanan kredensial arbitrer, seperti infrastruktur info masuk berbasis penyedia dalam sistem Keanggotaan ASP.NET 2.0.
Ini memungkinkan mengganti dukungan autentikasi dasar bawaan di IIS, yang terkait dengan penyimpanan kredensial Windows, dengan yang mendukung penyimpanan kredensial arbitrer, atau penyedia Keanggotaan yang ada yang dikirim dengan ASP.NET 2.0 seperti SQL Server, SQL Express, atau Direktori Aktif.
Artikel ini memeriksa tugas-tugas berikut:
- Mengembangkan modul terkelola menggunakan API ASP.NET
- Menyebarkan modul terkelola di server
Untuk mempelajari selengkapnya tentang dasar-dasar pengembangan modul dan penangan IIS, lihat Mengembangkan modul dan penangan IIS7 dengan kerangka kerja .NET.
Anda juga dapat menemukan banyak sumber daya dan tips tentang menulis modul IIS di blog, http://www.mvolo.com/, serta mengunduh modul IIS yang ada untuk aplikasi Anda. Untuk beberapa contoh, lihat Mengalihkan permintaan ke aplikasi Anda dengan modul HttpRedirection, Daftar direktori yang bagus untuk situs web IIS Anda dengan DirectoryListingModule, dan Menampilkan ikon file cantik di aplikasi ASP.NET Anda dengan IconHandler.
Catatan
Kode yang disediakan dalam artikel ini ditulis dalam C#.
Prasyarat
Untuk mengikuti langkah-langkah dalam dokumen ini, Anda harus menginstal fitur IIS berikut:
ASP.NET
Instal ASP.NET melalui Panel Kontrol Windows Vista. Pilih "Program" - "Aktifkan atau nonaktifkan fitur Windows". Kemudian buka "Layanan Informasi Internet" - "World Wide Web Services" - "Fitur Pengembangan Aplikasi" dan periksa "ASP.NET".
Jika Anda memiliki build Windows ServerĀ® 2008, buka "Manajer Server" - "Peran" dan pilih "Server Web (IIS)". Klik "Tambahkan layanan peran". Di bagian "Pengembangan Aplikasi" periksa "ASP.NET".
Informasi Latar Belakang tentang Autentikasi Dasar
Autentikasi dasar adalah skema autentikasi yang ditentukan dalam protokol HTTP.1 (RFC 2617). Ini menggunakan mekanisme berbasis tantangan standar yang berfungsi sebagai berikut pada tingkat tinggi:
- Browser membuat permintaan ke URL tanpa kredensial
- Jika server memerlukan autentikasi untuk URL tersebut, server merespons dengan pesan 401 Akses Ditolak, dan menyertakan header yang menunjukkan bahwa skema autentikasi dasar didukung
- Browser menerima respons, dan jika dikonfigurasi, akan meminta nama pengguna/kata sandi yang akan disertakan dalam teks biasa di dalam header permintaan untuk permintaan berikutnya ke URL
- Server menerima nama pengguna/kata sandi di dalam header, dan menggunakannya untuk autentikasi
Catatan
Meskipun diskusi terperinci tentang protokol autentikasi ini berada di luar cakupan artikel ini, perlu disebutkan bahwa skema autentikasi dasar mengharuskan SSL aman, karena mengirim nama pengguna/kata sandi dalam teks biasa.
IIS menyertakan dukungan untuk autentikasi dasar terhadap akun Windows yang disimpan di penyimpanan akun lokal atau Direktori Aktif untuk akun domain. Kami ingin memungkinkan pengguna kami mengautentikasi menggunakan autentikasi dasar, tetapi untuk memvalidasi kredensial menggunakan layanan Keanggotaan ASP.NET 2.0 sebagai gantinya. Ini memberikan kebebasan untuk menyimpan informasi pengguna di berbagai penyedia Keanggotaan yang ada, seperti server SQL, tanpa terikat dengan akun Windows.
Tugas 1: Mengembangkan Modul menggunakan .NET
Dalam tugas ini, kami memeriksa pengembangan modul autentikasi yang mendukung skema autentikasi dasar HTTP.1. Modul ini dikembangkan menggunakan pola modul ASP.NET standar yang tersedia sejak ASP.NET v1.0. Pola yang sama ini digunakan untuk membangun modul ASP.NET yang memperluas server IIS. Bahkan, modul ASP.NET yang ada yang ditulis untuk versi IIS sebelumnya dapat digunakan pada IIS, dan memanfaatkan integrasi ASP.NET yang lebih baik untuk memberikan lebih banyak daya ke aplikasi web yang menggunakannya.
Catatan
Kode lengkap untuk modul disediakan dalam Lampiran A.
Modul terkelola adalah kelas .NET yang mengimplementasikan antarmuka System.Web.IHttpModule . Fungsi utama kelas ini adalah mendaftar untuk satu atau beberapa peristiwa yang terjadi dalam alur pemrosesan permintaan IIS, dan kemudian melakukan beberapa pekerjaan yang berguna ketika IIS memanggil penanganan aktivitas modul untuk peristiwa tersebut.
Mari membuat file sumber baru bernama "BasicAuthenticationModule.cs", dan membuat kelas modul (kode sumber lengkap disediakan dalam Lampiran A):
public class BasicAuthenticationModule : System.Web.IHttpModule
{
void Init(HttpApplication context)
{
}
void Dispose()
{
}
}
Fungsi utama metode Init adalah pengabelan metode penanganan aktivitas modul ke peristiwa alur permintaan yang sesuai. Kelas modul menyediakan metode penanganan aktivitas, dan menerapkan fungsionalitas yang diinginkan yang disediakan oleh modul. Ini dibahas lebih lanjut secara rinci.
Metode Buang digunakan untuk membersihkan status modul apa pun saat instans modul dibuang. Biasanya tidak diimplementasikan kecuali modul menggunakan sumber daya tertentu yang perlu dirilis.
Init()
Setelah membuat kelas, langkah selanjutnya adalah menerapkan metode Init . Satu-satunya persyaratan adalah mendaftarkan modul untuk satu atau beberapa peristiwa alur permintaan. Kawat metode modul, yang mengikuti tanda tangan delegasi System.EventHandler, ke peristiwa alur yang diinginkan yang diekspos pada instans System.Web.HttpApplication yang disediakan:
public void Init(HttpApplication context)
{
//
// Subscribe to the authenticate event to perform the
// authentication.
//
context.AuthenticateRequest += new
EventHandler(this.AuthenticateUser);
//
// Subscribe to the EndRequest event to issue the
// challenge if necessary.
//
context.EndRequest += new
EventHandler(this.IssueAuthenticationChallenge);
}
Metode AuthenticateUser dipanggil pada setiap permintaan selama peristiwa AuthenticateRequest . Kami menggunakannya untuk mengautentikasi pengguna berdasarkan informasi kredensial yang ada dalam permintaan.
Metode IssueAuthenticationChallenge dipanggil pada setiap permintaan selama peristiwa EndRequest. Ini bertanggung jawab untuk mengeluarkan tantangan autentikasi dasar kembali ke klien setiap kali modul otorisasi menolak permintaan, dan autentikasi diperlukan.
AuthenticateUser()
Terapkan metode AuthenticateUser . Metode ini melakukan hal berikut:
- Ekstrak kredensial dasar jika ada dari header permintaan masuk. Untuk melihat implementasi langkah ini, lihat metode utilitas ExtractBasicAuthenticationCredentials .
- Upaya untuk memvalidasi kredensial yang disediakan melalui Keanggotaan (menggunakan penyedia keanggotaan default yang dikonfigurasi). Untuk melihat implementasi langkah ini, lihat metode utilitas ValidateCredentials .
- Membuat prinsipal pengguna yang mengidentifikasi pengguna jika autentikasi berhasil, dan mengaitkannya dengan permintaan.
Pada akhir pemrosesan ini, jika modul berhasil mendapatkan dan memvalidasi kredensial pengguna, modul tersebut akan menghasilkan prinsipal pengguna terautentikasi yang nantinya digunakan modul dan kode aplikasi lain dalam keputusan kontrol akses. Misalnya, modul otorisasi URL memeriksa pengguna dalam peristiwa alur berikutnya untuk menegakkan aturan otorisasi yang dikonfigurasi oleh aplikasi.
IssueAuthenticationChallenge()
Terapkan metode IssueAuthenticationChallenge . Metode ini melakukan hal berikut:
- Periksa kode status respons untuk menentukan apakah permintaan ini ditolak.
- Jika demikian, terbitkan header tantangan autentikasi dasar ke respons untuk memicu klien untuk mengautentikasi.
Metode Utilitas
Terapkan metode utilitas yang digunakan modul, termasuk:
- ExtractBasicAuthenticationCredentials. Metode ini mengekstrak kredensial autentikasi dasar dari header permintaan Otorisasi, seperti yang ditentukan dalam skema autentikasi dasar.
- ValidateCredentials. Metode ini mencoba memvalidasi kredensial pengguna dengan menggunakan Keanggotaan. API Keanggotaan mengabstraksi penyimpanan kredensial yang mendasar, dan memungkinkan implementasi penyimpanan kredensial dikonfigurasi dengan menambahkan/menghapus penyedia Keanggotaan melalui konfigurasi.
Catatan
Dalam sampel ini, validasi Keanggotaan dikomentari, dan sebaliknya modul hanya memeriksa apakah nama pengguna dan kata sandi sama dengan string "uji". Ini dilakukan untuk kejelasan, dan tidak ditujukan untuk penyebaran produksi. Anda diundang untuk mengaktifkan validasi kredensial berbasis Keanggotaan hanya dengan membatalkan komentar kode Keanggotaan di dalam ValidateCredentials, dan mengonfigurasi penyedia Keanggotaan untuk aplikasi Anda. Lihat Lampiran C untuk informasi selengkapnya.
Tugas 2: Menyebarkan modul ke aplikasi
Setelah membuat modul di tugas pertama, kami selanjutnya menambahkannya ke aplikasi.
Menyebarkan ke Aplikasi
Pertama, sebarkan modul ke aplikasi. Di sini, Anda memiliki beberapa opsi:
Salin file sumber yang berisi modul ke direktori /App_Code aplikasi. Ini tidak memerlukan kompilasi modul - ASP.NET secara otomatis mengkompilasi dan memuat jenis modul saat aplikasi dimulai. Cukup simpan kode sumber ini sebagai BasicAuthenticationModule.cs di dalam direktori /App_Code aplikasi Anda. Lakukan ini jika Anda tidak merasa nyaman dengan langkah-langkah lain.
Kompilasi modul ke dalam rakitan, dan letakkan rakitan ini di direktori /BIN aplikasi. Ini adalah opsi paling umum jika Anda hanya ingin modul ini tersedia untuk aplikasi ini, dan Anda tidak ingin mengirim sumber modul dengan aplikasi Anda. Kompilasi file sumber modul dengan menjalankan yang berikut ini dari prompt baris perintah:
<PATH_TO_FX_SDK>csc.exe /out:BasicAuthenticationModule.dll /target:library BasicAuthenticationModule.csDi mana
<PATH_TO_FX_SDK>adalah jalur ke SDK .NET Framework yang berisi pengkompilasi CSC.EXE.Kompilasi modul ke dalam rakitan bernama kuat, dan daftarkan rakitan ini di GAC. Ini adalah opsi yang baik jika Anda ingin beberapa aplikasi di komputer Anda menggunakan modul ini. Untuk mempelajari selengkapnya tentang membangun rakitan bernama kuat, lihat Membuat dan menggunakan rakitan bernama kuat.
Sebelum membuat perubahan konfigurasi dalam file web.config aplikasi, kita harus membuka kunci beberapa bagian konfigurasi yang dikunci di tingkat server secara default. Jalankan yang berikut ini dari prompt perintah yang ditinggikan (Mulai > Klik kanan pada Cmd.exe dan pilih "Jalankan sebagai Administrator"):
%windir%\system32\inetsrv\APPCMD.EXE unlock config /section:windowsAuthentication
%windir%\system32\inetsrv\APPCMD.EXE unlock config /section:anonymousAuthentication
Setelah menjalankan perintah ini, Anda akan dapat menentukan bagian konfigurasi ini di file web.config aplikasi Anda.
Konfigurasikan modul Anda untuk dijalankan dalam aplikasi. Mulailah dengan membuat file web.config baru, yang akan berisi konfigurasi yang diperlukan untuk mengaktifkan dan menggunakan modul baru. Mulailah dengan menambahkan teks di bawah ini dan menyimpannya ke akar aplikasi Anda (%systemdrive%\inetpub\wwwroot\web.config jika menggunakan aplikasi root di Situs Web Default).
<configuration>
<system.webServer>
<modules>
</modules>
<security>
<authentication>
<windowsAuthentication enabled="false"/>
<anonymousAuthentication enabled="false"/>
</authentication>
</security>
</system.webServer>
</configuration>
Sebelum mengaktifkan modul autentikasi dasar baru, nonaktifkan semua modul autentikasi IIS lainnya. Secara default, hanya autentikasi Windows dan autentikasi anonim yang diaktifkan. Karena kami tidak ingin browser mencoba mengautentikasi dengan kredensial Windows Anda atau mengizinkan pengguna anonim, kami menonaktifkan modul Autentikasi Windows dan modul autentikasi Anonim.
Sekarang aktifkan modul dengan menambahkannya ke daftar modul yang dimuat oleh aplikasi kami. Buka web.config sekali lagi dan tambahkan entri di dalam ke <modules> tag
<add name="MyBasicAuthenticationModule" type="IIS7Demos.BasicAuthenticationModule" />
Anda juga dapat menyebarkan modul dengan menggunakan Alat Administrasi IIS, atau alat baris perintah APPCMD.EXE.
Konten akhir file web.config aplikasi setelah perubahan ini disediakan di Lampiran B.
Selamat, Anda telah selesai mengonfigurasi modul autentikasi dasar kustom.
Mari kita coba! Buka Internet Explorer, dan buat permintaan ke aplikasi di URL berikut:
http://localhost/
Anda akan melihat dialog login autentikasi dasar. Masukkan "uji" di bidang "Nama pengguna:" dan "uji" di bidang "Kata Sandi:" untuk mendapatkan akses. Perhatikan bahwa jika Anda menyalin HTML, JPG, atau konten lain ke aplikasi Anda, konten tersebut juga akan dilindungi oleh BasicAuthenticationModule baru Anda.
Ringkasan
Dalam artikel ini, Anda mempelajari cara mengembangkan dan menyebarkan modul terkelola kustom untuk aplikasi, dan memungkinkan modul tersebut untuk menyediakan layanan untuk semua permintaan ke aplikasi.
Anda juga menyaksikan kekuatan pengembangan komponen server dalam kode terkelola. Ini memungkinkan pengembangan layanan autentikasi dasar yang diputar dari penyimpanan kredensial Windows.
Jika Anda berani, konfigurasikan modul ini untuk memanfaatkan kekuatan layanan aplikasi Keanggotaan ASP.NET 2.0 untuk mendukung penyimpanan kredensial yang dapat dicolokkan. Lihat Lampiran C untuk informasi selengkapnya.
Temukan banyak sumber daya dan tips tentang menulis modul IIS di blog, http://www.mvolo.com/, serta unduh modul IIS yang ada untuk aplikasi Anda. Untuk beberapa contoh, lihat Mengalihkan permintaan ke aplikasi Anda dengan modul HttpRedirection, Daftar direktori yang terlihat bagus untuk situs web IIS Anda dengan DirectoryListingModule, dan Menampilkan ikon file cantik di aplikasi ASP.NET Anda dengan IconHandler.
Lampiran A: Kode Sumber Modul Autentikasi Dasar
Simpan kode sumber ini sebagai BasicAuthenticationModule.cs di dalam direktori /App_Code untuk menyebarkannya dengan cepat ke aplikasi Anda.
Catatan
Jika Anda menggunakan Notepad, pastikan untuk mengatur Simpan Sebagai: Semua File untuk menghindari penyimpanan file sebagai BasicAuthenticationModule.cs.txt.
#region Using directives
using System;
using System.Collections;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Security.Principal;
using System.IO;
#endregion
namespace IIS7Demos
{
///
/// This module performs basic authentication.
/// For details on basic authentication see RFC 2617.
///
/// The basic operational flow is:
///
/// On AuthenticateRequest:
/// extract the basic authentication credentials
/// verify the credentials
/// if succesfull, create the user principal with these credentials
///
/// On SendResponseHeaders:
/// if the request is being rejected with an unauthorized status code (401),
/// add the basic authentication challenge to trigger basic authentication.
///
///
public class BasicAuthenticationModule : IHttpModule
{
#region member declarations
public const String HttpAuthorizationHeader = "Authorization"; // HTTP1.1 Authorization header
public const String HttpBasicSchemeName = "Basic"; // HTTP1.1 Basic Challenge Scheme Name
public const Char HttpCredentialSeparator = ':'; // HTTP1.1 Credential username and password separator
public const int HttpNotAuthorizedStatusCode = 401; // HTTP1.1 Not authorized response status code
public const String HttpWWWAuthenticateHeader = "WWW-Authenticate"; // HTTP1.1 Basic Challenge Scheme Name
public const String Realm = "demo"; // HTTP.1.1 Basic Challenge Realm
#endregion
#region Main Event Processing Callbacks
public void AuthenticateUser(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
String userName = null;
String password = null;
String realm = null;
String authorizationHeader = context.Request.Headers[HttpAuthorizationHeader];
//
// Extract the basic authentication credentials from the request
//
if (!ExtractBasicCredentials(authorizationHeader, ref userName, ref password))
return;
//
// Validate the user credentials
//
if (!ValidateCredentials(userName, password, realm))
return;
//
// Create the user principal and associate it with the request
//
context.User = new GenericPrincipal(new GenericIdentity(userName), null);
}
public void IssueAuthenticationChallenge(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
//
// Issue a basic challenge if necessary
//
if (context.Response.StatusCode == HttpNotAuthorizedStatusCode)
{
context.Response.AddHeader(HttpWWWAuthenticateHeader, "Basic realm =\"" + Realm + "\"");
}
}
#endregion
#region Utility Methods
protected virtual bool ValidateCredentials(String userName, String password, String realm)
{
//
// Validate the credentials using Membership (refault provider)
//
// NOTE: Membership is commented out for clarity reasons.
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// WARNING: DO NOT USE THE CODE BELOW IN PRODUCTION
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// return Membership.ValidateUser(userName, password);
if (userName.Equals("test") && password.Equals("test"))
{
return true;
}
else
{
return false;
}
}
protected virtual bool ExtractBasicCredentials(String authorizationHeader, ref String username, ref String password)
{
if ((authorizationHeader == null) || (authorizationHeader.Equals(String.Empty)))
return false;
String verifiedAuthorizationHeader = authorizationHeader.Trim();
if (verifiedAuthorizationHeader.IndexOf(HttpBasicSchemeName) != 0)
return false;
// get the credential payload
verifiedAuthorizationHeader = verifiedAuthorizationHeader.Substring(HttpBasicSchemeName.Length, verifiedAuthorizationHeader.Length - HttpBasicSchemeName.Length).Trim();
// decode the base 64 encoded credential payload
byte[] credentialBase64DecodedArray = Convert.FromBase64String(verifiedAuthorizationHeader);
UTF8Encoding encoding = new UTF8Encoding();
String decodedAuthorizationHeader = encoding.GetString(credentialBase64DecodedArray, 0, credentialBase64DecodedArray.Length);
// get the username, password, and realm
int separatorPosition = decodedAuthorizationHeader.IndexOf(HttpCredentialSeparator);
if (separatorPosition <= 0)
return false;
username = decodedAuthorizationHeader.Substring(0, separatorPosition).Trim();
password = decodedAuthorizationHeader.Substring(separatorPosition + 1, (decodedAuthorizationHeader.Length - separatorPosition - 1)).Trim();
if (username.Equals(String.Empty) || password.Equals(String.Empty))
return false;
return true;
}
#endregion
#region IHttpModule Members
public void Init(HttpApplication context)
{
//
// Subscribe to the authenticate event to perform the
// authentication.
//
context.AuthenticateRequest += new
EventHandler(this.AuthenticateUser);
//
// Subscribe to the EndRequest event to issue the
// challenge if necessary.
//
context.EndRequest += new
EventHandler(this.IssueAuthenticationChallenge);
}
public void Dispose()
{
//
// Do nothing here
//
}
#endregion
}
}
Lampiran B: Web.config untuk Modul Autentikasi Dasar
Simpan konfigurasi ini sebagai file web.config di akar aplikasi Anda:
<configuration>
<system.webServer>
<modules>
<add name="MyBasicAuthenticationModule" type="IIS7Demos.BasicAuthenticationModule" />
</modules>
<security>
<authentication>
<windowsAuthentication enabled="false"/>
<anonymousAuthentication enabled="false"/>
</authentication>
</security>
</system.webServer>
</configuration>
Lampiran C: Mengonfigurasi Keanggotaan
Layanan Keanggotaan ASP.NET 2.0 memungkinkan aplikasi untuk dengan cepat menerapkan validasi kredensial dan manajemen pengguna yang diperlukan oleh sebagian besar skema autentikasi dan kontrol akses. Keanggotaan mengisolasi kode aplikasi dari implementasi penyimpanan kredensial aktual, dan menyediakan sejumlah opsi untuk mengintegrasikan dengan penyimpanan kredensial yang ada.
Untuk memanfaatkan Keanggotaan untuk sampel modul ini, batalkan komentar panggilan ke Membership.ValidateUser di dalam metode ValidateCredentials, dan konfigurasikan Penyedia keanggotaan untuk aplikasi Anda. Untuk informasi selengkapnya tentang mengonfigurasi Keanggotaan, lihat Mengonfigurasi Aplikasi ASP.NET untuk Menggunakan Keanggotaan.