ASP.NET實際開發中身份驗證 是一個不可回避的問題。在相當一段長的時間內,由于不求甚解,我對這個話題似懂非懂。今天就對它做個簡單的小結。
Authentication and Authorization(身份驗證和授權)
在開始ASP.NET身份驗證之前,我們必須了解兩個概念:Authentication and Authorization
Authentication是識別該用戶的身份,換句話說,它檢查特定用戶是不是特定網站的用戶,它回答了“Who are you”的問題。
Authorization 是識別該用戶的權限,換句話說,它檢查特定用戶是否有權限訪問website站點上的某些資源,它回到了“What right's you have”的問題。
當一個用戶訪問某個站點時,比方說http://job.VEVb.com/如果你要發送簡歷或者是發布招聘信息,但是你還不是VEVb.com的注冊用戶,那么你沒辦法登錄成功,你的身份標識是匿名用戶,你的權限是可以看到這些招聘信息。當你想投遞簡歷或者發布自己的招聘信息的時候,你必須成為注冊用戶并且滿足一些條件才行。也就是你得先被authentication然后被authorization。
Roles and permissions(角色和權限)
上面說到ASP.NET身份驗證其實是囊括了兩個概念Authentication and Authorization,伴隨而來的兩個概念是Roles and permissions它們的關系是多對多的關系。即一個角色可以同時擁有多個權限,一個權限也可以隸屬于多個絕色。比方說,曹操是可以劍履上殿,三公都可以開府。角色和權限與身份驗證和授權不同,大多數站點的策略是即使沒有通過身份驗證和授權,也不影響某個用戶是否擁有特定角色和權限。比方說你無需登錄也可以以匿名用戶的角色擁有查看到VEVb博文的權限。
PRincipal and Identity objects
如果你要得到身份認證的細節,你需要Identity對象,通過IIdentity.Name來查看“Who are you”如果你要得到授權身份的細節,你需要Principal對象,通過IPrincipal.IsInRole()來查看“What rights you have”
Types of authentication and authorization in ASP.NET(ASP.NET的身份驗證和授權的方式)
a.Windows authentication 使用本地windows用戶組進行身份驗證和授權b.Forms Authentication 它是一種將username和passWord存儲在客戶端計算機的cookie文件上或者(cookie不能用了)在每次請求的時通過加密后在URL地址傳遞的基于cookie/URL的身份驗證,它為用戶提供了基于html的Web頁面來輸入用戶憑證c.Passport authentication 它是基于微軟提供的通行證網站,當用戶登錄憑證達到通行證網站,將會發生認證,如果認證成功,將令牌返回到你的網站。d.Custom Authentication Mechanisms 它是用戶自定義身份驗證,比如基于iis的HttpModule身份驗證、PageBase身份驗證、自定義MembershipProvider身份驗證e.Anonymous access 即不采用任何認證方式,也就是允許匿名用戶來訪問。
身份驗證的方式有以上種種,每一種驗證方式都是可以細細玩味,由于篇幅和資質的原因,我今天就先說說第二種Forms Authentication
Forms Authentication(窗體身份驗證)
表單驗證的流程:
1.用戶在登錄界面輸入用戶名和密碼2.檢查用戶名和密碼3.驗證成功,將會在客戶端生成cookie文本,當用戶瀏覽該網站的其它資源文件,由于客戶端有cookie文件存在,將不在進行驗證。
表單驗證實例:
1.使用web.config作為數據源2.使用SQL server作為數據源3.使用ASP.NET Membership and role進行表單驗證
a.運行aspnet_regsql.exeb.配置連接字符串c.配置ASP.NET membership provider d.配置role provider
›使用web.config作為數據源

