ASP.NET Core标识框架Identity

目录

Authentication与Authorization

标识框架(Identity)

Identity框架的使用

初始化

自定义属性

案例一:添加用户、角色

案例二:检查登录用户信息

案例三:实现密码的重置

步骤


Authentication与Authorization

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

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

标识框架(Identity)

标识(Identity)框架:采用基于角色的访问控制(Role-Based Access Control,简称RBAC)策略,内置了对用户、角色等表的管理以及相关的接口,支持外部登录、2FA等。

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

Identity框架的使用

  1. IdentityUser<TKey>、IdentityRole<TKey>,TKey代表主键的类型。我们一般编写继承自IdentityUser<TKey>、IdentityRole<TKey>等的自定义类,可以增加自定义属性。
  2. NuGet:Microsoft.AspNetCore.Identity.EntityFrameworkCore。
  3. 创建继承自IdentityDbContext的类
  4. 可以通过IdDbContext类来操作数据库,不过框架中提供了RoleManager、UserManager等类来简化对数据库的操作。
  5. 部分方法的返回值为Task<IdentityResult>类型

初始化

初始化完执行数据库迁移操作

public class MyUser:IdentityUser<long>
{
}
public class MyRole:IdentityRole<long>
{
}
public class MyDbContext:IdentityDbContext<MyUser,MyRole,long>
{
    public MyDbContext(DbContextOptions<MyDbContext> options) : base(options)
    {
    }
}

Program.cs
//添加数据库上下文
builder.Services.AddDbContext<MyDbContext>(opt => {
    string connStr = Environment.GetEnvironmentVariable("ConnStr");
    opt.UseSqlServer(connStr);
});
//添加数据保护服务
builder.Services.AddDataProtection();
//添加身份认证服务
builder.Services.AddIdentityCore<MyUser>(options => {
    //设置密码规则,不需要数字,小写字母,大写字母,特殊字符,长度为6
    options.Password.RequireDigit = false;
    options.Password.RequireLowercase = false;
    options.Password.RequireUppercase = false;
    options.Password.RequireNonAlphanumeric = false;
    options.Password.RequiredLength = 6;
    //设置密码重置令牌提供程序为默认的电子邮件提供程序
    options.Tokens.PasswordResetTokenProvider = TokenOptions.DefaultEmailProvider;
    //设置电子邮件确认令牌提供程序为默认的电子邮件提供程序
    options.Tokens.EmailConfirmationTokenProvider = TokenOptions.DefaultEmailProvider;
});
//添加实体框架、默认令牌提供程序、角色管理器、用户管理器
var idBuilder = new IdentityBuilder(typeof(MyUser), typeof(MyRole), builder.Services);
idBuilder.AddEntityFrameworkStores<MyDbContext>().AddDefaultTokenProviders()
    .AddRoleManager<RoleManager<MyRole>>().AddUserManager<UserManager<MyUser>>();

自定义属性

public class MyUser:IdentityUser<long>
{
    public string? WeChatAccout { get; set; }
}

案例一:添加用户、角色

通过RoleManager、UserManager等来进行数据操作,创建用户:小明,角色:admin,为小明添加admin角色

[Route("api/[controller]/[action]")]
[ApiController]
public class DemoContrller : ControllerBase
{
    private readonly UserManager<MyUser> userManager;
    private readonly RoleManager<MyRole> roleManager;

    public DemoContrller(UserManager<MyUser> userManager, RoleManager<MyRole> roleManager)
    {
        this.userManager = userManager;
        this.roleManager = roleManager;
    }

    [HttpPost]
    public async Task<ActionResult<string>> Test1()
    {
        if (!await roleManager.RoleExistsAsync("admin"))
        {
            var result = await roleManager.CreateAsync(new MyRole { Name = "admin" });
            if (!result.Succeeded)
            {
                return BadRequest("角色创建失败");
            }
        }
        MyUser user1 = await userManager.FindByNameAsync("小明");
        if (user1 == null)
        {
            var result = await userManager.CreateAsync(new MyUser { UserName = "小明" }, "123456");
            if (!result.Succeeded)
            {
                return BadRequest("用户创建失败");
            }
        }
        if(!await userManager.IsInRoleAsync(user1, "admin"))
        {
            var result = await userManager.AddToRoleAsync(user1, "admin");
            if (!result.Succeeded)
            {
                return BadRequest("用户添加角色失败");
            }
        }
        return Ok("测试成功");
    }
}

案例二:检查登录用户信息

userManager.AccessFailedAsync记录“登录失败”,多次失败后,会被锁定一段时间,以避免账号被暴力破解,默认锁定时间5分钟,失败次数5次,,可以在Program.cs中设置options.Lockout.DefaultLockoutTimeSpanoptions.Lockout.MaxFailedAccessAttempts来修改默认值

