.Net 验证授权(一)Identity入门

ASP .NET Identity

ASP .NET Identity是微软所贡献的开源项目,用来提供ASP.NET的验证、授权等等机制。在ASP .NET Identity里除了提供最基础的:用户注册、密码重设、密码验证等等基础功能之外,也提供了进阶的:Cookie登入、Facebook登入、Google登入等等进阶功能

ASP .NET Identity具有以下优势:

  1. 自定义用户信息
  2. 可以轻松地整合到 ASP.NET 各种框架以及程序上
  3. owin集成,Authentication(验证)基于owin中间件,可以再任何owin宿主上执行,不依赖system.web
  4. 第三方账号接入
  5. Nuget
  6. 兼容多种数据库(默认是code first 访问sqlserver)
  7. 自定义角色

ASP .NET Identity主要包括核心功能模块、EntityFramework模块以及OWIN模块。具体如下

  1. Microsoft.AspNet.Identity.Core   核心库,包含Identity的主要功能。
  2. Microsoft.AspNet.Identity.EntityFramework  主要包括ASP .NET Identity 的EF 部分的实现。
  3. Microsoft.AspNet.Identity.OWIN  ASP .NET Identity对OWIN 的支持。

使用默认数据库的Identity(sqlserver)

  1. 新建一个MVC项目

  2. 选择个人用户账户验证

  3. 修改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>
  1. 运行

  2. 注册

可以看见注册成功后对应的数据:

从下面代码可以看见没在注册的时候是通过调用UserManager的CreateAsync方法创建了一个新账号,账号新建成功后通过SignInAsync 完成登录操作,具体的实现逻辑在后续会讲到。

综上,就可以尝试使用sqlserver存储用户信息的Identity了

使用mysql 的Identity

因为在实际项目中大部分会选择使用mysql 数据库,所以重点讲一下怎么基于MySql 使用Identity

  1. 同sqlserver一样,先新建一个个人用户账户验证的MVC项目

  2. 安装 MySql.Data、MySql.Data.Entity

  3. 修改web.config

  • 连接地址
<connectionStrings>
    <add name="DefaultConnection" connectionString="Server=localhost;User ID=root;Password=root;Database=IdentityUser" providerName="MySql.Data.MySqlClient" />
  </connectionStrings>
  <!--指定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>
  1. 运行程序——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);
        }
  1. 重新运行

代码参见(Identity):
https://github.com/dzjx/UserOAuth.git

到这里,基于Mysql 的Identity 新建就完成了,参考地址:
https://docs.microsoft.com/en-us/aspnet/identity/overview/getting-started/introduction-to-aspnet-identity

posted @ 2019-01-29 13:38  Pen丶  阅读(1056)  评论(0编辑  收藏  举报