ASP.NET Core 标识(Identity)框架系列(一):如何使用 ASP.NET Core 标识(Identity)框架创建用户和角色?

image

前言

ASP.NET Core 内置的标识(identity)框架,采用的是 RBAC(role-based access control,基于角色的访问控制)策略,是一个用于管理用户身份验证、授权和安全性的框架。

它提供了一套工具和库,用于管理用户、角色、登录、密码重置、电子邮件确认等功能。

通过它,你可以:

  1. 用户管理:创建、管理和验证用户,这样你可以轻松操作注册用户、登录、注销、密码重置等功能。

  2. 角色管理:定义不同的用户角色,并将用户分配到这些角色中,这样你可以更好地控制用户的权限和访问级别。

  3. 密码策略:框架提供了密码策略功能,允许你定义密码的复杂度要求,例如密码长度、大小写字母、数字等要求。

  4. 外部登录:框架还支持你使用外部身份验证提供者(如 QQ、微信、微博等)进行身份验证。

  5. 电子邮件确认:通过电子邮件确认用户注册和密码重置操作,这样注册和修改密码操作更加安全可靠。

今天,我们主要聊聊如何使用 ASP.NET Core 标识(Identity)框架来管理用户和角色,也有涉及到密码策略、电子邮件确认等方面。

