ASP .NET Identity
ASP .NET Identity是微软所贡献的开源项目,用来提供ASP.NET的验证、授权等等机制。在ASP .NET Identity里除了提供最基础的:用户注册、密码重设、密码验证等等基础功能之外,也提供了进阶的:Cookie登入、Facebook登入、Google登入等等进阶功能
ASP .NET Identity具有以下优势:
- 自定义用户信息
- 可以轻松地整合到 ASP.NET 各种框架以及程序上
- owin集成,Authentication(验证)基于owin中间件,可以再任何owin宿主上执行,不依赖system.web
- 第三方账号接入
- Nuget
- 兼容多种数据库(默认是code first 访问sqlserver)
- 自定义角色
ASP .NET Identity主要包括核心功能模块、EntityFramework模块以及OWIN模块。具体如下
- Microsoft.AspNet.Identity.Core 核心库,包含Identity的主要功能。
- Microsoft.AspNet.Identity.EntityFramework 主要包括ASP .NET Identity 的EF 部分的实现。
- Microsoft.AspNet.Identity.OWIN ASP .NET Identity对OWIN 的支持。
使用默认数据库的Identity(sqlserver)
新建一个MVC项目
选择个人用户账户验证
- 修改web.config 指定数据库
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\demo.mdf;Initial Catalog=demo;Integrated Security=True" providerName="System.Data.SqlClient" />
</connectionStrings>
运行
注册
可以看见注册成功后对应的数据:
从下面代码可以看见没在注册的时候是通过调用UserManager的CreateAsync方法创建了一个新账号,账号新建成功后通过SignInAsync 完成登录操作,具体的实现逻辑在后续会讲到。
综上,就可以尝试使用sqlserver存储用户信息的Identity了
使用mysql 的Identity
因为在实际项目中大部分会选择使用mysql 数据库,所以重点讲一下怎么基于MySql 使用Identity
同sqlserver一样,先新建一个个人用户账户验证的MVC项目
安装 MySql.Data、MySql.Data.Entity
修改web.config
- 连接地址
<connectionStrings>
<add name="DefaultConnection" connectionString="Server=localhost;User ID=root;Password=root;Database=IdentityUser" providerName="MySql.Data.MySqlClient" />
</connectionStrings>
- codeConfigurationType,具体原因参见 CodeFirst(一)一个简单的Mysql例子
<!--指定mydql 的 codeConfigurationType-->
<entityFramework codeConfigurationType="MySql.Data.Entity.MySqlEFConfiguration, MySql.Data.Entity.EF6">
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="mssqllocaldb" />
</parameters>
</defaultConnectionFactory>
<providers>
<provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
<provider invariantName="MySql.Data.MySqlClient" type="MySql.Data.MySqlClient.MySqlProviderServices, MySql.Data.Entity.EF6, Version=6.10.8.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d">
</provider>
</providers>
</entityFramework>
- 运行程序——Specified key was too long; max key length is 767 bytes
导致这个问题产生的原因是在使用的数据库上下文中,添加了两个长度为varchar(256) 的索引,而默认情况下,Mysql InnoDB 引擎单一字段索引的长度最大为 767 字节,当使用UTF-8 编码的情况下占的字节数(256*3=768) 刚好超过
IdentityDbContext 的源码
所以我们只能重载IdentityDbContext的OnModelCreating,将用户的UserName 和 角色的Name 的长度修改为255
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
if (modelBuilder == null)
{
throw new ArgumentNullException("modelBuilder");
}
var user = modelBuilder.Entity<ApplicationUser>()
.ToTable("AspNetUsers");
user.HasMany(u => u.Roles).WithRequired().HasForeignKey(ur => ur.UserId);
user.HasMany(u => u.Claims).WithRequired().HasForeignKey(uc => uc.UserId);
user.HasMany(u => u.Logins).WithRequired().HasForeignKey(ul => ul.UserId);
user.Property(u => u.UserName)
.IsRequired()
.HasMaxLength(255) // 修改长度 避免Mysql 索引超出范围
.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("UserNameIndex") { IsUnique = true }));
user.Property(u => u.Email).HasMaxLength(256);
modelBuilder.Entity<IdentityUserRole>()
.HasKey(r => new { r.UserId, r.RoleId })
.ToTable("AspNetUserRoles");
modelBuilder.Entity<IdentityUserLogin>()
.HasKey(l => new { l.LoginProvider, l.ProviderKey, l.UserId })
.ToTable("AspNetUserLogins");
modelBuilder.Entity<IdentityUserClaim>()
.ToTable("AspNetUserClaims");
var role = modelBuilder.Entity<IdentityRole>()
.ToTable("AspNetRoles");
role.Property(r => r.Name)
.IsRequired()
.HasMaxLength(255)// 修改长度 避免Mysql 索引超出范围
.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("RoleNameIndex") { IsUnique = true }));
role.HasMany(r => r.Users).WithRequired().HasForeignKey(ur => ur.RoleId);
}
- 重新运行
代码参见(Identity):
https://github.com/dzjx/UserOAuth.git
到这里,基于Mysql 的Identity 新建就完成了,参考地址:
https://docs.microsoft.com/en-us/aspnet/identity/overview/getting-started/introduction-to-aspnet-identity