.Net中的标识框架Identity

news/2024/12/22 22:50:30/

中间件:

1、Authentication对访问者的用户身份进行验证,“用户是否登录成功”。

2、Authorization验证访问者的用户身份是否有对资源访问的访问权限,“用户是否有权限访问这个地址”。

简单描述

1、标识(Identity)框架:采用基于角色的访问控制(Role-Based Access Control,简称RBAC)策略,内置了对用户、角色等表的管理以及相关的接口,支持外部登录、2FA等。它允许我们创建、读取、更新和删除账户。支持账号验证、身份验证、授权、恢复密码和SMS双因子身份验证。它还支持微软、Facebook和Google等第三方登录提供商。它提供了一个丰富的API,并且这些API还可以进行大量的扩展。我们将在本书的后面实现这些功能。

2、标识框架使用EF Core对数据库进行操作,因此标识框架支持几乎所有数据库。

使用场景

涉及注册、登录和修改密码等功能,登录系统后,有些功能会提示没有权限,甚至有些位置我们无法访问,这些都是系统权限和认证的体现。

配置Identity

安装Nuget

Microsoft.AspNetCore.Identity.EntityFrameworkCore

创建Identity上下文对象

public class MyContext:IdentityDbContext<User,Role,long>

{

    public MyContext(DbContextOptions<MyContext> options)

    : base(options)

    {

    }

 

    protected override void OnModelCreating(ModelBuilder builder)

    {

        base.OnModelCreating(builder);

        builder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);

    }

}

如果需要对User(用户)和Role(角色)进行扩展可进行继承

public class Role:IdentityRole<long> //泛型类型longId类型

{

}

 

public class User:IdentityUser<long>

{

    public DateTime CreationTime { get; set; } //创建时间

    public string? NickName { get; set; }   //昵称

}

向依赖注入容器中注册标识框架相关的服务

builder.Services.AddDataProtection();

//注意不是AddIdentity

builder.Services.AddIdentityCore<User>(options => {   

    options.Password.RequireDigit = false;//设置密码是否必须是数字

    options.Password.RequireLowercase = false;//是否必须小写

    options.Password.RequireNonAlphanumeric = false;//是否必须非数字

    options.Password.RequireUppercase = false;//是否必须大写

    options.Password.RequiredLength = 6;//长度为6

    options.Tokens.PasswordResetTokenProvider = TokenOptions.DefaultProvider;//设置密码令牌

    options.Tokens.EmailConfirmationTokenProvider = TokenOptions.DefaultEmailProvider;//设置邮箱令牌

});

var idBuilder = new IdentityBuilder(typeof(User), typeof(Role), builder.Services);

idBuilder.AddEntityFrameworkStores<MyContext>()

    .AddDefaultTokenProviders().AddRoleManager<RoleManager<Role>>()

    .AddUserManager<UserManager<User>>();

执行Add-Migration、Update-Database等命令执行EF Core的数据库迁移。

Add-Migration Init

Update-Database

创建角色与用户信息

[Route("api/[controller]/[action]")]

[ApiController]

public class IdentityController : ControllerBase

{

//通过RoleManager、UserManager等来进行数据操作。比如创建角色、创建用户。

    private readonly RoleManager<Role> roleManager;

    private readonly UserManager<User> userManager;

    public IdentityController(RoleManager<Role> roleManager, UserManager<User> userManager)

    {

        this.roleManager = roleManager;

        this.userManager = userManager;

    }

 

    [HttpPost]

    public async Task<ActionResult> CreateUserRole()

    {

        bool roleExists = await roleManager.RoleExistsAsync("admin");//判断是否存在这个角色

        if (!roleExists)

        {

            Role role = new Role { Name = "Admin" };

            var r = await roleManager.CreateAsync(role);

            //创建失败返回错误信息

            if (!r.Succeeded)

            {

                return BadRequest(r.Errors);

            }

        }

 

        User user = await this.userManager.FindByNameAsync("rodio");//获取某用户信息

        if (user == null)

        {

            user = new User {

           UserName = "rodio",

           Email = "abc123888@gmail.com",

               EmailConfirmed = true

            };

            var r = await userManager.CreateAsync(user, "123456");

            //创建用户信息失败返回错误信息

            if (!r.Succeeded)

            {

                return BadRequest(r.Errors);

            }

            //将角色和用户进行关联

            r = await userManager.AddToRoleAsync(user, "admin");

            if (!r.Succeeded)

            {

                return BadRequest(r.Errors);

            }

        }

        return Ok();

    }

}

 