Step By Step 步骤

  1. 创建一个 ASP.NET Core webapi 项目,命名为 IdentitySample

  2. 引用以下 Nuget 包:

    Microsoft.AspNetCore.Identity.EntityFrameworkCore
    Microsoft.EntityFrameworkCore.Relational
    Microsoft.EntityFrameworkCore.SqlServer
    Microsoft.EntityFrameworkCore.Tools

  3. 修改 appsettings.json,添加数据库连接字符串

    {"Logging": {"LogLevel": {"Default": "Information","Microsoft.AspNetCore": "Warning"}},"AllowedHosts": "*","ConnectionStrings": {"Default": "Server=(localdb)\\mssqllocaldb;Database=IdentityTestDB;Trusted_Connection=True;MultipleActiveResultSets=true"}
    }	
    
  4. 创建用户实体类 User(重点看注释

    using Microsoft.AspNetCore.Identity;// IdentityUser<long> 表示 long 类型主键的用户实体类
    // IdentityUser 中定义了 UserName(用户名)、Email(邮箱)、PhoneNumber(手机号)、PasswordHash(密码的哈希值)等属性,
    // 这里又添加了 CreationTime(创建时间)、NickName(昵称)两个属性。
    public class User: IdentityUser<long>
    {public DateTime CreationTime { get; set; }public string? NickName { get; set; }
    }
    
  5. 创建角色实体类 Role

    using Microsoft.AspNetCore.Identity;public class Role: IdentityRole<long>
    {}
    
  6. 创建继承自 IdentityDbContext 的上下文类(重点看注释

    using Microsoft.EntityFrameworkCore;
    using Microsoft.AspNetCore.Identity.EntityFrameworkCore;// 使用 Identity 框架要继承 IdentityDbContext
    // IdentityDbContext 是一个泛型类,有3个泛型参数,分别代表用户类型、角色类型和主键类型
    public class IdDbContext: IdentityDbContext<User, Role, long>
    {public IdDbContext(DbContextOptions<IdDbContext> options) : base(options){}protected override void OnModelCreating(ModelBuilder modelBuilder){base.OnModelCreating(modelBuilder);modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);}
    }	
    
  7. 打开 Program.cs 文件,向依赖注入容器中注册与标识框架相关的服务,并且对相关的选项进行配置(重点看注释

    using Microsoft.AspNetCore.Identity;
    using Microsoft.EntityFrameworkCore;var builder = WebApplication.CreateBuilder(args);// Add services to the container.builder.Services.AddControllers();
    // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
    builder.Services.AddEndpointsApiExplorer();
    builder.Services.AddSwaggerGen();// 向依赖注入容器中注册与标识框架相关的服务,并对相关的选项进行配置
    // ----1. 数据库注入
    IServiceCollection services = builder.Services;
    services.AddDbContext<IdDbContext>(opt =>
    {string connStr = builder.Configuration.GetConnectionString("Default")!;opt.UseSqlServer(connStr);
    });
    // ----2. 数据保护服务注入
    // ----数据保护提供了一个简单、基于非对称加密改进的加密API用于确保Web应用敏感数据的安全存储
    // ----不需要开发人员自行生成密钥,它会根据当前应用的运行环境,生成该应用独有的一个私钥
    services.AddDataProtection();
    // ----3. 添加标识框架的一些重要的基础服务
    services.AddIdentityCore<User>(options => { options.Password.RequireDigit = false;options.Password.RequireLowercase = false;options.Password.RequireNonAlphanumeric = false;options.Password.RequireUppercase = false;options.Password.RequiredLength = 6;options.Tokens.PasswordResetTokenProvider = TokenOptions.DefaultEmailProvider;options.Tokens.EmailConfirmationTokenProvider = TokenOptions.DefaultEmailProvider;
    });
    // ----4. 注入 UserManager、RoleManager等服务
    var idBuilder = new IdentityBuilder(typeof(User), typeof(Role), services);
    idBuilder.AddEntityFrameworkStores<IdDbContext>().AddDefaultTokenProviders().AddRoleManager<RoleManager<Role>>().AddUserManager<UserManager<User>>();var app = builder.Build();// Configure the HTTP request pipeline.
    if (app.Environment.IsDevelopment())
    {app.UseSwagger();app.UseSwaggerUI();
    }app.UseHttpsRedirection();app.UseAuthorization();app.MapControllers();app.Run();
    
  8. 执行以下命令进行数据迁移,执行后将在数据库中生成多张与 Identity 相关的表

    Add-Migration InitIdentity
    Update-database
    
  9. 创建相应的实体类

    public record LoginRequest(string UserName, string Password);public record SendResetPasswordTokenRequest(string Email);public record ResetPasswordResponse(string Email, string Token, string NewPassword);
    
  10. 在控制器中编写代码,操作角色、用户数据(重点看注释

    using Microsoft.AspNetCore.Mvc;
    using Microsoft.AspNetCore.Identity;namespace IdentitySample.Controllers
    {[ApiController][Route("[controller]/[action]")]public class Test1Controller : ControllerBase{private readonly ILogger<Test1Controller> logger;private readonly RoleManager<Role> roleManager;private readonly UserManager<User> userManager;// 注入 RoleManager,UserManager,ILoggerpublic Test1Controller(ILogger<Test1Controller> logger,RoleManager<Role> roleManager,UserManager<User> userManager){this.logger = logger;this.roleManager = roleManager;this.userManager = userManager;}// 创建角色和用户[HttpPost]public async Task<ActionResult> CreateUserRole(){// 1. 判断管理员角色是否存在,不存在则创建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);}}// 2. 创建账户User user = await userManager.FindByNameAsync("yzk");if (user == null){user = new User{UserName = "yzk",Email = "51398898@qq.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();}// 登录[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{// 调用userManager的AccessFailedAsync方法来记录一次“登录失败”,// 当连续多次登录失败之后,账户就会被锁定一段时间,以避免账户被暴力破解var r = await userManager.AccessFailedAsync(user);if (!r.Succeeded){return BadRequest("AccessFailed failed");}return BadRequest("Failed");}}// 发送重置密码 Token[HttpPost]public async Task<IActionResult> SendResetPasswordToken(SendResetPasswordTokenRequest req){string email = req.Email;var user = await userManager.FindByEmailAsync(email);if (user == null){return NotFound($"邮箱不存在:[{email}]");}// 调用GeneratePasswordResetTokenAsync方法来生成一个密码重置令牌,这个令牌会被保存到数据库中// 然后把这个令牌发送到用户邮箱string token = await userManager.GenerateEmailConfirmationTokenAsync(user);logger.LogInformation($"向邮箱{user.Email}发送Token={token}");return Ok(token); }// 重置密码[HttpPost]public async Task<IActionResult> VerifyResetPasswordToken(ResetPasswordRequest req){string email = req.Email;var user = await userManager.FindByEmailAsync(email);string token = req.Token;string password = req.NewPassword;var r = await userManager.ResetPasswordAsync(user, token, password);return Ok();}}
    }	
    
  11. 启动项目,通过 Postman 或 Swagger 运行 API 进行测试

最后

ASP.NET Core 内置的标识(identity)框架使用 EF Core 对数据库进行操作

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

openGauss学习笔记-259 openGauss性能调优-使用Plan Hint进行调优-指定不使用全局计划缓存的Hint

文章目录 openGauss学习笔记-259 openGauss性能调优-使用Plan Hint进行调优-指定不使用全局计划缓存的Hint259.1 功能描述259.2 语法格式259.3 示例 openGauss学习笔记-259 openGauss性能调优-使用Plan Hint进行调优-指定不使用全局计划缓存的Hint 259.1 功能描述 全局计划缓…

Windows下MySQL服务启动常见的两种方式,完美适配Mysql5.7,MySql8.0

文章目录 一、图形界面下启动mysql服务二、在命令行重新启动mysql服务三、推荐阅读四、源码获取&#xff1a; Windows系统下&#xff0c;MySQL服务的启动&#xff0c;常见的两种启动方式如下&#xff1a; 一、图形界面下启动mysql服务 在图形界面下启动mysql服务的流程如下&am…

雄安建博会:中矿雄安新区的总部开工建设

中矿落位雄安&#xff1a;助力国家战略与新区发展 雄安新区&#xff0c;作为中国未来发展的重要战略支点&#xff0c;正迎来一系列央企总部的疏解与建设。最近&#xff0c;中国矿产资源集团有限公司&#xff08;简称“中矿”&#xff09;在雄安新区的总部项目正式开工建设&…

leetcode628-Maximum Product of Three Numbers

题目 给你一个整型数组 nums &#xff0c;在数组中找出由三个数组成的最大乘积&#xff0c;并输出这个乘积。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;6 分析 这道题目要求数组中三个数组成的最大乘积&#xff0c;由于元素有正数有负数&#xff…

0.Go的安装和基本语法

0.安装 0.1.下载安装包 https://golang.google.cn/dl/ linux下载go1.Xxx.Yyy.linux-amd64.tar.gz版本安装包 0.2.解压 tar -C /usr/local -xzf go1.4.linux-amd64.tar.gz0.3.安装 修改/etc/profile文件&#xff0c; 添加一行 export PATH$PATH:/usr/local/go/bin或者修改…

Python 怎么将dict字典转换成json文件保存

文章目录 Python 怎么将dict字典转换成json文件保存1. json.dump&#xff08;&#xff09;2. with open("要打开的文件路径/保存的地址file_name", "w") as outfiles: Python 怎么将dict字典转换成json文件保存 1. json.dump&#xff08;&#xff09; 公…

C++设计模式:原型模式(八)

1、定义与动机 定义&#xff1a;使用原型实例指定创建对象的种类&#xff0c;然后通过拷贝这些原型来创建新的对象。 动机&#xff1a; 在软件系统中&#xff0c;经常面临着“某些结构复杂的对象”的创建工作&#xff1b;由于需求的变化&#xff0c;这些对象经常面临着剧烈的变…

BUUCTF刷题十一道(12)附-SSTI专题二

文章目录 学习文章[CISCN2019 华东南赛区]Web11【存疑】[RootersCTF2019]I_<3_Flask 学习文章 SSTI-服务端模板注入漏洞 flask之ssti模板注入从零到入门 CTFSHOW SSTI篇-yu22x SSTI模板注入绕过&#xff08;进阶篇&#xff09;-yu22x SSTI模板注入学习-竹言笙熙 全部总结看最…

Chatgpt掘金之旅—有爱AI商业实战篇|在线辅导业务|(十一)

演示站点&#xff1a; https://ai.uaai.cn 对话模块 官方论坛&#xff1a; www.jingyuai.com 京娱AI 一、AI技术创业在线辅导业务有哪些机会&#xff1f; 人工智能&#xff08;AI&#xff09;技术作为当今科技创新的前沿领域&#xff0c;为创业者提供了广阔的机会和挑战。随着…

谷歌浏览器快捷键, VScode 快捷键

谷歌浏览器快捷键 谷歌浏览器跳转标签页的方式&#xff1a; control Tab 跳转下一个标签页 control shift tab 上一个标签页 command 1-8 跳转对应的标签页&#xff0c;而command 9 则是跳转最后一个标签页 Previous Tab 插件实现谷歌浏览器两个tab页来回切换。快捷键为…

稀碎从零算法笔记Day44-LeetCode:整数转罗马数字

题型&#xff1a;贪心、模拟 链接&#xff1a; 12. 整数转罗马数字 - 力扣&#xff08;LeetCode&#xff09; 来源&#xff1a;LeetCode 题目描述 罗马数字包含以下七种字符&#xff1a; I&#xff0c; V&#xff0c; X&#xff0c; L&#xff0c;C&#xff0c;D 和 M。 …

网络名称空间在Linux虚拟化技术中的位置

网络名称空间&#xff08;Network Namespaces&#xff09;是Linux内核特性之一&#xff0c;提供了隔离网络环境的能力&#xff0c;使得每个网络名称空间都拥有独立的网络设备、IP地址、路由表、端口号范围以及iptables规则等。这一特性在Linux虚拟化技术中占据了核心位置&#…

上海计算机学会 2023年6月月赛 乙组T1 两数归零(STL、map)

第一题&#xff1a;T1两数归零 标签&#xff1a; S T L 、 m a p STL、map STL、map 题意&#xff1a;给定 n n n个整数 a 1 , a 2 , a 3 , . . . , a n a_1,a_2,a_3,...,a_n a1​,a2​,a3​,...,an​&#xff0c;请统计有多少二元组 i , j i,\ j i, j满足 i < j i < j …

天池医疗AI大赛[第一季] Rank5解决方案

一、赛题说明 数据格式 本次大赛数据集包含数千份高危患者的低剂量肺部CT影像&#xff08;mhd格式&#xff09;数据&#xff0c;每个影像包含一系列胸腔的多个轴向切片。每个影像包含的切片数量会随着扫描机器、扫描层厚和患者的不同而有差异。原始图像为三维图像。这个三维图…

Win10系统下的EDGE浏览器启用IE模式

Win10系统下的EDGE浏览器目前已弃用IE内核&#xff0c;这样在访问某些较老的网站会有兼容性问题&#xff0c;本文记录了在EDGE浏览器中启用IE模式的操作方法。 一、启用EDGE浏览器的IE模式 要打开Internet Explorer模式&#xff0c;执行以下步骤: 1、在Microsoft Edge的地址栏…

TryHackMe - HTTP Request Smuggling

学完、打完后的复习 HTTP 1 这部分比较简单&#xff0c;直接略过 HTTP2请求走私 首先要了解HTTP2的结构&#xff0c;与HTTP1之间的一些差异 HTTP2中不再使用CRLF来作为字段的边界限定&#xff0c;而是在二进制中直接通过长度、名字、值长度、值&#xff0c;来确认边界 而这…

数据仓库的概念和作用?如何搭建数据仓库?

随着企业规模的扩大和数据量的爆炸性增长&#xff0c;有效管理和分析海量数据成为企业数字化转型的关键。而在互联网的普及过程中&#xff0c;信息技术已深入渗透各行业&#xff0c;逐渐融入企业的日常运营。然而&#xff0c;企业在信息化建设中面临了一系列困境和挑战&#xf…

微信小程序第六次课(模块化和绑定事件)

模块化 1.首先 我们在utils里面创建一个新的js文件 2.新的js文件里面写我们要实现的函数功能 3.把新的函数功能 通过 module.export.对外公开文件名 新文件名 的方式把之前的函数公开到其他他模块 &#xff08;类似于public 让别的模块可以…

https的配置和使用(以腾讯云为例)

1、注册域名 2、获取证书 3、下载证书 下载下来的证书所有格式 4、在服务器上下载nginx并配置 nginx的配置文件 如下 server {listen 80;listen 443 ssl;server_name delegate.letspiu.net.cn;ssl on; #开启ssl#指定证书位置ssl_certificate /etc/ss…

JRT判断数据是否存在优化

有一种业务情况类似下图&#xff0c;质控能做的项目是仪器关联的项目。这时候维护质控物时候开通项目时候要求加载仪器项目里面的项目&#xff08;没有开通的子业务数据的部分&#xff09;。对右边已经开通的部分要求加载仪器项目里面的项目&#xff08;有开通业务子数据的部分…