Asp.net core 身份认证框架 Microsoft Identity的使用以及如何使用Idengtity创建自带的用户模型SignInManager和UserManager的使用等等

要启动身份认证组件,首先要更改数据库上下文中继承的关系,原本我们是继承于在这里插入图片描述
Dbcontext这个类,现在我们需要继承IdentityDbContext
继承这个类,我们需要安装对应的框架,
如图:
在这里插入图片描述
这里注意,版本一定要和你.net core 框架版本一致,不然不匹配。
框架安装完成后,我们进入数据库上下文类引入框架。
在这里插入图片描述
接着,将DbContext替换为IdentityDbContext
在这里插入图片描述
其中IdentityDbContext里的泛型IdentityUser就是身份认证的数据库结构,相当于UserModel也就是用户模型,里面有自定义好的相关用户信息字段。比如ID,姓名,性别什么的。这些定义都是由.net core 自动完成的,也会映射到数据库中。有了数据库结构后,IdentityDbContext会自动为我们的系统添加与用户表相对应的映射关系,如果数据库的用户表,UserTable还不存在,IdentityDbContext可以帮我们更新数据库,自动为我们添加用户表,这样通过数据库上下文对象,我们系统就可以自动获取到用户的信息了。而我们不需要为实现用户模块写一丁点代码。

对于IdentityUser如果默认结构不能满足你的需求,你也可以通过继承IdentityUser去修改用户模型。
补充点:记得初始化构造函数

 public AppDBcontext(DbContextOptions<AppDBcontext> options) : base(options)
        {
        }

好了,接着
在创建数据库之前,我们需要给框架注册服务认证的依赖。
我们找到Startup.cs文件
在ConfigureServices这个函数中添加函数依赖,代码如下:

  ///注册身份认证的服务依赖  
            ///泛型俩个参数分别是用户数据模型和角色模型
            ///AddEntityFrameworkStores 通过这个函数连接数据库上下文对象   泛型为对应的上下文对象。
            services.AddIdentity<IdentityUser, IdentityRole>().AddEntityFrameworkStores<AppDbContext>();

框架注入成功后,我们来进行数据更新。
这里使用.net 的命令进行数据迁移,不会数据迁移的请看这篇文章
在项目根目录下 进行CMD
输入一下命令 进行数据迁移
在这里插入图片描述
执行完成后我们可以在项目中看到对应的项目迁移代码。
在这里插入图片描述
我们可以在代码中的UP函数中看到,代码自动编写了大概创建了八张表。可能很多人有疑问了,我明明没有添加这些表,为什么系统给我加了这么多乱七八糟的表呢,
我们打开数据库上下文,其实就是因为你继承了IdentityDbContext所以也就继承了IdentityDbContext自带的数据模型,以及数据模型所对应的数据库表,接下来让我回到命令行,执行更新数据库。
在这里插入图片描述
输入红线代码进行数据库更新。
执行完成后我们可以去数据库看到更新的表
在这里插入图片描述
这些表就是我们用户模块的新表。现在项目的用户数据就创建完成了。

接着我们试着用这写数据库,做一个注册功能。

首先创建一个接收注册消息的Dto

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.ComponentModel.DataAnnotations;
namespace Fakexiecheng.API.Dtos
{
    public class RegisterDto
    {
        [Required]//Required注释  为必填字段
        public string Email { get; set; }
        [Required]
        public string Password { get; set; }
        [Required]
        [Compare(nameof(Password),ErrorMessage ="输入的密码不一致")]
        public string CofirmPassword { get; set; }
    }
}

接着我们在对应的Api里写好对应的注册函数

   private readonly UserManager<IdentityUser> _userManager;//可以通过这个工具对密码进行加密  泛型为定义的用户模型
 /// <summary>
        /// 用户注册
        /// </summary>
        /// <param name="registerDto">注册信息</param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("register")]
        public async Task<IActionResult> Register([FromBody] RegisterDto registerDto)
        {
            //1 使用用户名创建用户对象
            var user = new IdentityUser()
            {
                UserName = registerDto.Email,
                Email = registerDto.Email
            };
            //2 hash密码,保存用户
            var result = await _userManager.CreateAsync(user, registerDto.Password);//hash密码并连同用户模型对象 一起保存打数据库中
            //如果成功表示  用户创建成功并且保存起来了

            //不成功
            if (!result.Succeeded) {
                //返回400
                return BadRequest();
            }
            //3 return
            //成功  200
            return Ok();
        
        }

