ASP.NET Identity 使用簡介__.net

來源:互聯網
上載者:User
1. 什麼是 ASP.NET Identity

ASP.NET Identity 是微軟推出,用於在ASP.NET應用中系統管理使用者的組件。

 

The mainstay for user management in recent years has been ASP.NET Membership, which has suffered from design choices. The biggest limitation is that the schema used to store the data worked only with SQL Server and was difficult to extend without re-implementing a lot of provider classes. The schema itself was overly complex, which made it harder to implement changes than it should have been.

  --Pro ASP.NET MVC 5 Platform

  2. 如何配置ASP.NET Identity with MySQL 2.1 配置ASP.NET Identity 2.1.1 安裝相應的組件包

Microsoft.AspNet.Identity.EntityFramework

Microsoft.AspNet.Identity.OWIN

Microsoft.Owin.Host.SystemWeb

  2.1.2 自訂核心組件

$ User model

預設的user model是 IdentityUser(Microsoft.AspNet.Identity.EntityFramework)。這個類有12個內建的屬性,如 Id、UserName、PasswordHash、Email等

一般,根據業務需求,我們需要其它額外的屬性。我們可以建立一個繼承自IdentityUser的自訂類,在這個自訂類中添加額外的屬性。

using Microsoft.AspNet.Identity.EntityFrameworkpublic class AppUser : IdentityUser {    // 在這裡添加額外的屬性}

 

$ DB Context

一般我們需要改變Identity用到的資料庫表的名稱。預設的資料庫表為:AspNetUsers、AspNetUserRoles、AspNetUserLogins、AspNetUserCliams、AspNetRoles。

using System.Data.Entity;using Microsoft.Asp.Net.Identity.EntityFramework;public class AppIdentityDbContext : IdentityDbContext<AppUser> {    public AppIdentityDbContext() : base("IdentityDb") { }    public AppIdentityDbContext(string connectionString)        : base(connectionString) {    }    protected override void OnModelCreating(DbModelBuilder modelBuilder {        base.OnModelCreating(modelBuilder);        modelBuilder.Entity<AppUser>().ToTable("user");        modelBuilder.Entity<IdentityRole>().ToTable("role");        modelBuilder.Entity<IdentityUserRole>().ToTable("userrole");        modelBuilder.Entity<IdentityUserClaim>().ToTable("userclaim");        modelBuilder.Entity<IdentituUserLogin>().ToTable("userlogin");    }}

 

$ DB 初始化

如果你不熟悉Identity的資料庫表的結構,可以通過代碼讓Identity自動建立。

如果你比較熟悉,那我推薦用專業的資料庫管理工具來建立,如MySQL Workbench。

程式碼範例。一般初始化代碼只需要執行一次,好好斟酌策略,防止資料被刪。

using System.Data.Entity;public class AppIdentityDbContext : IdentityDbContext<AppUser> {    ...    static AppIdentityDbContext() {        Database.SetInitializer<AppIdentityDbContext>(new IdentityDbInit());    }}

 

using System.Data.Entity;using Microsoft.AspNet.Identity;using Microsoft.AspNet.Identity.EntityFramework;public class IdentityDbInit : DropCreateDatabaseAlways<AppIdentityDbContext> {    protectedd override void Seed(AppIdentityDbContext context) {        this.InitAdmin(context);        base.Seed(context);    }    public void InitAdmin(AppIdentityDbContext context) {        string adminName = "admin";        string adminPassword = "changeme";        string adminRoleName = "Administrators";        // 建立使用者        UserManager<AppUser> userManager = new UserManager<AppUser>(            new UserStore<AppUser>(context));        var user = new AppUser { UserName = adminName };        userManager.Create(user, adminPassword);        // 建立角色        RoleManager<IdentityRole> roleManager = new RoleManager<IdentityRole>(            new RoleStore<IdentityRole>(context));        var adminRole = roleManager.Create(new IdentityRole(adminRoleName));        // 給使用者賦予角色        userManager.AddToRole(user.Id, adminRoleName);    }}

 

$ 配置

using Microsoft.AspNet.Identity;using Microsoft.AspNet.Identity.EntityFramework;using Microsoft.AspNet.Identity.Owin;using Microsoft.Owin;using Microsoft.Owin.Security.Cookies;using Owin;public class IdentityConfig {    public void Configuration(IAppBuilder app) {        app.CreatePerOwinContext<AppIdentityDbContext>(() => new AppIdentityDbContext());        app.CreatePerOwinContext<UserManager<AppUser>>(            (o, c) => new UserManager<AppUser>(new UserStore<AppUser>(                c.Get<AppIdentityDbContext>())));        app.CreatePerOwinContext<RoleManager<IdentityRole>>(            (o, c) => new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(                c.Get<AppIdentityDbContext>())));        app.UseCookieAuthentication(new CookieAuthenticationOptions {            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,            LoginPath = new PathString("/Account/Login")        });    }}

  2.1.3 配置web.config

<configuration>  <appSettings>    <add key="owin:AppStartup" value="IdentityConfig" />    ...  </appSettings>  ...</configuration>

  2.2 配置MySQL DB 2.2.1 安裝相應的組件包

MySql.Data.Entity

  2.2.2 配置web.config

 

<configuration>  <configSections>    <section name="entityFramework"         type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework">  </configSections>  <system.data>    <DbProviderFactories>  <remove invariant="MySql.Data.MySqlClient" />  <add name="MySQL Data Provider"       invariant="MySql.Data.MySqlClient"   description=".Net Framework Data Provider for MySQL"   type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data" /></DbProviderFactories>  </system.data>  <connectionStrings>    <add name="IdentityDb"     connectionString="server=192.168.0.9;user id=tester;password=changeme;database=IdentityDb" providerName="MySql.Data.MySqlClient" />  </connectionStrings>  <entityFramework>    <providers>  <provider invariantName="MySql.Data.MySqlClient"  type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6" /></providers>  </entityFramework></configuration>

  2.2.3 建立DB

方法一:建立一個沒有表的空DB,通過代碼讓Identity自動建立表。(見上文)

方法二:建立一個帶有所有Identity相關表的DB

 

$ User


 

CREATE TABLE `user` (  `Id` varchar(128) NOT NULL,  `Email` varchar(256) DEFAULT NULL,  `EmailConfirmed` tinyint(1) NOT NULL,  `PasswordHash` longtext,  `SecurityStamp` longtext,  `PhoneNumber` longtext,  `PhoneNumberConfirmed` tinyint(1) NOT NULL,  `TwoFactorEnabled` tinyint(1) NOT NULL,  `LockoutEndDateUtc` datetime DEFAULT NULL,  `LockoutEnabled` tinyint(1) NOT NULL,  `AccessFailedCount` int(11) NOT NULL,  `UserName` varchar(256) NOT NULL,  PRIMARY KEY (`Id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8

 

$ Role


 

CREATE TABLE `role` (  `Id` varchar(128) NOT NULL,  `Name` varchar(256) NOT NULL,  PRIMARY KEY (`Id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8

 

$ UserRole


 

CREATE TABLE `userrole` (  `UserId` varchar(128) NOT NULL,  `RoleId` varchar(128) NOT NULL,  PRIMARY KEY (`UserId`,`RoleId`),  KEY `IdentityRole_Users` (`RoleId`),  CONSTRAINT `AppUser_Roles` FOREIGN KEY (`UserId`) REFERENCES `user` (`Id`)    ON DELETE CASCADE ON UPDATE NO ACTION,  CONSTRAINT `IdentityRole_Users` FOREIGN KEY (`RoleId`) REFERENCES `role` (`Id`)    ON DELETE CASCADE ON UPDATE NO ACTION) ENGINE=InnoDB DEFAULT CHARSET=utf8

 

$ UserClaim


 

 

CREATE TABLE `userclaim` (  `Id` int(11) NOT NULL AUTO_INCREMENT,  `UserId` varchar(128) NOT NULL,  `ClaimType` longtext,  `ClaimValue` longtext,  PRIMARY KEY (`Id`),  UNIQUE KEY `Id` (`Id`),  KEY `UserId` (`UserId`),  CONSTRAINT `AppUser_Claims` FOREIGN KEY (`UserId`) REFERENCES `user` (`Id`)    ON DELETE CASCADE ON UPDATE NO ACTION) ENGINE=InnoDB DEFAULT CHARSET=utf8

 

$ UserLogin



 

CREATE TABLE `userlogin` (  `LoginProvider` varchar(128) NOT NULL,  `ProviderKey` varchar(128) NOT NULL,  `UserId` varchar(128) NOT NULL,  PRIMARY KEY (`LoginProvider`,`ProviderKey`,`UserId`),  KEY `AppUser_Logins` (`UserId`),  CONSTRAINT `AppUser_Logins` FOREIGN KEY (`UserId`) REFERENCES `user` (`Id`)    ON DELETE CASCADE ON UPDATE NO ACTION) ENGINE=InnoDB DEFAULT CHARSET=utf8

 


  3. 如何使用ASP.NET Identity 3.1 認證(Authenticate)

using System.Security.Claims;using System.Web;using System.Web.Mvc;using Microsoft.AspNet.Identity;using Microsoft.AspNet.Identity.Owin;public class AccountController : Controller {    [HttpPost]    [AllowAnonymous]    [ValidateAntiForgeryToken]    public ActionResult Login(string name, string password, string returnUrl) {        var userManager = HttpContext.GetOwinContext()            .GetUserManager<UserManager<AppUser>>();        var authManager = HttpContext.GetOwinContext().Authentication;        var user = userManager.Find(name, password);        if (user == null) {            // Invalid name or password        }        else {            ClaimsIdentity identity = userManager.CreateIdentity(                user, DefaultAuthenticationTypes.ApplicationCookie);            authManager.SignOut();            authManager.SignIn(identity);            return Redirect(returnUrl);        }        return View();    }}

  3.2 使用者操作

using System.Security.Principal;using System.Web;using Microsoft.AspNet.Identity;using Microsoft.AspNet.Identity.Owin;var userManager = HttpContext.Current.GetOwinContext()    .GetUserManager<UserManager<AppUser>>();// 擷取目前使用者IPrincipal principal = HttpContext.Current.User;AppUser user = userManager.FindByName(principal.Identity.Name);// 建立使用者var newUser = new AppUser { UserName = "Alice" };varr password = "changeme";userManager.Create(newUser, password);// 刪除使用者userManager.Delete(user);// 修改使用者資訊user.Email = "huangc126@126.com";user.PasswordHash = userManager.PasswordHasher.HashPassword("secret");

  3.3 角色管理

using System.Web;using Microsoft.AspNet.Identity;using Microsoft.AspNet.Identity.EntityFramework;using Microsoft.AspNet.Identity.Owin;var roleManager = HttpContext.Current.GetOwinContext()    .GetUserManager<RoleManager<IdentityRole>>();// 建立角色var newRole = new IdentityRole { Name = "Admin" };roleManager.Create(newRole);// 將角色授予使用者userManager.AddToRole(userId, role: "Admin");// 移除使用者的角色userManager.RemoveFromRole(userId, role: "Admin");// 刪除角色var role = roleManager.FindByName("Admin");roleManager.Delete(role);

  3.4 授權(Authorization) 3.4.1 基於角色的授權

using System.Web.Mv;[Authorize(Roles = "Administrators")]public class AdminController : Controller {    ...}

  3.4.2 基於聲明(Claim)的授權

using System.Security.Claims;using System.Web;using System.Web.Mvc;[ClaimsAccess(Issuer = "RemoteClaims", ClaimType = ClaimTypes.PostalCode, Value = "123456")]public ActionResult Action() {    ...}public class ClaimsAccessAttribute : AuthorizeAttribute {    public string Issuer { get; set; }public string ClaimType { get; set; }public string Value { get; set; }protected override bool AuthorizeCore(HttpContextBase context) {    return context.User.Identity.IsAuthenticated    && context.User.Identity is ClaimsIdentity&& ((ClaimnsIdentity)context.User.Identity).HasClaim(    c => c.Issuer == this.Issuer    && c.Type == this.ClaimType&& c.Value == this.Value);}}

 

  4. 小結

ASP.NET Identity非常靈活,支援各種擴充,對中小型系統來說足夠用了。雖然看上去有點麻煩,但即使是小系統,我也建議用Identity。因為自己去搞一套太麻煩,又容易出錯。我們應該把更多的精力花在業務實現上,而不是去摳底層技術細節。 大小: 14.7 KB 大小: 5.5 KB 大小: 4.9 KB 大小: 6.6 KB 大小: 5.6 KB 大小: 24.6 KB 查看圖片附件

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.