用户登录

//用户登录类

public record LoginRequest(string UserName,string Password);

//控制器添加一个Action

[HttpPost]

public async Task<ActionResult> Login(LoginRequest req)

{

    string userName = req.UserName;

    string password = req.Password;

    var user = await userManager.FindByNameAsync(userName);//获取某用户信息

    if (user == null)//判断是否存在

    {

        return NotFound($"用户名不存在{userName}");

    }

    //判断该用户是否被锁(封号)

    if (await userManager.IsLockedOutAsync(user))

    {

        return BadRequest("LockedOut");

    }

    //判断用户的账号密码是否成功

    var success = await userManager.CheckPasswordAsync(user, password);

    if (success)

    {

        return Ok("Success");

    }

    else

    {

        //将用户的登录失败进行计数。如果超过配置次数将会被锁(封号)

        var r = await userManager.AccessFailedAsync(user);

        if (!r.Succeeded)

        {

            return BadRequest("AccessFailed failed");

        }

        return BadRequest("Failed");

    }

}

 


http://www.ppmy.cn/news/48018.html

相关文章

轻松掌握K8S使用kubectl操作配置文件挂载ConfigMap和密钥Secret知识点05

1、挂载应用配置文件配置集ConfigMap 当有许多应用如redis、mysql&#xff0c;希望将它的配置文件挂载出去&#xff0c;以便随时修改&#xff0c;可以用ConfigMap配置集 具体用法查看使用命令行操作里的 3、ConfigMap配置集实战 2、挂载应用配置文件的敏感信息Secret Secre…

Linux 系统调用深思:从原理到实战

Linux 系统调用揭秘&#xff1a;从原理到实战&#xff08;Demystifying Linux System Calls: From Principles to Practice&#xff09; 引言&#xff08;Introduction&#xff09;系统调用的概念&#xff08;Concept of System Calls&#xff09;Linux操作系统与系统调用的关系…

使用element-plus组件,修改date-picker默认样式

使用深度选择器来修改子组件的样式&#xff0c;今天遇到一个需求&#xff0c;在el-drawer中嵌入的el-date-picker&#xff0c;再一次总结一下深度选择器的用法&#xff0c;需求如下&#xff1a; template内容&#xff1a; <el-drawer size"70%" v-model"dr…

Golang微服务一把嗦 用户微服务集成主流最新go技术栈

声明&#xff1a;此文章为博主个人学习记录&#xff0c;仅供学习和交流&#xff0c;如有侵权请联系博主。 前言 前段时间&#xff0c;因为本地k8s环境一直出问题&#xff0c;线上云环境也用不起&#xff0c;&#xff08;后面搞定了再慢慢学习&#xff09;所以就暂时搁置了k8s学…

【C/C++】GDB 快速定位虚函数表并获取详情信息

文章目录 在GDB中&#xff0c;可以使用以下命令来查看虚函数表&#xff1a; 首先&#xff0c;使用GDB调试程序&#xff0c;并在程序运行到需要查看虚函数表的地方停下来。 然后&#xff0c;使用命令“p /x (long)object”来查看对象的地址。这个命令会输出对象的地址&#xff…

DHCP原理与配置

目录 一、DHCP工作原理 1&#xff09;了解DHCP服务 使用DHCP的好处 DHCP的分配方式 2&#xff09;DHCP的租约过程 分为四个步骤 二、DHCP服务器的配置 1&#xff09;检查并且安装dhcp有关软件包 2&#xff09;查看系统的配置文件&#xff0c;并且利用好官方给的参考案…

一起学 Java(三) 集合框架、数据结构、泛型

一、Java 集合框架 集合框架是一个用来代表和操纵集合的统一架构。所有的集合框架都包含如下内容&#xff1a; 接口&#xff1a;是代表集合的抽象数据类型。接口允许集合独立操纵其代表的细节。在面向对象的语言&#xff0c;接口通常形成一个层次。实现&#xff08;类&#x…

注册功能编写--购物车拓展

教程给出的模板在登录板块的功能不够齐全&#xff0c;正常情况下我们还应该有一个注册功能。所以这次我来写一个注册功能。 1、给登录的jsp页面添加相关超链接按钮&#xff0c;顺便把页面内容通过css改一改。然后再写一个负责注册的jsp 2、在userdao中再写一个方法负责给user表…