3.3 Intranet系統(tǒng)的選擇決策流程 參見圖2。
3.4 SQL Server用戶驗證 對SQL Server的客戶端進(jìn)行驗證,一般說來Windows身份驗證要比SQL Server身份驗證更安全,原因主要有以下幾點(diǎn): 前者負(fù)責(zé)管理用戶的憑據(jù)信息,而且用戶的憑據(jù)不會在網(wǎng)絡(luò)上傳輸。可以避免在連接字符串中嵌入用戶名和密碼。可通過密碼過期時限、最小密碼長度、以及多次無效登錄后請求的帳戶鎖定等措施改進(jìn)登錄安全性。這樣可以見少詞典攻擊的威脅。 但是某些特定的應(yīng)用程序方案中不允許使用Windows身份驗證,例如: 數(shù)據(jù)庫客戶端和數(shù)據(jù)庫服務(wù)器由一個防火墻分隔開,從而導(dǎo)致無法使用Windows身份驗證。應(yīng)用程序需要使用多個標(biāo)識連接到一個或多個數(shù)據(jù)庫。連接到的數(shù)據(jù)庫不是SQL Server。在ASP.NET中沒有一種安全的方式以特定的Windows用戶的身份運(yùn)行代碼。 在以上這些方案中,將必須使用SQL身份驗證,或是數(shù)據(jù)庫的本機(jī)身份驗證機(jī)制。
4. ASP.NET身份驗證實(shí)現(xiàn) 4.1 方案特性在這部分,僅提供了一種Intranet下交互式WEB應(yīng)用程序的身份驗證的實(shí)現(xiàn),本方案假設(shè)具有以下特性: 只有通過了身份驗證的客戶端才能訪問應(yīng)用程序。數(shù)據(jù)庫相信應(yīng)用程序?qū)τ脩暨M(jìn)行了相應(yīng)的身份驗證-即應(yīng)用程序代表用戶對數(shù)據(jù)庫進(jìn)行調(diào)用。 WEB應(yīng)用程序通過使用ASP.NET進(jìn)程帳戶連接到數(shù)據(jù)庫。用戶的憑據(jù)信息是根據(jù)SQL Server數(shù)據(jù)庫進(jìn)行驗證的。使用窗體身份驗證模式。 在WEB應(yīng)用程序中,用戶的憑據(jù)信息是根據(jù)SQL Server數(shù)據(jù)庫,采用窗體身份驗證模式,便于實(shí)現(xiàn)用戶個性化設(shè)計。采用應(yīng)用程序代表用戶對數(shù)據(jù)庫進(jìn)行調(diào)用的方式,可采用受信任子系統(tǒng)模型,更好地利用數(shù)據(jù)庫連接池,并且可以保證用戶不能直接訪問后端數(shù)據(jù)庫,另外可以減少后端的ACL管理工作。
4.2 安全配置步驟 4.2.1 IIS配置步驟 對Web服務(wù)的虛擬根目錄啟用匿名訪問。
主要方法是使用IIS MMC管理單元,右擊應(yīng)用程序的虛擬目錄,然后單擊屬性---〉目錄安全性--〉匿名訪問和安全控制--〉編輯。
4.2.2 ASP.NET配置步驟 1. 將ASPNET帳戶(用于運(yùn)行ASP.NET)的密碼重新設(shè)置為一個更安全的密碼。
這樣允許在數(shù)據(jù)庫服務(wù)器上復(fù)制一個本地帳戶(具有相同的用戶名和密碼)。為了使用Windows身份驗證連接到數(shù)據(jù)庫時,能夠使ASPNET帳戶對來自數(shù)據(jù)庫的網(wǎng)絡(luò)身份驗證要求進(jìn)行響應(yīng),這是必須的。
具體方法是編輯位于%windr%\Microsoft.NET\Framework\v1.1.4322\CONFIG目錄下的 Machine.config文件,將<processModel>元素上的密碼屬性重新配置,將其默認(rèn)值<!-UserName= "machine" password="AutoGenerate" -->改為<!-UserName="machine" password="NewPassword" -->。
2. 配置ASP.NET,使用窗體身份驗證。
編輯位于WEB服務(wù)的虛擬根目錄下的Web.config文件,將<authentication>元素設(shè)置為:
<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進(jìn)程帳戶匹配的Windows帳戶。
用戶名和密碼必須和ASP.NET應(yīng)用程序帳號匹配。
2. 配置SQL Server,使其使用Windows身份驗證。
3. 為自定義的ASP.NET應(yīng)用程序帳戶創(chuàng)建一個SQL Server登錄,授予對SQL Server的訪問權(quán)。
4. 創(chuàng)建一個新的數(shù)據(jù)庫用戶,并將登錄名映射為數(shù)據(jù)庫用戶。
5. 創(chuàng)建一個用戶定義的新數(shù)據(jù)庫角色,并將數(shù)據(jù)庫用戶添加到該角色。
6. 為數(shù)據(jù)庫角色確定數(shù)據(jù)庫權(quán)限。
4.3 程序代碼 4.3.1 身份驗證事件序列 當(dāng)未通過身份驗證的用戶試圖放一個受保護(hù)的文件或資源被拒絕時,觸發(fā)的事件序列如圖3所示。
4.3.2 代碼實(shí)現(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ù)庫進(jìn)行驗證(具體實(shí)現(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對象置于當(dāng)前的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;
}
具體的代碼讀者可以自行補(bǔ)充完成。
5. 后記與授權(quán)與安全通訊有關(guān)的內(nèi)容將另外論述。 ---------------------- 服務(wù)器安全討論區(qū)
http://www.safe263.cn