VS2013中web項目中自動生成的ASP.NET Identity代碼思考

vs2013沒有再分webform、mvc、api項目,使用vs2013建立一個web項目模板選MVC,身份驗證選我的用戶帳戶。項目會生成ASP.NET Identity的一些代碼。這些代碼主要在AccountController中。html

ASP.NET Identity微軟宣稱的好處就不說了,這是原文web

複製代碼
ASP.NET Identity

As the membership story in ASP.NET has evolved over the years, the ASP.NET team has learned a lot from feedback from customers. The assumption that users will log in by entering a user name and password that they have registered in your own application is no longer valid. The web has become more social. Users are interacting with each other in real time through social channels such as Facebook, Twitter, and other social web sites. Developers want users to be able to log in with their social identities so that they can have a rich experience on their web sites. A modern membership system must enable redirection-based log-ins to authentication providers such as Facebook, Twitter, and others. As web development evolved, so did the patterns of web development. Unit testing of application code became a core concern for application developers. In 2008 ASP.NET added a new framework based on the Model-View-Controller (MVC) pattern, in part to help developers build unit testable ASP.NET applications. Developers who wanted to unit test their application logic also wanted to be able to do that with the membership system. Considering these changes in web application development, ASP.NET Identity was developed with the following goals: • One ASP.NET Identity system •ASP.NET Identity can be used with all of the ASP.NET frameworks, such as ASP.NET MVC, Web Forms, Web Pages, Web API, and SignalR. • ASP.NET Identity can be used when you are building web, phone, store, or hybrid applications. • Ease of plugging in profile data about the user •You have control over the schema of user and profile information. For example, you can easily enable the system to store birth dates entered by users when they register an account in your application. Persistence control •By default, the ASP.NET Identity system stores all the user information in a database. ASP.NET Identity uses Entity Framework Code First to implement all of its persistence mechanism. •Since you control the database schema, common tasks such as changing table names or changing the data type of primary keys is simple to do. •It's easy to plug in different storage mechanisms such as SharePoint, Windows Azure Storage Table Service, NoSQL databases, etc., without having to throw System.NotImplementedExceptions exceptions.  • Unit testability • ASP.NET Identity makes the web application more unit testable. You can write unit tests for the parts of your application that use ASP.NET Identity. • Role provider • There is a role provider which lets you restrict access to parts of your application by roles. You can easily create roles such as 「Admin」 and add users to roles. • Claims Based • ASP.NET Identity supports claims-based authentication, where the user’s identity is represented as a set of claims. Claims allow developers to be a lot more expressive in describing a user’s identity than roles allow. Whereas role membership is just a boolean (member or non-member), a claim can include rich information about the user’s identity and membership. •Social Login Providers • You can easily add social log-ins such as Microsoft Account, Facebook, Twitter, Google, and others to your application, and store the user-specific data in your application. • Windows Azure Active Directory •You can also add log-in functionality using Windows Azure Active Directory, and store the user-specific data in your application. For more information, see Organizational Accounts in Creating ASP.NET Web Projects in Visual Studio 2013 • OWIN Integration • ASP.NET authentication is now based on OWIN middleware that can be used on any OWIN-based host. ASP.NET Identity does not have any dependency on System.Web. It is a fully compliant OWIN framework and can be used in any OWIN hosted application. •ASP.NET Identity uses OWIN Authentication for log-in/log-out of users in the web site. This means that instead of using FormsAuthentication to generate the cookie, the application uses OWIN CookieAuthentication to do that. • NuGet package • ASP.NET Identity is redistributed as a NuGet package which is installed in the ASP.NET MVC, Web Forms and Web API templates that ship with Visual Studio 2013. You can download this NuGet package from the NuGet gallery. •Releasing ASP.NET Identity as a NuGet package makes it easier for the ASP.NET team to iterate on new features and bug fixes, and deliver these to developers in an agile manner.
複製代碼

 

個人感興趣的主要是幾個方面。一、能夠擴展用戶類的字段;二、使用EF codefirst存儲;三、OWIN集成 。四、基於Claims(Claims是什麼,到底有什麼用我都不知道,只知道是.NET框架裏的一個命名空間)。redis

我看了整個代碼以爲它有點相似於三層架構。這裏要特別重要的幾個類:數據庫

  • ApplicationDbContext類。就是繼承字自ef的DbContext,EF codefirst的必備。
  • UserStore類。封裝了數據庫訪問一系列方法,經過DbContext操做數據庫。相似三層架構中的數據訪問層。
  • UserManager類。用戶管理的類,封裝了用戶、角色、Claim等一系列的方法,經過UserStore類與數據庫交互。相似三層的業務邏輯層。
  • AuthenticationManager類。Owin的一些東西,包含了用戶登陸、註銷、驗證等一些方法。
  • ApplicationUser。用戶模型。繼承自IdentityUser,能夠自行擴展屬性。

這個東西怎麼用呢:express

1、設置ApplicationDbContext類

先看下代碼:api

{ public ApplicationDbContext() : base("DefaultConnection") { } }
複製代碼

這個類繼承自IdentityDbContext類,ApplicationUser是用戶模型。cookie

