ASP.NET Core Identity 配置

在本章中,我们将安装和配置 Identity 框架,这只需要一点点工作。如果您转到 Visual Studio 并创建一个新的 ASP.NET Core 应用程序,并且选择了身份验证设置为单个用户帐户的完整 web 应用程序模板,则该新项目将包含为您设置的 Identity 框架的所有部分。

步骤 1:首先创建一个新的 ASP.NET Core 应用,命名为 MyCoreWeb,身份验证选择个人账户。

然后新建 Models 文件夹,并在 Models 中新建一个类,命名为 User

调用这个类 User 并单击上面截图中的 添加 按钮。在这个类中,您可以添加属性来保存您想要存储的关于用户的任何信息。

让我们从 Identity 框架提供的类派生 User 类。Identity.EntityFramework 命名空间中的 IdentityUser 类。

  1. using Microsoft.AspNetCore.Identity;
  2. namespace MyCoreWeb.Models
  3. {
  4. public class User: IdentityUser
  5. {
  6. }
  7. }

步骤 2:现在,让我们转到 IdentityUser,将光标放在该符号上,然后按 F12 查看 Visual Studio 的元数据视图。

您可以看到 IdentityUser 是从字符串的 IdentityUser 派生的。您可以通过从 IdentityUser 派生并指定泛型类型参数来更改主键的类型。您还可以使用主键(理想情况下为整数值)存储内容。

现在让我们将光标放在字符串的 IdentityUser 上,然后再次按 F12 转到元数据视图。

默认情况下,您现在可以查看与用户相关的所有信息。信息包括以下内容:

  • 我们不会在此应用程序中使用的字段,但可以使用。
  • Identity 框架可以跟踪特定用户登录失败的次数,并可以在一段时间内锁定该帐户。
  • 用于存储PasswordHash和PhoneNumber的字段。我们将使用的两个重要字段是 PasswordHashUserName
  • 我们还将隐式使用用户的主键和 ID 属性。如果需要查询特定用户,也可以使用该属性。

现在,我们需要确保 User 包含在 DBContext 中。因此,让我们打开应用程序中的 MyCoreWeb,而不是直接从 DBContext 派生它,DBContext 是内置的 Entity Framework 基类,我们现在需要从 IdentityDbContext 派生它。

  1. using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
  2. using Microsoft.EntityFrameworkCore;
  3. namespace MyCoreWeb.Models
  4. {
  5. public class MyCoreWebDbContext : IdentityDbContext<User>
  6. {
  7. public MyCoreWebDbContext(DbContextOptions<MyCoreWebDbContext> options) : base(options)
  8. {
  9. }
  10. public DbSet<Employee> Employees { get; set; }
  11. protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
  12. {
  13. optionsBuilder.UseSqlServer("Data Source=localhost;Initial Catalog=program;Persist Security Info=True;User ID=sa;Password=123456");
  14. }
  15. }
  16. }

步骤 3IdentityDbContext 类也在 Microsoft.AspNet.Identity.EntityFramework 命名空间中,我们可以指定它应该存储的用户类型。这样,我们添加到 User 类的任何其他字段都会进入数据库。

  • IdentityDbContext 带来了额外的 DbSet,不仅用于存储用户,还用于存储有关用户角色和用户声明的信息。
  • 我们的 User 类现在准备好了。我们的 MyCoreWebDbContext 类被配置为使用 Identity 框架。
  • 现在,我们可以进入 ConfigureConfigureServices 来设置 Identity 框架。

