7.3 ASP.NET Core Identity 7.3 ASP.NET Core Identity ASP.NET Core Identity 是一个用于处理用户身份验证和授权的完整系统。它提供了创建、管理和验证用户帐户所需的所有基本功能,并具有高度的可定制性和可扩展性。与之前的 ASP.NET Membership 相比,ASP.NET Core Identity 更加模块化,更易于集成到现代应用程序中。 7.3.1 ASP.NET Core Identity 的核心概念 在深入代码之前,理解 ASP.NET Core Identity 的核心概念至关重要: User: 代表应用程序中的一个用户。通常包含用户名、密码哈希、电子邮件地址等信息。 Role: 代表一组权限。
ASP.NET Core Identity 是一个用于处理用户身份验证和授权的完整系统。它提供了创建、管理和验证用户帐户所需的所有基本功能,并具有高度的可定制性和可扩展性。与之前的 ASP.NET Membership 相比,ASP.NET Core Identity 更加模块化,更易于集成到现代应用程序中。
在深入代码之前,理解 ASP.NET Core Identity 的核心概念至关重要:
User: 代表应用程序中的一个用户。通常包含用户名、密码哈希、电子邮件地址等信息。
Role: 代表一组权限。用户可以被分配到一个或多个角色。
Claim: 关于用户的声明,例如用户的姓名、年龄、权限等。Claims 可以用于更细粒度的授权。
UserManager: 用于管理用户的核心类。提供创建、更新、删除用户、验证密码、添加/删除角色等功能。
RoleManager: 用于管理角色的核心类。提供创建、更新、删除角色等功能。
SignInManager: 用于处理用户登录和注销的核心类。它与 UserManager 协同工作以验证用户凭据并创建身份验证 cookie。
IUserStore: 定义了用户数据的存储方式的接口。ASP.NET Core Identity 默认提供了 Entity Framework Core (EF Core) 实现,但也允许自定义存储。
IRoleStore: 定义了角色数据的存储方式的接口。与 IUserStore 类似,也提供了 EF Core 实现和自定义选项。
安装 NuGet 包:
首先,需要在项目中安装必要的 NuGet 包。 最常用的包是:
Microsoft.AspNetCore.Identity.EntityFrameworkCore: 用于使用 EF Core 作为 Identity 存储。
Microsoft.AspNetCore.Identity.UI: 提供默认的 UI 组件,例如注册、登录、忘记密码等页面。
可以使用 .NET CLI 安装这些包:
dotnet add package Microsoft.AspNetCore.Identity.EntityFrameworkCore dotnet add package Microsoft.AspNetCore.Identity.UI
配置 Identity 服务:
在 Startup.cs 文件中的 ConfigureServices 方法中,需要配置 Identity 服务。
using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using YourProjectName.Data; // 替换为你的数据上下文命名空间 public void ConfigureServices(IServiceCollection services) { // 配置数据库上下文 services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); // 添加 Identity 服务 services.AddDefaultIdentity<IdentityUser>(options => { // 配置 Identity 选项 (可选) options.SignIn.RequireConfirmedAccount = false; // 是否需要确认帐户 options.Password.RequireDigit = false; options.Password.RequireLowercase = false; options.Password.RequireNonAlphanumeric = false; options.Password.RequireUppercase = false; options.Password.RequiredLength = 6; options.Password.RequiredUniqueChars = 1; }) .AddRoles<IdentityRole>() // 添加角色支持 .AddEntityFrameworkStores<ApplicationDbContext>(); // 添加 Razor Pages 支持 (如果使用默认 UI) services.AddRazorPages(); }
AddDbContext<ApplicationDbContext>: 配置 EF Core 数据上下文。你需要创建一个继承自 DbContext 的类来代表你的数据库。
AddDefaultIdentity<IdentityUser>: 添加 Identity 服务,并指定 IdentityUser 作为默认的用户类型。你可以创建自定义的用户类,继承自 IdentityUser,以添加额外的属性。
AddRoles<IdentityRole>(): 添加角色支持。 同样,可以使用自定义角色类,继承自IdentityRole。
AddEntityFrameworkStores<ApplicationDbContext>: 指定使用 EF Core 作为 Identity 存储。
AddRazorPages(): 如果使用默认的 UI 组件,需要添加 Razor Pages 支持。
配置中间件:
在 Startup.cs 文件中的 Configure 方法中,确保添加 Identity 中间件。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseMigrationsEndPoint(); } else { app.UseExceptionHandler("/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); // 添加身份验证中间件 app.UseAuthorization(); // 添加授权中间件 app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); }); }
UseAuthentication(): 添加身份验证中间件,用于验证用户的身份。
UseAuthorization(): 添加授权中间件,用于检查用户是否具有访问特定资源的权限。
创建数据库上下文:
创建一个继承自 IdentityDbContext 的类,用于表示 Identity 的数据库上下文。
using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; namespace YourProjectName.Data { public class ApplicationDbContext : IdentityDbContext { public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { } } }
创建数据库迁移并更新数据库:
使用 EF Core 迁移来创建数据库表。
dotnet ef migrations add InitialCreate dotnet ef database update
配置完成后,可以使用 UserManager, RoleManager 和 SignInManager 来管理用户、角色和登录。
示例:创建用户
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using System.Threading.Tasks; public class AccountController : Controller { private readonly UserManager<IdentityUser> _userManager; public AccountController(UserManager<IdentityUser> userManager) { _userManager = userManager; } [HttpPost] public async Task<IActionResult> Register(string username, string password) { var user = new IdentityUser { UserName = username, Email = username }; var result = await _userManager.CreateAsync(user, password); if (result.Succeeded) { // 用户创建成功 return Ok("User created successfully"); } else { // 处理错误 return BadRequest(result.Errors); } } }
示例:登录用户
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using System.Threading.Tasks; public class AccountController : Controller { private readonly SignInManager<IdentityUser> _signInManager; public AccountController(SignInManager<IdentityUser> signInManager) { _signInManager = signInManager; } [HttpPost] public async Task<IActionResult> Login(string username, string password, bool rememberMe) { var result = await _signInManager.PasswordSignInAsync(username, password, rememberMe, lockoutOnFailure: false); if (result.Succeeded) { // 登录成功 return Ok("Login successful"); } else { // 处理错误 return BadRequest("Invalid login attempt"); } } }
示例:创建角色并分配给用户
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using System.Threading.Tasks; public class RoleController : Controller { private readonly RoleManager<IdentityRole> _roleManager; private readonly UserManager<IdentityUser> _userManager; public RoleController(RoleManager<IdentityRole> roleManager, UserManager<IdentityUser> userManager) { _roleManager = roleManager; _userManager = userManager; } [HttpPost] public async Task<IActionResult> CreateRole(string roleName) { if (!await _roleManager.RoleExistsAsync(roleName)) { var role = new IdentityRole(roleName); var result = await _roleManager.CreateAsync(role); if (result.Succeeded) { return Ok("Role created successfully"); } else { return BadRequest(result.Errors); } } return BadRequest("Role already exists"); } [HttpPost] public async Task<IActionResult> AddUserToRole(string username, string roleName) { var user = await _userManager.FindByNameAsync(username); if (user == null) { return BadRequest("User not found"); } if (!await _roleManager.RoleExistsAsync(roleName)) { return BadRequest("Role not found"); } var result = await _userManager.AddToRoleAsync(user, roleName); if (result.Succeeded) { return Ok("User added to role successfully"); } else { return BadRequest(result.Errors); } } }
Claims 允许你定义关于用户的更细粒度的信息,并使用这些信息进行授权。
示例:添加 Claim
using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using System.Security.Claims; using System.Threading.Tasks; public class AccountController : Controller { private readonly UserManager<IdentityUser> _userManager; public AccountController(UserManager<IdentityUser> userManager) { _userManager = userManager; } [HttpPost] public async Task<IActionResult> AddClaim(string username, string claimType, string claimValue) { var user = await _userManager.FindByNameAsync(username); if (user == null) { return BadRequest("User not found"); } var claim = new Claim(claimType, claimValue); var result = await _userManager.AddClaimAsync(user, claim); if (result.Succeeded) { return Ok("Claim added successfully"); } else { return BadRequest(result.Errors); } } }
示例:使用 Claims 进行授权
在 Startup.cs 中配置授权策略:
using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.DependencyInjection; public void ConfigureServices(IServiceCollection services) { services.AddAuthorization(options => { options.AddPolicy("RequireAdministratorRole", policy => policy.RequireRole("Administrator")); options.AddPolicy("RequireClaim.DateOfBirth", policy => policy.RequireClaim("DateOfBirth")); options.AddPolicy("RequireClaim.DateOfBirthValue", policy => policy.RequireClaim("DateOfBirth", "2000-01-01")); }); }
在 Controller 中使用授权策略:
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; [Authorize(Policy = "RequireClaim.DateOfBirthValue")] public class AdminController : Controller { public IActionResult Index() { return View(); } }
ASP.NET Core Identity 允许你自定义用户类、角色类和存储机制。
自定义 User 类:
创建一个继承自 IdentityUser 的类,并添加自定义属性。
using Microsoft.AspNetCore.Identity; public class AppUser : IdentityUser { public string FirstName { get; set; } public string LastName { get; set; } }
在 Startup.cs 中使用自定义用户类:
services.AddDefaultIdentity<AppUser>() .AddRoles<IdentityRole>() .AddEntityFrameworkStores<ApplicationDbContext>();
自定义 Role 类:
创建一个继承自 IdentityRole 的类,并添加自定义属性。
using Microsoft.AspNetCore.Identity; public class AppRole : IdentityRole { public string Description { get; set; } }
在 Startup.cs 中使用自定义角色类:
services.AddDefaultIdentity<IdentityUser>() .AddRoles<AppRole>() .AddEntityFrameworkStores<ApplicationDbContext>();
自定义存储:
你可以实现 IUserStore 和 IRoleStore 接口,以使用自定义的存储机制,例如 NoSQL 数据库。
Microsoft.AspNetCore.Identity.UI 包提供了默认的 UI 组件,例如注册、登录、忘记密码等页面。 可以通过以下步骤使用这些UI组件。
确保已安装了Microsoft.AspNetCore.Identity.UI 包。
在Startup.cs 文件中,调用 AddRazorPages()方法。
默认情况下,UI 组件位于 /Areas/Identity/Pages 目录下。 可以复制这些文件并进行自定义。
ASP.NET Core Identity 是一个强大而灵活的身份验证和授权系统。 它提供了丰富的功能,并且可以高度定制以满足各种应用程序的需求。 通过理解其核心概念和使用方法,可以构建安全可靠的 ASP.NET Core 应用程序。
希望这篇文章能够帮助你理解和使用 ASP.NET Core Identity。