其中hash密码的时候,我们用的Identity自带的工具 UserManager。代码中都有注释 自己看吧,
接着我们来试着用Postman进行请求一下。
在这里插入图片描述
可以看到没什么问题,而且UserManager可以帮你自动把用户名是否相同的验证都做了,就是CreateAsync用它哈希加密后 貌似不能解密。可能我没找到方法吧,而且UserManager对密码做的有限制,看我上面图密码搞那么复杂 你应该就懂了,太简单,是无法注册的。。。内部是如何验证的我也不知道,,,这个还等着网友们去探秘。可以下载微软自己提供的反编译工具,叫什么来着 ,忘记了,自己可以看看CreateAsync这个方法的内部结构,相信你可以找到答案,,,

接着把数据库接入登录系统中

首先用Identity框架下的SignInManager来处理用户登录验证,同时使用UserManager获取用户信息,并且提取用户权限,并转换为Claim使用JWT输出。
首先我们在控制器中注入服务依赖。
在这里插入图片描述
添加划线的代码,.net core 服务注入都是通过构造函数实现的,这个我想大家都知道吧。

接下来我们使用SignInManager来进行用户验证,
登录方法中加入一下代码:

        [AllowAnonymous]//允许所有人访问
        [HttpPost("login")]
        public async  Task<IActionResult> login([FromBody] LoginDto loginDto) 
        {
            //1.进行信息认证
            var loginResult = await _signInManager.PasswordSignInAsync(loginDto.Email,loginDto.password
                , false  //指示在关闭浏览器后登录 Cookie 是否应该保留的标志。
                , false//多次登录失败后 是否锁定账号
                );
            //判断是否验证成功
            if (!loginResult.Succeeded) 
            {
                // 400
                return BadRequest();
            }
            //获取用户信息
            var user = await _userManager.FindByNameAsync(loginDto.Email);

           

            //2.创建JWT  Token
            //header   singningAlgorithm储存编码算法
            var singningAlgorithm = SecurityAlgorithms.HmacSha256;
            //payload   需要用到的数据
            var claims = new List<Claim> { 
           // sub ==jwt的ID    
           //等同于  Sub:fake_user_id
           new Claim(JwtRegisteredClaimNames.Sub,user.Id),
          // new Claim(ClaimTypes.Role,"Admin")//角色信息

           };
            //获取用户角色
            var roleNames = await _userManager.GetRolesAsync(user);
            //遍历角色  一个用户可能有多个角色
            foreach (var roleName in roleNames)
            {
                var roleClaim = new Claim(ClaimTypes.Role, roleName);
                claims.Add(roleClaim);
            }

            //signature   数字签名   需要用到私钥
            //私钥一般放在配置文件中  私钥是自定义的  想写什么写什么

            //使用utf进行编码
            var secretByte = Encoding.UTF8.GetBytes(_configuration["Authentication:SecretKey"]);
            //使用非对称算法 对私钥加密
            var signingkey = new SymmetricSecurityKey(secretByte);
            //通过256验证非对称加密的私钥
            var signingCredentials = new SigningCredentials(signingkey, singningAlgorithm);

            //创建token
            var token = new JwtSecurityToken(
                issuer:_configuration  ["Authentication:Issuer"],//谁发布的TOken
                audience:_configuration["Authentication:Audience"],//token发布给谁
           claims,//payload数据
           notBefore:DateTime.UtcNow,//发布时间
           expires:DateTime.UtcNow.AddDays(1),//有效时间
           signingCredentials//数字签名
                );

            //以字符串形式 输出Token
            var tokenStr = new JwtSecurityTokenHandler().WriteToken(token);

            //3.返回jwt字符串

            return Ok(tokenStr);
        }

接下来我们来postman测试一下。
首先注册用户
在这里插入图片描述

然后用注册的用户登录系统
在这里插入图片描述

然后通过返回的JWT来进行一下数据访问
在这里插入图片描述

