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.EntityFramework public 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。因为自己去搞一套太麻烦,又容易出错。我们应该把更多的精力花在业务实现上,而不是去抠底层技术细节。
相关推荐
本系列教程详细、完整、深入地介绍了微软的ASP.NET Identity技术,描述了如何运用ASP.NET Identity实现应用程序的用户管理,以及实现应用程序的认证与授权等相关技术,译者希望本系列教程能成为掌握ASP.NET Identity...
ASP.NET Identity自定义用户和权限,Mysql EntityFramework实现
asp.net identity 文档
ASP.NET 身份示例ASP.NET Identity 示例,包括 oAuth、两个因素、迁移等这些演示与这里的课程一起使用 (尽管您不必观看它就可以从中获得一些东西) 在每个项目中,我都保留了相同的命名空间,并从“BasicTemplate -...
ASP.NET-Identity-SQLite-EntityFramework 基于SQLite数据库和Entity Framework OR/M实现ASP.NET Identity成员资格 基础信息 这是 ASP.NET Identity 成员身份与实体框架和 SQLite 数据库的实现。 出于我的目的,...
Aspnet-ASP.NET-WebForm-Identity-Demo.zip,asp.net-webform-identity-demoasp.net-webform-identity-demo,asp.net是一个开源的web框架,用于使用.net构建现代web应用和服务。asp.net创建基于html5、css和javascript...
题记:在ASP.NET 5中虽然继续可以沿用ASP.NET Identity来做验证授权,不过也可以很容易集成支持标准协议的第三方服务,比如Azure Active Directory。 其实,在ASP.NET 5中集成AzureAD,利用其进行验证和授权,是非常...
新增了对One ASP.NET项目模板、ASP.NET Identity、Bootstrap和特性路由的介绍 探讨了一些重要主题,如Ajax、NuGet、依赖注入、单元测试和MVC扩展 提供了分步骤指导、真实案例以及众多代码示例,帮助读者从入门阶段...
ASP.NET Core MVC从入门到精通系列文章。 本系列文章共计20篇,主要包括ASP.NET Core MVC项目创建,启动运行,以及命名约定,创建控制器,视图,模型,接收参数,传递数据ViewData,ViewBag,路由,页面布局,...
ASP.NET MVC5高级编程(第5版.NET开发经典名著...新增了对One ASP.NET项目模板、ASP.NET Identity、Bootstrap和特性路由的介绍 探讨了一些重要主题,如Ajax、NuGet、依赖注入、单元测试和MVC扩展 提供了分步骤指导。
Aspnet-ASP.NET-Identity.zip,使用user/role management.asp.net-identity进行asp.net身份验证和授权,asp.net是一个开源的web框架,用于使用.net构建现代web应用和服务。asp.net创建基于html5、css和javascript的...
使用 ASP.NET Identity RavenDB 端口非常简单。 您可以通过安装库。 目前,面向 ASP.NET Identity 2.0.0 版本的AspNet.Identity.RavenDB包是预发布版。 因此,请确保在通过 NuGet 获取时使用-pre开关: Install-...
ASP.NET+MVC+创建用户权限管理范例程序源码
如果您使用的是Neo4jClient 3+,则需要2.x当前版本特征使用Neo4j作为后备存储的嵌入式替代ASP.NET Identity。 包含由MVC 5项目模板中的EntityFramework提供程序使用的同一IdentityUser类在应用程序的用户模型上支持...
包括的功能有: 使用ASP.NET Identity 2系统的身份验证和授权以及令牌身份验证杜兰达尔观点中的授权客户端(淘汰验证)和服务器(数据属性)的模型验证客户端和服务器的UnitOfWork和存储库模式在客户端中使用Breeze...
Asp.Net Core Identity 是Asp.Net Core 的重要组成部分,他为 Asp.Net Core 甚至其他 .Net Core 应用程序提供了一个简单易用且易于扩展的基础用户管理系统框架。它包含了基本的用户、角色、第三方登录、Claim等功能...
AspNet 身份演示使用 ASP.NET Identity 和自定义存储的 ASP.NET MVC 站点(正在进行演示)。推荐链接:
ASPNETIdentity ASP.NET Identity自定义示例应用程序
主要介绍了ASP.NET Identity 的“多重”身份验证代码,以及实现的原理讲解,需要的朋友参考一下。
ASP.NET MVC with Entity Framework and CSS by Lee Naylor 2016 | ISBN: 1484221362 | English | 608 pages | True PDF | 30 MB This book will teach readers how to build and deploy a fully working example ...