ASP.NET應用程序的安全方案(一)
發(fā)表時間:2024-02-22 來源:明輝站整理相關軟件相關文章人氣:
[摘要]摘要:本文ASP.NET應用程序身份驗證的概念,介紹了各種身份驗證模式并進行了比較,闡述了選擇身份驗證模式的機制,并給出了一種基于窗體身份驗證模式的實現(xiàn)方法。關鍵字:身份驗證 authentication ASP.NET WEB應用1.身份驗證概念 任何成功的應用程序安全策略的基礎都是穩(wěn)固的...
摘要:本文ASP.NET應用程序身份驗證的概念,介紹了各種身份驗證模式并進行了比較,闡述了選擇身份驗證模式的機制,并給出了一種基于窗體身份驗證模式的實現(xiàn)方法。
關鍵字:身份驗證 authentication ASP.NET WEB應用
1.身份驗證概念
任何成功的應用程序安全策略的基礎都是穩(wěn)固的身份驗證和授權手段,以及提供機密數(shù)據(jù)的保密性和完整性的安全通訊。
身份驗證(authentication)是一個標識應用程序客戶端的過程,這里的客戶端可能包括終端用戶、服務、進程或計算機,通過了身份驗證的客戶端被稱為主體(principal)。身份驗證可以跨越應用程序的多個層發(fā)生。終端用戶起初由Web應用程序進行身份驗證,通常根據(jù)用戶名和密碼進行;隨后終端用戶的請求由中間層應用程序服務器和數(shù)據(jù)庫服務器進行處理,這過程中也將進行身份驗證以便驗證并處理這些請求。
圖1列出了各種安全技術以及每種技術所提供的主要驗證方式。
2. 身份驗證模式
如圖1所示,Windows 2000上的.NET框架上提供了以下幾種身份驗證:
ASP.NET身份驗證模式
Enterprise Services身份驗證
SQL Server身份驗證
2.1 ASP.NET身份驗證模式
ASP.NET身份驗證模式包括Windows、Forms(窗體)、Passport(護照)和None(無)。
2.1.1 Windows身份驗證
使用這種身份驗證模式時,ASP.NET依賴于IIS對用戶進行驗證,并創(chuàng)建一個Windows訪問令牌來表示已通過驗證的標識。IIS提供以下幾種身份驗證機制:
基本身份驗證
簡要身份驗證
集成Windows身份驗證
證書身份驗證
匿名身份驗證
2.1.2 護照身份驗證
使用這種身份驗證模式時,ASP.NET使用Microsoft Passport的集中式身份驗證服務,ASP.NET為Microsoft Passport軟件開發(fā)包(SDK)所提供的功能提供了一個方便的包裝(Wrapper)。此SDK必須安裝在WEB服務器上。
2.1.3 窗體身份驗證
這種驗證方式使用客戶端重定向功能,將未通過身份驗證的用戶轉發(fā)到特定的登錄窗體,要求用戶輸入其憑據(jù)信息(通常是用戶名和密碼)。這些憑據(jù)信息被驗證后,系統(tǒng)生成一個身份驗證票證(ticket)并將其返回客戶端。身份驗證票證可在用戶的會話期間維護用戶的身份標識信息,以及用戶所屬的角色列表(可選)。
2.1.4 None
使用這種身份驗證模式,表示你不希望對用戶進行驗證,或是采用自定義的身份驗證協(xié)議。
2.2 Enterprise Services身份驗證
Enterprise Services身份驗證通過使用底層的遠程過程調(diào)用(RPC,Remote Procedure Call)傳輸結構來進行,而這種結構又使用了操作系統(tǒng)安全服務提供程序接口(SSPI,Security Service Provider Interface)?梢岳肒erberose或NTLM身份驗證機制對Enterprise Services應用程序的客戶端進行驗證。
2.3 SQL Server身份驗證
SQL Server可以通過Windows身份驗證機制(Kerberose或NTLM),也可以通過其內(nèi)置的身份驗證方案-SQL身份驗證機制進行驗證。通常有兩種可用的驗證方案。
2.3.1 SQL Server and Windows
客戶端可用通過SQL Server身份驗證或Windows身份驗證機制來連接SQL Server的某個實例。這種方式有時也被稱為混合模式的身份驗證。
2.3.2 Windows Only
客戶端必須通過使用Windows身份驗證機制來連接到SQL Server的一個實例。
3. 選擇身份驗證機制
設計分布式應用程序的身份驗證是一項具有挑戰(zhàn)性的任務。在應用程序開發(fā)的早期階段,進行適當?shù)纳矸蒡炞C設計有助于降低許多安全風險。
3.1 各種身份驗證機制的比較
用戶是否需要在服務器域中擁有Windows帳戶 是否支持委托 是否需要Windows 2000客戶端和服務器 憑據(jù)是否明文傳輸(需要SSL) 是否支持非IE瀏覽器
基本身份驗證 是 是 否 是 是
簡要身份驗證 是 否 是 否 否
NTLM身份驗證 是 否 否 否 否
Kerberos身份驗證 是 是 是 否 否
證書身份驗證 否 是 否 否 是
窗體身份驗證 否 是 否 是 是
護照身份驗證 否 是 否 否 是
3.2 選擇身份驗證機制需要考慮的因素
標識 只有當應用程序的用戶具有的Windows帳戶可以通過一個受信任的權威機構(它可以被應用程序Web服務器訪問)來進行驗證時,使用Windows身份驗證機制才是合適的。
憑據(jù)管理 Windows身份驗證的一個關鍵優(yōu)勢在于它可以使用操作系統(tǒng)進行憑據(jù)管理。當使用非Windows身份驗證方式,例如窗體身份驗證時,必須仔細考慮在何處以及如何保存用戶憑據(jù)。其中最常用的方式是使用SQL Server數(shù)據(jù)庫或是使用位于Active Directory中的User對象。
標識流動 是否需要實現(xiàn)一個模擬/委托模型,并將原始調(diào)用者的安全上下文在操作系統(tǒng)級進行跨層流動-例如,以便支持審核或針對每個用戶的精細授權。
瀏覽器類型 應用程序的所有用戶是否都擁有IE瀏覽器?或是你是否需要支持一個具有混合型瀏覽器的用戶群? 我們選擇身份驗證時需要根據(jù)各種方式的特點,綜合考慮以上因素。
3.3 Intranet系統(tǒng)的選擇決策流程
參見圖2。
3.4 SQL Server用戶驗證
對SQL Server的客戶端進行驗證,一般說來Windows身份驗證要比SQL Server身份驗證更安全,原因主要有以下幾點:
前者負責管理用戶的憑據(jù)信息,而且用戶的憑據(jù)不會在網(wǎng)絡上傳輸。
可以避免在連接字符串中嵌入用戶名和密碼。
可通過密碼過期時限、最小密碼長度、以及多次無效登錄后請求的帳戶鎖定等措施改進登錄安全性。這樣可以見少詞典攻擊的威脅。
但是某些特定的應用程序方案中不允許使用Windows身份驗證,例如:
數(shù)據(jù)庫客戶端和數(shù)據(jù)庫服務器由一個防火墻分隔開,從而導致無法使用Windows身份驗證。
應用程序需要使用多個標識連接到一個或多個數(shù)據(jù)庫。
連接到的數(shù)據(jù)庫不是SQL Server。
在ASP.NET中沒有一種安全的方式以特定的Windows用戶的身份運行代碼。
在以上這些方案中,將必須使用SQL身份驗證,或是數(shù)據(jù)庫的本機身份驗證機制。
4. ASP.NET身份驗證實現(xiàn)
4.1 方案特性
在這部分,僅提供了一種Intranet下交互式WEB應用程序的身份驗證的實現(xiàn),本方案假設具有以下特性:
只有通過了身份驗證的客戶端才能訪問應用程序。
數(shù)據(jù)庫相信應用程序對用戶進行了相應的身份驗證-即應用程序代表用戶對數(shù)據(jù)庫進行調(diào)用。
WEB應用程序通過使用ASP.NET進程帳戶連接到數(shù)據(jù)庫。
用戶的憑據(jù)信息是根據(jù)SQL Server數(shù)據(jù)庫進行驗證的。
使用窗體身份驗證模式。
在WEB應用程序中,用戶的憑據(jù)信息是根據(jù)SQL Server數(shù)據(jù)庫,采用窗體身份驗證模式,便于實現(xiàn)用戶個性化設計。采用應用程序代表用戶對數(shù)據(jù)庫進行調(diào)用的方式,可采用受信任子系統(tǒng)模型,更好地利用數(shù)據(jù)庫連接池,并且可以保證用戶不能直接訪問后端數(shù)據(jù)庫,另外可以減少后端的ACL管理工作。
4.2 安全配置步驟
4.2.1 IIS配置步驟
對Web服務的虛擬根目錄啟用匿名訪問。
主要方法是使用IIS MMC管理單元,右擊應用程序的虛擬目錄,然后單擊屬性---〉目錄安全性--〉匿名訪問和安全控制--〉編輯。
4.2.2 ASP.NET配置步驟
1. 將ASPNET帳戶(用于運行ASP.NET)的密碼重新設置為一個更安全的密碼。
這樣允許在數(shù)據(jù)庫服務器上復制一個本地帳戶(具有相同的用戶名和密碼)。為了使用Windows身份驗證連接到數(shù)據(jù)庫時,能夠使ASPNET帳戶對來自數(shù)據(jù)庫的網(wǎng)絡身份驗證要求進行響應,這是必須的。
具體方法是編輯位于%windr%\Microsoft.NET\Framework\v1.1.4322\CONFIG目錄下的Machine.config文件,將<processModel>元素上的密碼屬性重新配置,將其默認值<!-UserName="machine" password="AutoGenerate" -->改為<!-UserName="machine" password="NewPassword" -->。
2. 配置ASP.NET,使用窗體身份驗證。
編輯位于WEB服務的虛擬根目錄下的Web.config文件,將<authentication>元素設置為:
<authentication mode="Forms" >
<forms name="MyAppFormAuth" loginUrl="login.aspx" protection="All" timeout="20" path="/">
</forms>
</authentication>
4.2.3 配置SQL Server
1. 在SQL Server數(shù)據(jù)庫上創(chuàng)建一個和ASP.NET進程帳戶匹配的Windows帳戶。
用戶名和密碼必須和ASP.NET應用程序帳號匹配。
2. 配置SQL Server,使其使用Windows身份驗證。
3. 為自定義的ASP.NET應用程序帳戶創(chuàng)建一個SQL Server登錄,授予對SQL Server的訪問權。
4. 創(chuàng)建一個新的數(shù)據(jù)庫用戶,并將登錄名映射為數(shù)據(jù)庫用戶。
5. 創(chuàng)建一個用戶定義的新數(shù)據(jù)庫角色,并將數(shù)據(jù)庫用戶添加到該角色。
6. 為數(shù)據(jù)庫角色確定數(shù)據(jù)庫權限。
4.3 程序代碼
4.3.1 身份驗證事件序列
當未通過身份驗證的用戶試圖放一個受保護的文件或資源被拒絕時,觸發(fā)的事件序列如圖3所示。
4.3.2 代碼實現(xiàn)步驟
1. 建一個WEB登錄窗體并驗證用戶提供的憑據(jù)信息
根據(jù)SQL Server數(shù)據(jù)庫來驗證憑據(jù)信息。
2. 從數(shù)據(jù)庫里獲取角色列表
3. 創(chuàng)建窗體身份驗證票證
在票證中保存所獲取的角色信息。示例代碼如下:
private void btnLogin_Click(object sender, System.EventArgs e)
{
//根據(jù)SQL Server數(shù)據(jù)庫進行驗證(具體實現(xiàn)略)。
bool isAuthenticated = IsAuthenticated( txtUserName.Text, txtPassword.Text );
if (isAuthenticated == true )
{
//獲取用戶的角色
string roles = GetRoles( txtUserName.Text, txtPassword.Text );
// 創(chuàng)建身份驗證票證
FormsAuthenticationTicket authTicket = new
FormsAuthenticationTicket(1, // version
txtUserName.Text, // user name
DateTime.Now, // creation
DateTime.Now.AddMinutes(60),// Expiration
false, // Persistent
roles ); // User data
string encryptedTicket = FormsAuthentication.Encrypt(authTicket);
// 創(chuàng)建Cookie
HttpCookie authCookie =
new HttpCookie(FormsAuthentication.FormsCookieName,
encryptedTicket);
Response.Cookies.Add(authCookie);
// 將用戶重定向到最初請求頁面。
Response.Redirect( FormsAuthentication.GetRedirectUrl(
txtUserName.Text,
false ));
}
}
4. 創(chuàng)建IPrincipal對象 可在Application_AuthenticateRequest事件中創(chuàng)建一個IPrincipal對象,一般使用GenericPrincipal類。
5. 將IPrincipal對象置于當前的HTTP上下文
protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
// 提去窗體身份驗證cookie
string cookieName = FormsAuthentication.FormsCookieName;
HttpCookie authCookie = Context.Request.Cookies[cookieName];
if(null == authCookie)
{
return;
}
FormsAuthenticationTicket authTicket = null;
try
{
authTicket = FormsAuthentication.Decrypt(authCookie.Value);
}
catch(Exception ex)
{
return;
}
if (null == authTicket)
{
return;
}
//提取角色
string[] roles = authTicket.UserData.Split(new char[]{' '});
// 創(chuàng)建Identity object
FormsIdentity id = new FormsIdentity( authTicket );
GenericPrincipal principal = new GenericPrincipal(id, roles);
Context.User = principal;
}
具體的代碼讀者可以自行補充完成。
5. 后記
與授權與安全通訊有關的內(nèi)容將