步骤 4:现在让我们从 ConfigureServices 开始。除了 MVC 服务和 Entity Framework 服务之外,我们还需要添加 Identity 服务。这将添加 Identity 框架工作所依赖的所有服务。

  1. public void ConfigureServices(IServiceCollection services)
  2. {
  3. services.AddControllersWithViews();
  4. services.AddDbContext<MyCoreWebDbContext>(options =>
  5. options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
  6. services.AddIdentity<User, IdentityRole>()
  7. .AddEntityFrameworkStores<MyCoreWebDbContext>();
  8. services.AddRazorPages();
  9. }
  • AddIdentity 方法采用两个通用类型参数——用户实体的类型和角色实体的类型。
  • 两个通用类型参数是我们的用户类型——我们刚刚创建的 user 类和我们要使用的 Role 类。现在我们将使用内置的 IdentityRole。此类位于 EntityFramework 命名空间中。
  • 当我们使用带有标识的 Entity Framework 时,我们还需要调用第二个方法—— AddEntityFrameworkStores
  • AddEntityFrameworkStores 方法将配置 UserStore 等服务,该服务用于创建用户并验证其密码。

步骤 5:下面两行是我们为应用程序配置服务所需的全部内容。

  1. services.AddIdentity<User, IdentityRole>()
  2. .AddEntityFrameworkStores<MyCoreWebDbContext>();

步骤 6:我们还需要添加中间件。我们插入中间件的位置很重要,因为如果我们在管道中插入中间件太晚,它将永远没有机会处理请求。

如果我们需要在 MVC 控制器内部进行授权检查,我们需要在 MVC 框架之前插入 Identity 中间件,以确保 cookie 和 401 错误都得到成功处理。

  1. public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
  2. {
  3. if (env.IsDevelopment())
  4. {
  5. app.UseDeveloperExceptionPage();
  6. app.UseDatabaseErrorPage();
  7. }
  8. else
  9. {
  10. app.UseExceptionHandler("/Error");
  11. app.UseHsts();
  12. }
  13. app.UseHttpsRedirection();
  14. app.UseStaticFiles();
  15. app.UseRouting();
  16. app.UseAuthentication();
  17. app.UseAuthorization();
  18. app.UseEndpoints(endpoints =>
  19. {
  20. endpoints.MapRazorPages();
  21. });
  22. }

步骤 7:插入中间件的位置是添加 Identity 中间件的地方。以下是 Startup.cs 文件的完整代码:

  1. using Microsoft.AspNetCore.Builder;
  2. using Microsoft.AspNetCore.Hosting;
  3. using Microsoft.AspNetCore.Identity;
  4. using Microsoft.EntityFrameworkCore;
  5. using Microsoft.Extensions.Configuration;
  6. using Microsoft.Extensions.DependencyInjection;
  7. using Microsoft.Extensions.Hosting;
  8. using MyCoreWeb.Models;
  9. namespace MyCoreWeb
  10. {
  11. public class Startup
  12. {
  13. public Startup(IConfiguration configuration)
  14. {
  15. Configuration = configuration;
  16. }
  17. public IConfiguration Configuration { get; }
  18. public void ConfigureServices(IServiceCollection services)
  19. {
  20. services.AddControllersWithViews();
  21. services.AddDbContext<MyCoreWebDbContext>(options =>
  22. options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
  23. services.AddIdentity<User, IdentityRole>()
  24. .AddEntityFrameworkStores<MyCoreWebDbContext>();
  25. services.AddRazorPages();
  26. }
  27. public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
  28. {
  29. if (env.IsDevelopment())
  30. {
  31. app.UseDeveloperExceptionPage();
  32. app.UseDatabaseErrorPage();
  33. }
  34. else
  35. {
  36. app.UseExceptionHandler("/Error");
  37. app.UseHsts();
  38. }
  39. app.UseHttpsRedirection();
  40. app.UseStaticFiles();
  41. app.UseRouting();
  42. app.UseAuthentication();
  43. app.UseAuthorization();
  44. app.UseEndpoints(endpoints =>
  45. {
  46. endpoints.MapRazorPages();
  47. });
  48. }
  49. }
  50. }

现在让我们继续构建应用程序。在下一章中,我们需要添加另一个 Entity Framework 迁移,以确保 SQL Server 数据库中有 Identity 模式。