這裏要設置的就是base("DefaultConnection")。數據庫的連接字符串。在web.config的connectionStrings節設置。架構

image

咱們再分析IdentityDbContext類的元數據。併發

image

能夠看出它繼承自DbContext。共再數據庫建立兩個表,Users根據傳輸的用戶模型來建立。角色表 Roles表根據IdentityRole來建立(這個類只有兩個屬性ID和name)看以看出這裏角色的字段是不能擴展的。mvc

2、擴展用戶模型(ApplicationUser)

固然不擴展能夠直接用,當預設不知足要求時就能夠自行擴展字段。首先看下代碼

http://go.microsoft.com/fwlink/?LinkID=317594 to learn more. public class ApplicationUser : IdentityUser { }

是個繼承自IdentityUser的空類,須要擴展的字段直接寫這就行,若是擴展個年齡(Age)

http://go.microsoft.com/fwlink/?LinkID=317594 to learn more. public class ApplicationUser : IdentityUser { public int Age { get; set; } }

咱們看下其繼承的IdentityUser類,這裏面都是一些預知的屬性。IUser是一個接口只有ID和username兩個屬性。

複製代碼
public class IdentityUser : IUser { public IdentityUser(); public IdentityUser(string userName); public virtual ICollection<IdentityUserClaim> Claims { get; } public virtual string Id { get; set; } public virtual ICollection<IdentityUserLogin> Logins { get; } public virtual string PasswordHash { get; set; } public virtual ICollection<IdentityUserRole> Roles { get; } public virtual string SecurityStamp { get; set; } public virtual string UserName { get; set; } }
複製代碼

3、利用UserManager,AuthenticationManager進行用戶相關操做

這一步就可直接在控制器中寫代碼了。咱們先看下AccountController的構造函數

new UserStore<ApplicationUser>( new ApplicationDbContext()))) { }
複製代碼

注意,UserManager,ApplicationUser,UserStore,ApplicationDbContext

一、看下用戶註冊代碼

Register(RegisterViewModel model) { if (ModelState.IsValid) { var user = new ApplicationUser() { UserName = model.UserName }; var result = await UserManager.CreateAsync(user, model.Password); if (result.Succeeded) { await SignInAsync(user, isPersistent: false); return RedirectToAction("Index", "Home"); } else { AddErrors(result);//一個循環向ModelState添加錯誤消息的方法 } } // 若是咱們進行到這一步時某個地方出錯,則從新顯示錶單 return View(model); }
複製代碼

咱們來看下這段代碼。

public async Task<ActionResult> Register(RegisterViewModel model)這句將Register聲明爲異步action。

var user = new ApplicationUser() { UserName = model.UserName };這句是ApplicationUser這個建立模型類。

var result = await UserManager.CreateAsync(user, model.Password);
這句是一個異步添加用戶。利用UserManager這個類的CreateAsync方法建立用戶。

類元數據以下圖,裏面封裝了各類用戶操做的方法。

image

await SignInAsync(user, isPersistent: false);這句依然。這裏是AccountController的一個函數,代碼以下:

private async Task SignInAsync(ApplicationUser user, bool isPersistent) {  AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie); var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie); AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity); }

能夠看出利用AuthenticationManager的SignOut和SignIn進行清除cookie和登陸。

二、再看下注銷

複製代碼
[HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult LogOff() { AuthenticationManager.SignOut(); return RedirectToAction("Index", "Home"); }
複製代碼

使用AuthenticationManager.SignOut方法。這是相似於 WebFor中的FormsAuthentication所使用的FormsAuthentication.SignOut方法。

三、再看登陸代碼

string returnUrl) { if (ModelState.IsValid) { var user = await UserManager.FindAsync(model.UserName, model.Password); if (user != null) { await SignInAsync(user, model.RememberMe); return RedirectToLocal(returnUrl); } else { ModelState.AddModelError("", "Invalid username or password."); } } // 若是咱們進行到這一步時某個地方出錯,則從新顯示錶單 return View(model); }
複製代碼

代碼比較相似,用UserManager的FindAsync查找用戶,成功又有是用調用SignInAsync方法進行登陸(方法內部是用AuthenticationManager的SignIn進行登陸)

4、總結

這裏用到的是ApplicationDbContext、UserStore、UserManager、 AuthenticationManager、ApplicationUser這5個類。其中ApplicationDbContext須要設置鏈接字符 串,ApplicationUser能夠擴展用戶字段,UserStore、UserManager、AuthenticationManager這三個 類都封裝好的類直接拿來用就行,關鍵是要理解方法和屬性的含義、清楚其用途。

5、問題及思考

  • 依靠[Authorize]應該是用來驗證用戶是否登陸的,直接用來進行權限管理(控制器上寫[Authorize(Roles="管理員")])是否是太僵化了?
  • Claims這是東西什麼東西,歷來沒用過,是否與權限有關?
做者: 洞庭夕照
出處: http://mzwhj.cnblogs.com http://www.cnblogs.com/mzwhj/p/3540017.html
本文由 洞庭夕照原創,併發布到博客園,歡迎轉載,但必須在文章頁面明顯位置寫明做者和出處,很是感謝!
相關文章
相關標籤/搜索