[HttpPost]
public async Task<ActionResult<string>> Test2(CheckPwdRequest req)
{
    string userName = req.UserName;
    string password = req.Password;
    var user = await userManager.FindByNameAsync(userName);
    if (user == null)
    {
        return BadRequest("用户或密码错误");
    }
    //await userManager.ResetAccessFailedCountAsync(user);
    if (await userManager.IsLockedOutAsync(user))
    {
        DateTimeOffset lockout = (DateTimeOffset)user.LockoutEnd + new TimeSpan(8, 0, 0);
        return BadRequest(DateTime.Now + "用户已被锁定,解锁时间" + lockout);
    }
    if (await userManager.CheckPasswordAsync(user, password))
    {
        await userManager.ResetAccessFailedCountAsync(user);
        return Ok("登录成功");
    }
    else
    {
        await userManager.AccessFailedAsync(user);
        return BadRequest("用户或密码错误");
    }
}

案例三:实现密码的重置

调用GeneratePasswordResetTokenAsync方法来生成密码重置令牌,实际项目中,邮件发送一般调用邮件服务提供商的接口,这里只是简单输出到控制台,默认生成的令牌很长,我们可以在Project.cs设置options.Tokens.PasswordResetTokenProvider属性的值

步骤
  1. 生成重置Token
  2. Token发给客户(邮件、短信等),形式:链接、验证码等。
  3. 根据Token完成密码的重置。
[HttpPost]
public async Task<ActionResult> SendResetPasswordToken(string userName)
{
    var user = await userManager.FindByNameAsync(userName);
    if (user == null)
    {
        return BadRequest("用户名不存在!");
    }
    string token = await userManager.GeneratePasswordResetTokenAsync(user);
    Console.WriteLine($"向邮箱{user.Email}发送Token={token}");
    return Ok(token);
}