網站項目文件結構如上所示。現在實現的目標是:拒絕匿名用戶訪問本網站,Employee用戶可以訪問Employee下的資源,Manager用戶可以同時訪問Employee和Manager下的資源。
首先,在web.config文件中做如下配置:
<configuration> <system.web> <compilation debug="true" targetFramework="4.5" /> <httpRuntime targetFramework="4.5" /> <!--身份認證--> <authentication mode="Forms"> <forms loginUrl="Login.aspx" timeout="30" defaultUrl="Index.aspx" cookieless="UseDeviceProfile" > </forms> </authentication> <authorization> <deny users="?"/> <!--拒絕匿名用戶--> </authorization> </system.web> <!--控制資源的訪問權限--> <location path="Manager"> <system.web> <authorization> <deny users="*"/> </authorization> </system.web> </location> <location path="Employee"> <system.web> <authorization> <deny users="*"/> </authorization> </system.web> </location></configuration>
接下來,創建用戶憑證:
<system.web> <compilation debug="true" targetFramework="4.5" /> <httpRuntime targetFramework="4.5" /> <!--身份認證--> <authentication mode="Forms"> <forms loginUrl="Login.aspx" timeout="30" defaultUrl="Index.aspx" cookieless="UseDeviceProfile" > <credentials passwordFormat="Clear"> <user name="flowers" password="flowers"/> <user name="Jim" password="Jim"/> </credentials> </forms> </authentication> <authorization> <deny users="?"/> <!--拒絕匿名用戶--> </authorization></system.web><!--控制資源的訪問權限--><location path="Manager"> <system.web> <authorization> <allow users="flowers"/> <deny users="*"/> </authorization> </system.web></location><location path="Employee"> <system.web> <authorization> <allow users="flowers"/> <allow users="Jim"/> <deny users="*"/> </authorization> </system.web></location>
接下來在登錄頁面的登錄按鈕中進行登錄驗證:
protected void btnLogin_ServerClick(object sender, EventArgs e){ if (FormsAuthentication.Authenticate(txtUserName.Value, txtUserPass.Value)) { FormsAuthentication.RedirectFromLoginPage(txtUserName.Value, chkPersistCookie.Checked); //此時設置defaultUrl是必須的。當Loginout之后再次登錄,它將跳轉致你設置的defaultUrl地址 } else Response.Redirect("Login.aspx", true);}接下來,看結果。
先使用flowers登錄,看看他是不是能同時訪問Employee和Manager下的Default.aspx




不出所料,訪問成功了,再來看看Jim是不是只能訪問Employee下的DDefault.aspx


也如預期所料,那么當Jim試圖訪問Manager的時候被拒絕,

以上是使用web.config作為數據存儲來實現表單驗證。這種方式很簡單,但是在實際生產過程中,我想用戶數據量大的情況下,不宜采用它。
代碼下載
›使用SQL server作為數據源
依舊使用上面的demo稍作修改。配置文件如下:
<system.web> <compilation debug="true" targetFramework="4.5" /> <httpRuntime targetFramework="4.5" /> <!--身份認證--> <authentication mode="Forms"> <forms loginUrl="Login.aspx" timeout="30" defaultUrl="Index.aspx" cookieless="UseDeviceProfile" > </forms> </authentication> <authorization> <deny users="?"/> <!--拒絕匿名用戶--> </authorization></system.web><!--控制資源的訪問權限--><location path="Manager"> <system.web> <authorization> <allow roles="Manager" /> <deny users="*"/> </authorization> </system.web></location><location path="Employee"> <system.web> <authorization> <allow roles="Employee,Manager" /> <deny users="*"/> </authorization> </system.web></location>
為了簡單,我在User類中使用靜態數據模擬(大家可以看看微軟的基于SQL數據庫的表單的身份驗證demo)。
public class User{ public string UserName { get; set; } public string Password { get; set; } public int Role { get; set; } public static List<User> users = new List<User>() { new User { UserName = "Jim", Password = "Jim",Role=1}, new User { UserName = "flowers", Password = "flowers",Role=2 } }; public static User GetUser(string name, string password) { return users.FirstOrDefault(i => i.UserName == name && i.Password == password); } public static User GetUser(string name) { return users.FirstOrDefault(i => i.UserName == name); }}添加角色枚舉:
/// <summary>/// Role 的摘要說明/// </summary>public enum Role{ Anonymous = 0, Employee = 1, Manager = 2}修改登錄頁面的登錄按鈕事件:
private bool ValidateUser(string userName, string passWord, out int role){ //http://support.microsoft.com/kb/301240 var user =FormAuthenticationDemo.User.GetUser(userName, passWord); if (user != null) { role = user.Role; return true; } else { role = Convert.ToInt32(FormAuthenticationDemo.Role.Anonymous); return false; }}protected void btnLogin_ServerClick(object sender, EventArgs e){ int role; if (ValidateUser(txtUserName.Value, txtUserPass.Value, out role)) { FormsAuthentication.RedirectFromLoginPage(txtUserName.Value, chkPe
新聞熱點
疑難解答