我们发现404
其实这里有个天大的坑。
原因:在我们使用Identity框架的多角色验证时,验证中间件使用的并不是JWT验证,和默认验证并不匹配。
解决办法
显示指定使用JWT 的验证方式。
再要访问的所有需要权限认证方法头部加上一下代码:

   [Authorize(AuthenticationSchemes = "Bearer")]

接着测试一下
在这里插入图片描述
这下可以看到 返回403权限不足而不是404了 这是因为我规定了只有管理员才可以创建东西。所以这是正确的。

接着我们来定制一下用户模型

场景:当我们用的默认用户模型字段不够的时候,我么可以通过继承来定制一个用户模型。比如下图中
在这里插入图片描述
自带的这些字段不够用呢,就可以通过定制来扩展、

我们来看看数据库结构


表示用户模型
在这里插入图片描述
用于保存直接与用户权限绑定的声明,比如只允许张三可以删除数据。
在这里插入图片描述
用于第三方登录工具,比如记录微信登录的信息。
在这里插入图片描述
用于保存用户角色信息,一个用户可能有多个角色
在这里插入图片描述
记录用户登录的session,比如登录时长,拉黑用户都在这个表记录。

接着我们从代码的角度重载一下这几张表,首先新建一个ApplicationUser类继承IdentityUser,然后添加一下代码,这里切记 代码一定要一致,因为名称要和父类名称一致,不然会失败。

using Microsoft.AspNetCore.Identity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Fakexiecheng.API.Models
{
    public class ApplicationUser:IdentityUser
    {
        public string Address { get; set; }
        //shoppingCart
        //orders
        public virtual ICollection<IdentityUserRole<string>> UserRoles { get; set; }

        public virtual ICollection<IdentityUserClaim<string>> Claims { get; set; }

        public virtual ICollection<IdentityUserLogin<string>> Logins { get; set; }

        public virtual ICollection<IdentityUserToken<string>> Tokens { get; set; }


    }
}

然后我们把用到的IdentityUser全部替换为ApplicationUser

接着我们可以注入一下种子数据进行数据的更新、
接着我进入上下文关系文档,在OnModelCreating函数中进行种子数据的初始化。
添加如下代码:

 //初始化用户与角色的种子数据
            //1.更新用户与角色的外键
            //HasMany 表示一对多的关系  这个关系可以被映射为roles 每一个role都有一个外键关系 WithOne  而这个外键关系使用的是UserID  这个ID是必须的  所以加上IsRequired()
            modelBuilder.Entity<ApplicationUser>(u => u.HasMany(x => x.UserRoles).WithOne().HasForeignKey(ur => ur.UserId).IsRequired());

            //2.添加管理员角色

            //给角色添加主键
            var adminRoleId = Guid.NewGuid().ToString();
            modelBuilder.Entity<IdentityRole>().HasData(
                new IdentityRole()
                {
                    Id = adminRoleId,
                    Name = "Admin",
                    NormalizedName = "Admin".ToUpper()//大写
                }
                ); 
            //3.添加用户
            var adminUserID = Guid.NewGuid().ToString();
            ApplicationUser adminUser = new ApplicationUser
            {
                Id = adminUserID,
                UserName = "13011@qq.com",
                NormalizedUserName = "13011@qq.com".ToUpper(),
                Email= "13011@qq.com",
                NormalizedEmail= "13011@qq.com".ToUpper(),
                TwoFactorEnabled=false,
                EmailConfirmed=true,
                PhoneNumber="1234567891",
                PhoneNumberConfirmed=false


            };
            //hash密码
            var ph = new PasswordHasher<ApplicationUser>();
            adminUser.PasswordHash = ph.HashPassword(adminUser, "Fake123$");
            modelBuilder.Entity<ApplicationUser>().HasData(adminUser);

            //4.给用户加入管理员角色
            modelBuilder.Entity<IdentityUserRole<string>>().HasData(new  IdentityUserRole<string>(){ 

            RoleId=adminRoleId,
            UserId=adminUserID
            
            });

然后我们进行数据迁移。
在这里插入图片描述
然后我们去数据迁移文件里解读一下代码
在这里插入图片描述
我们可以看到 ,添加了对应的数据和字段。
接着我们去用一下我们的种子数据。
在这里插入图片描述