[HttpPut]
public async Task<ActionResult> ResetPassword(string userName, string token, string newPassword)
{
    var user = await userManager.FindByNameAsync(userName);
    if (user == null)
    {
        return BadRequest("用户名不存在!");
    }
    var result = await userManager.ResetPasswordAsync(user, token, newPassword);
    if (result.Succeeded)
    {
        await userManager.ResetAccessFailedCountAsync(user);
        return Ok("密码重置成功");
    }
    else
    {
        await userManager.AccessFailedAsync(user);
        return BadRequest("密码重置失败");
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/965898.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

124,【8】buuctf web [极客大挑战 2019] Http

进入靶场 查看源码 点击 与url有关&#xff0c;抓包 over

windows下安装Open Web UI

windows下安装openwebui有三种方式,docker,pythonnode.js,整合包. 这里我选择的是第二种,非docker. 非Docker方式安装 1. 安装Python&#xff1a; 下载并安装Python 3.11&#xff0c;建议安装路径中不要包含中文字符&#xff0c;并勾选“Add python 3.11 to Path”选项。 安…

Mac 基于Ollama 本地部署DeepSeek离线模型

最近节日期间最火的除了《哪吒》就是deepseek了&#xff0c;毕竟又让西方各个层面都瑟瑟发抖的产品。DeepSeek凭借其强大的AI能力真的是在全球多个领域展现出强大的影响力。由于受到外部势力的恶意攻击倒是deepseek官方服务不稳定&#xff0c;国内其他厂家的适配版本也不是很稳…

解决aspose将Excel转成PDF中文变成方框的乱码问题

原文网址&#xff1a;解决aspose将Excel转成PDF中文变成方框的乱码问题_IT利刃出鞘的博客-CSDN博客 简介 本文介绍如何解决aspose将Excel转成PDF中文变成方框的乱码问题。 问题描述 用aspose将word、excel等转成PDF后&#xff0c;英文展示正常&#xff0c;但中文全部变成了…

Jupyter Notebook自动保存失败等问题的解决

一、未生成配置文件 需要在命令行中&#xff0c;执行下面的命令自动生成配置文件 jupyter notebook --generate-config 执行后会在 C:\Users\用户名\.jupyter目录中生成文件 jupyter_notebook_config.py 二、在网页端打开Jupyter Notebook后文件保存失败&#xff1b;运行代码…

【漫话机器学习系列】083.安斯库姆四重奏(Anscombe‘s Quartet)

安斯库姆四重奏&#xff08;Anscombes Quartet&#xff09; 1. 什么是安斯库姆四重奏&#xff1f; 安斯库姆四重奏&#xff08;Anscombes Quartet&#xff09;是一组由统计学家弗朗西斯安斯库姆&#xff08;Francis Anscombe&#xff09; 在 1973 年 提出的 四组数据集。它们…

Axure设计教程:动态排名图(中继器实现)

一、开篇 在Axure原型设计中&#xff0c;动态图表是展示数据和交互效果的重要元素。今天&#xff0c;我们将学习如何使用中继器来创建一个动态的排名图&#xff0c;该图表不仅支持自动轮播&#xff0c;还可以手动切换&#xff0c;极大地增强了用户交互体验。此教程旨在提供一个…

MySQL视图索引操作

创建学生表&#xff1b; mysql> create table Student(-> Sno int primary key auto_increment,-> Sname varchar(30) not null unique,-> Ssex char(2) check (Ssex男 or Ssex女) not null,-> Sage int not null,-> Sdept varchar(10) default 计算机 not …

【正点原子K210连载】第六十七章 音频FFT实验 摘自【正点原子】DNK210使用指南-CanMV版指南

第六十七章 音频FFT实验 本章将介绍CanMV下FFT的应用&#xff0c;通过将时域采集到的音频数据通过FFT为频域。通过本章的学习&#xff0c;读者将学习到CanMV下控制FFT加速器进行FFT的使用。 本章分为如下几个小节&#xff1a; 32.1 maix.FFT模块介绍 32.2 硬件设计 32.3 程序设…

基于 Ollama+Docker+OpenWebUI 的本地化部署deepseek流程

搭建deepseek 安装Ollama Ollama官方下载地址 下载完成后双击打开Ollama进行安装,点击install 安装完成后系统会弹出下图提示代表安装成功并且已启动 验证安装 ollama -v安装完成后&#xff0c;cmd 打开命令行窗口&#xff0c;输入 “ollama -v” 测试&#xff0c;显示 olla…

Mac 部署Ollama + OpenWebUI完全指南

文章目录 &#x1f4bb; 环境说明&#x1f6e0;️ Ollama安装配置1. 安装[Ollama](https://github.com/ollama/ollama)2. 启动Ollama3. 模型存储位置4. 配置 Ollama &#x1f310; OpenWebUI部署1. 安装Docker2. 部署[OpenWebUI](https://www.openwebui.com/)&#xff08;可视化…

C#常用集合优缺点对比

先上结论&#xff1a; 在C#中&#xff0c;链表、一维数组、字典、List<T>和ArrayList是常见的数据集合类型&#xff0c;它们各有优缺点&#xff0c;适用于不同的场景。以下是它们的比较&#xff1a; 1. 一维数组 (T[]) 优点&#xff1a; 性能高&#xff1a;数组在内存中…

额外题目汇总2-链表

链表 1.24. 两两交换链表中的节点 力扣题目链接(opens new window) 给定一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后的链表。 你不能只是单纯的改变节点内部的值&#xff0c;而是需要实际的进行节点交换。 思路 使用虚拟头结点会很方便&#xff…

Nginx 中启用 Gzip 压缩以优化网页加载速度

&#x1f3e1;作者主页&#xff1a;点击&#xff01; Nginx-从零开始的服务器之旅专栏&#xff1a;点击&#xff01; &#x1f427;Linux高级管理防护和群集专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2025年2月7日17点14分 目录 1. 配置网页压缩 目的 …

《云夹:高效便捷的书签管理利器》

在信息爆炸的时代&#xff0c;我们每天都会浏览大量的网页&#xff0c;遇到许多有价值的内容。如何高效地管理这些网页书签&#xff0c;以便随时快速访问&#xff0c;成为了一个重要的问题。云夹作为一款出色的书签管理工具&#xff0c;为我们提供了完美的解决方案。 强大的功能…

学习数据结构(6)链表OJ

1.移除链表元素 解法一&#xff1a;&#xff08;我的做法&#xff09;在遍历的同时移除&#xff0c;代码写法比较复杂 解法二&#xff1a;创建新的链表&#xff0c;遍历原链表&#xff0c;将非val的节点尾插到新链表&#xff0c;注意&#xff0c;如果原链表结尾是val节点需要将…

MongoDB开发规范

分级名称定义P0核心系统需7*24不间断运行&#xff0c;一旦发生不可用&#xff0c;会直接影响核心业务的连续性&#xff0c;或影响公司名誉、品牌、集团战略、营销计划等&#xff0c;可能会造成P0-P2级事故发生。P1次核心系统这些系统降级或不可用&#xff0c;会间接影响用户使用…

设计模式.

设计模式 一、介绍二、六大原则1、单一职责原则&#xff08;Single Responsibility Principle, SRP&#xff09;2、开闭原则&#xff08;Open-Closed Principle, OCP&#xff09;3、里氏替换原则&#xff08;Liskov Substitution Principle, LSP&#xff09;4、接口隔离原则&am…

STM32的HAL库开发-通用定时器输入捕获实验

一、通用定时器输入捕获部分框图介绍 1、捕获/比较通道的输入部分(通道1) 首先设置 TIM_CCMR1的CC1S[1:0]位&#xff0c;设置成01&#xff0c;那么IC1来自于TI1&#xff0c;也就是说连接到TI1FP1上边。设置成10&#xff0c;那个IC1来自于TI2&#xff0c;连接到TI2FP1上。设置成…

JavaScript 复习

文章目录 语法前置语法组成引入位置内部引入外部引入 基础语法输出变量变量声明规则变量赋值变量的作用范围 数据类型强制类型转换强转为 Number强转为 Boolean强转为 String强转为 整数 | 浮点数 运算符流程控制隐式转换函数常用内置对象String 对象Array 数组对象Math 数学对…