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
类。
using Microsoft.AspNetCore.Identity;
namespace MyCoreWeb.Models
{
public class User: IdentityUser
{
}
}
步骤 2:现在,让我们转到 IdentityUser
,将光标放在该符号上,然后按 F12 查看 Visual Studio 的元数据视图。
您可以看到 IdentityUser
是从字符串的 IdentityUser
派生的。您可以通过从 IdentityUser
派生并指定泛型类型参数来更改主键的类型。您还可以使用主键(理想情况下为整数值)存储内容。
现在让我们将光标放在字符串的 IdentityUser
上,然后再次按 F12 转到元数据视图。
默认情况下,您现在可以查看与用户相关的所有信息。信息包括以下内容:
- 我们不会在此应用程序中使用的字段,但可以使用。
Identity
框架可以跟踪特定用户登录失败的次数,并可以在一段时间内锁定该帐户。- 用于存储PasswordHash和PhoneNumber的字段。我们将使用的两个重要字段是
PasswordHash
和UserName
。 - 我们还将隐式使用用户的主键和
ID
属性。如果需要查询特定用户,也可以使用该属性。
现在,我们需要确保 User 包含在 DBContext 中。因此,让我们打开应用程序中的 MyCoreWeb,而不是直接从 DBContext 派生它,DBContext 是内置的 Entity Framework 基类,我们现在需要从 IdentityDbContext 派生它。
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
namespace MyCoreWeb.Models
{
public class MyCoreWebDbContext : IdentityDbContext<User>
{
public MyCoreWebDbContext(DbContextOptions<MyCoreWebDbContext> options) : base(options)
{
}
public DbSet<Employee> Employees { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Data Source=localhost;Initial Catalog=program;Persist Security Info=True;User ID=sa;Password=123456");
}
}
}
步骤 3:IdentityDbContext
类也在 Microsoft.AspNet.Identity.EntityFramework 命名空间中,我们可以指定它应该存储的用户类型。这样,我们添加到 User
类的任何其他字段都会进入数据库。
IdentityDbContext
带来了额外的 DbSet,不仅用于存储用户,还用于存储有关用户角色和用户声明的信息。- 我们的
User
类现在准备好了。我们的 MyCoreWebDbContext 类被配置为使用 Identity 框架。 - 现在,我们可以进入
Configure
和ConfigureServices
来设置 Identity 框架。
步骤 4:现在让我们从 ConfigureServices
开始。除了 MVC 服务和 Entity Framework 服务之外,我们还需要添加 Identity 服务。这将添加 Identity 框架工作所依赖的所有服务。
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddDbContext<MyCoreWebDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<User, IdentityRole>()
.AddEntityFrameworkStores<MyCoreWebDbContext>();
services.AddRazorPages();
}
AddIdentity
方法采用两个通用类型参数——用户实体的类型和角色实体的类型。- 两个通用类型参数是我们的用户类型——我们刚刚创建的
user
类和我们要使用的Role
类。现在我们将使用内置的IdentityRole
。此类位于 EntityFramework 命名空间中。 - 当我们使用带有标识的 Entity Framework 时,我们还需要调用第二个方法——
AddEntityFrameworkStores
。 AddEntityFrameworkStores
方法将配置UserStore
等服务,该服务用于创建用户并验证其密码。
步骤 5:下面两行是我们为应用程序配置服务所需的全部内容。
services.AddIdentity<User, IdentityRole>()
.AddEntityFrameworkStores<MyCoreWebDbContext>();
步骤 6:我们还需要添加中间件。我们插入中间件的位置很重要,因为如果我们在管道中插入中间件太晚,它将永远没有机会处理请求。
如果我们需要在 MVC 控制器内部进行授权检查,我们需要在 MVC 框架之前插入 Identity 中间件,以确保 cookie 和 401 错误都得到成功处理。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
步骤 7:插入中间件的位置是添加 Identity 中间件的地方。以下是 Startup.cs 文件的完整代码:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using MyCoreWeb.Models;
namespace MyCoreWeb
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddDbContext<MyCoreWebDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<User, IdentityRole>()
.AddEntityFrameworkStores<MyCoreWebDbContext>();
services.AddRazorPages();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapRazorPages();
});
}
}
}
现在让我们继续构建应用程序。在下一章中,我们需要添加另一个 Entity Framework 迁移,以确保 SQL Server 数据库中有 Identity 模式。