7.3 ASP.NET Core Identity


文档摘要

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: 代表一组权限。

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: 代表一组权限。用户可以被分配到一个或多个角色。

  • Claim: 关于用户的声明,例如用户的姓名、年龄、权限等。Claims 可以用于更细粒度的授权。

  • UserManager: 用于管理用户的核心类。提供创建、更新、删除用户、验证密码、添加/删除角色等功能。

  • RoleManager: 用于管理角色的核心类。提供创建、更新、删除角色等功能。

  • SignInManager: 用于处理用户登录和注销的核心类。它与 UserManager 协同工作以验证用户凭据并创建身份验证 cookie。

  • IUserStore: 定义了用户数据的存储方式的接口。ASP.NET Core Identity 默认提供了 Entity Framework Core (EF Core) 实现,但也允许自定义存储。

  • IRoleStore: 定义了角色数据的存储方式的接口。与 IUserStore 类似,也提供了 EF Core 实现和自定义选项。

graph TD A[User] --> B(User Claims); A --> C(User Roles); D[Role] --> E(Role Claims); F[UserManager] --> A; G[RoleManager] --> D; H[SignInManager] --> A; I[IUserStore] --> A; J[IRoleStore] --> D; style A fill:#f9f,stroke:#333,stroke-width:2px style D fill:#f9f,stroke:#333,stroke-width:2px

7.3.2 配置 ASP.NET Core Identity

  1. 安装 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
  2. 配置 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 支持。

  3. 配置中间件:

    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(): 添加授权中间件,用于检查用户是否具有访问特定资源的权限。

  4. 创建数据库上下文:

    创建一个继承自 IdentityDbContext 的类,用于表示 Identity 的数据库上下文。

    using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; namespace YourProjectName.Data { public class ApplicationDbContext : IdentityDbContext { public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { } } }
  5. 创建数据库迁移并更新数据库:

    使用 EF Core 迁移来创建数据库表。

    dotnet ef migrations add InitialCreate dotnet ef database update

7.3.3 使用 UserManager, RoleManager 和 SignInManager

配置完成后,可以使用 UserManager, RoleManagerSignInManager 来管理用户、角色和登录。

示例:创建用户

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); } } }

7.3.4 使用 Claims 进行授权

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(); } }

7.3.5 自定义 Identity

ASP.NET Core Identity 允许你自定义用户类、角色类和存储机制。

  1. 自定义 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>();
  2. 自定义 Role 类:

    创建一个继承自 IdentityRole 的类,并添加自定义属性。

    using Microsoft.AspNetCore.Identity; public class AppRole : IdentityRole { public string Description { get; set; } }

    Startup.cs 中使用自定义角色类:

    services.AddDefaultIdentity<IdentityUser>() .AddRoles<AppRole>() .AddEntityFrameworkStores<ApplicationDbContext>();
  3. 自定义存储:

    你可以实现 IUserStoreIRoleStore 接口,以使用自定义的存储机制,例如 NoSQL 数据库。

7.3.6 ASP.NET Core Identity UI

Microsoft.AspNetCore.Identity.UI 包提供了默认的 UI 组件,例如注册、登录、忘记密码等页面。 可以通过以下步骤使用这些UI组件。

  1. 确保已安装了Microsoft.AspNetCore.Identity.UI 包。

  2. Startup.cs 文件中,调用 AddRazorPages()方法。

  3. 默认情况下,UI 组件位于 /Areas/Identity/Pages 目录下。 可以复制这些文件并进行自定义。

7.3.7 总结

ASP.NET Core Identity 是一个强大而灵活的身份验证和授权系统。 它提供了丰富的功能,并且可以高度定制以满足各种应用程序的需求。 通过理解其核心概念和使用方法,可以构建安全可靠的 ASP.NET Core 应用程序。

希望这篇文章能够帮助你理解和使用 ASP.NET Core Identity。


发布者: 作者: 转发
评论区 (0)
U