在这里插入图片描述

我们发现可以成功登录并且创建数据。好了 就更新这么多了。。。。写的有点乱,希望不要介意。

  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ASP.NET Core IdentityASP.NET Core 框架提供的一种身份认证和授权框架,它可以用于管理用户、角色和权限。 下面是使用 ASP.NET Core Identity 的步骤: 1. 首先,要在 ASP.NET Core 项目中安装 Microsoft.AspNetCore.Identity 包。 2. 接着,在 Startup.cs 文件中配置 Identity 服务。可以使用 AddIdentity() 方法来配置 Identity,默认情况下会将 Identity 存储在内存中,但这并不适合生产环境。因此,我们需要配置 Identity 存储提供程序。例如,可以使用 Entity Framework Core 来存储 Identity 数据。如果要使用 Entity Framework Core,可以使用 AddEntityFrameworkStores() 方法将 Identity 存储在数据库中。 ```csharp public void ConfigureServices(IServiceCollection services) { // 添加 Identity 服务 services.AddIdentity<IdentityUser, IdentityRole>() .AddEntityFrameworkStores<ApplicationDbContext>() .AddDefaultTokenProviders(); // 添加其他服务 services.AddControllersWithViews(); } ``` 3. 然后,需要创建一个 ApplicationDbContext 类来表示 Identity 数据库上下文。这个类需要继承 IdentityDbContext 类,并指定 IdentityUserIdentityRole 类型。 ```csharp public class ApplicationDbContext : IdentityDbContext<IdentityUser, IdentityRole, string> { public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { } } ``` 4. 在 ConfigureServices() 方法中,还需要配置身份认证和授权选项。例如,可以配置密码复杂性要求、登录尝试锁定、cookie 配置等等。 ```csharp public void ConfigureServices(IServiceCollection services) { // 添加 Identity 服务 services.AddIdentity<IdentityUser, IdentityRole>() .AddEntityFrameworkStores<ApplicationDbContext>() .AddDefaultTokenProviders(); // 配置身份认证和授权选项 services.Configure<IdentityOptions>(options => { // 密码复杂性要求 options.Password.RequireDigit = true; options.Password.RequireLowercase = true; options.Password.RequireNonAlphanumeric = true; options.Password.RequireUppercase = true; options.Password.RequiredLength = 8; // 登录尝试锁定 options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5); options.Lockout.MaxFailedAccessAttempts = 5; // cookie 配置 options.Cookies.ApplicationCookie.ExpireTimeSpan = TimeSpan.FromDays(7); options.Cookies.ApplicationCookie.LoginPath = "/Account/Login"; options.Cookies.ApplicationCookie.LogoutPath = "/Account/Logout"; }); // 添加其他服务 services.AddControllersWithViews(); } ``` 5. 最后,在应用程序中使用 Identity API 来管理用户、角色和权限。例如,可以在控制器中使用 UserManager 和 RoleManager 类来创建、删除和修改用户和角色。 ```csharp public class AccountController : Controller { private readonly UserManager<IdentityUser> _userManager; private readonly SignInManager<IdentityUser> _signInManager; private readonly RoleManager<IdentityRole> _roleManager; public AccountController(UserManager<IdentityUser> userManager, SignInManager<IdentityUser> signInManager, RoleManager<IdentityRole> roleManager) { _userManager = userManager; _signInManager = signInManager; _roleManager = roleManager; } public IActionResult Register() { return View(); } [HttpPost] public async Task<IActionResult> Register(RegisterViewModel model) { if (ModelState.IsValid) { var user = new IdentityUser { UserName = model.Email, Email = model.Email }; var result = await _userManager.CreateAsync(user, model.Password); if (result.Succeeded) { await _signInManager.SignInAsync(user, isPersistent: false); return RedirectToAction("Index", "Home"); } foreach (var error in result.Errors) { ModelState.AddModelError(string.Empty, error.Description); } } return View(model); } public async Task<IActionResult> CreateRole() { var result = await _roleManager.CreateAsync(new IdentityRole("Admin")); if (result.Succeeded) { return Ok(); } return BadRequest(); } } ``` 以上就是使用 ASP.NET Core Identity 来管理用户和角色的步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值