ASP.NET Core – 身份配置
ASP.NET Core – 身份配置
在本章中,我们将安装和配置 Identity 框架,这需要一些工作。如果您转到 Visual Studio 并创建一个新的 ASP.NET Core 应用程序,并选择将身份验证设置为单个用户帐户的完整 Web 应用程序模板,则该新项目将包含为您设置的 Identity 框架的所有部分。
我们从一个空项目开始。我们现在将从头开始设置 Identity 框架,这是了解完整应用程序模板中所有部分的好方法,因为如果您没有详细了解所有代码,可能会感到困惑。
首先,我们需要安装依赖项,即Microsoft.AspNet.Identity。我们将继续安装Microsoft.AspNet.Identity.EntityFramework,然后实现与实体框架配合使用的 Identity 框架。
-
如果我们依赖 Identity.EntityFramework,则该包包含 Identity 包。
-
如果您构建自己的数据存储,则只需使用 Identity 包即可。
-
安装依赖项后,我们可以创建一个客户 User 类,其中包含我们要存储的有关用户的所有信息。
-
对于这个应用程序,我们将继承 Identity 框架提供的一个类,该类将为我们提供所有基本要素,如 Username 属性和存储散列密码的位置。
-
我们还需要修改FirstAppDemoDbContext类以从 Identity 框架的IdentityDb类继承。
-
IdentityDb 为我们提供了使用实体框架存储为用户信息所需的一切。一旦我们设置了 User 类和DBContext,我们就需要使用 Startup 类的ConfigureServices方法将 Identity 服务配置到应用程序中。
-
就像我们需要添加服务来支持 MVC 框架一样,Identity 框架需要将服务添加到应用程序中才能工作。
-
这些服务包括像服务UserStore服务和SignInManager。
-
我们会将这些服务注入到我们的控制器中,以在适当的时候创建用户并发布 cookie。
-
最后,在启动的Configure方法中,我们需要添加Identity中间件。
-
该中间件不仅有助于将 cookie 转换为用户身份,还可以确保用户不会看到带有 401 响应的空白页面。
现在让我们按照下面给出的步骤进行操作。
步骤 1 – 我们需要通过添加对身份框架的依赖来继续。让我们将 Microsoft.AspNet.Identity.EntityFramework 依赖项添加到 project.json 文件中。这将包括我们需要的所有其他必要的身份包。
{ "version": "1.0.0-*", "compilationOptions": { "emitEntryPoint": true }, "dependencies": { "Microsoft.AspNet.Mvc": "6.0.0-rc1-final", "Microsoft.AspNet.Diagnostics": "1.0.0-rc1-final", "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final", "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final", "Microsoft.AspNet.StaticFiles": "1.0.0-rc1-final", "EntityFramework.MicrosoftSqlServer": "7.0.0-rc1-final", "EntityFramework.Commands": "7.0.0-rc1-final", "Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-rc1-final", "Microsoft.AspNet.Identity.EntityFramework": "3.0.0-rc1-final" }, "commands": { "web": "Microsoft.AspNet.Server.Kestrel", "ef": "EntityFramework.Commands" }, "frameworks": { "dnx451": { }, "dnxcore50": { } }, "exclude": [ "wwwroot", "node_modules" ], "publishExclude": [ "**.user", "**.vspscc" ] }
步骤 2 – 保存此文件。Visual Studio 恢复包,现在,我们可以添加我们的 User 类。让我们通过右键单击 Models 文件夹并选择 Add → Class 添加 User 类。
调用此类 User 并单击上面的屏幕截图中的 Add 按钮。在这个类中,您可以添加属性来保存您想要存储的关于用户的任何信息。
第 3 步– 让我们从 Identity 框架提供的类派生 User 类。它是 Identity.EntityFramework 命名空间中的 IdentityUser 类。
using Microsoft.AspNet.Identity.EntityFramework; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace FirstAppDemo.Models { public class User : IdentityUser { } }
第 4 步– 现在让我们转到 IdentityUser,将光标放在该符号上,然后按 F12 以查看 Visual Studio 的元数据视图。
#region Assembly Microsoft.AspNet.Identity.EntityFramework, Version = 3.0.0.0, namespace Microsoft.AspNet.Identity.EntityFramework { public class IdentityUser : IdentityUser<string> { public IdentityUser(); public IdentityUser(string userName); } }
第 5 步– 您可以看到 IdentityUser 派生自字符串的 IdentityUser。您可以通过从 IdentityUser 派生并指定我们的泛型类型参数来更改主键的类型。您还可以使用理想情况下是整数值的主键来存储内容。
第 6 步– 现在让我们将光标放在字符串的 IdentityUser 上,然后再次按 F12 转到元数据视图。
默认情况下,您现在可以查看与用户相关的所有信息。信息包括以下内容 –
-
我们不会在此应用程序中使用但可以使用的字段。
-
身份框架可以跟踪特定用户的失败登录尝试次数,并可以在一段时间内锁定该帐户。
-
用于存储 PasswordHash 和 PhoneNumber 的字段。我们将使用的两个重要字段是 PasswordHash 和 UserName。
-
我们还将隐式使用用户的主键和 ID 属性。如果您需要查询特定用户,也可以使用该属性。
第 7 步– 现在,我们需要确保用户包含在我们的 DBContext 中。因此,让我们打开应用程序中的FirstAppDemoDBContext,而不是直接从 DBContext(内置 Entity Framework 基类)派生,现在需要从 IdentityDbContext 派生。
using Microsoft.AspNet.Identity.EntityFramework; using Microsoft.Data.Entity; namespace FirstAppDemo.Models { public class FirstAppDemoDbContext : IdentityDbContext<User> { public DbSet<Employee> Employees { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer("Data Source = (localdb)\\MSSQLLocalDB; Initial Catalog = FirstAppDemo;Integrated Security = True; Connect Timeout = 30;Encrypt = False;TrustServerCertificate = True; ApplicationIntent = ReadWrite;MultiSubnetFailover = False"); } } }
第 8 步– IdentityDbContext 类也在 Microsoft.AspNet.Identity.EntityFramework 命名空间中,我们可以指定它应该存储的用户类型。这样,我们添加到 User 类的任何其他字段都会进入数据库。
-
IdentityDbContext 带来了额外的 DbSet,不仅可以存储用户,还可以存储有关用户角色和用户声明的信息。
-
我们的 User 类现在准备好了。我们的 FirstAppDemoDbContext 类被配置为使用 Identity 框架。
-
我们现在可以进入 Configure 和 ConfigureServices 来设置 Identity 框架。
第 9 步– 现在让我们从ConfigureServices开始。除了我们的 MVC 服务和我们的实体框架服务,我们还需要添加我们的身份服务。这将添加身份框架依赖于完成其工作的所有服务。
public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddEntityFramework() .AddSqlServer() .AddDbContext<FirstAppDemoDbContext> (option => option.UseSqlServer(Configuration["database:connection"])); services.AddIdentity<User, IdentityRole>() .AddEntityFrameworkStores<FirstAppDemoDbContext>(); }
-
AddIdentity 方法采用两个泛型类型参数——用户实体的类型和角色实体的类型。
-
两个泛型类型参数是我们用户的类型——我们刚刚创建的 User 类和我们想要使用的 Role 类。我们现在将使用内置的 IdentityRole。此类位于 EntityFramework 命名空间中。
-
当我们使用带有 Identity 的实体框架时,我们还需要调用第二种方法 – AddEntityFrameworkStores。
-
AddEntityFrameworkStores 方法将配置像 UserStore 这样的服务,该服务用于创建用户和验证他们的密码。
步骤 10 – 以下两行是我们为应用程序配置服务所需的全部内容。
services.AddIdentity<User, IdentityRole>() .AddEntityFrameworkStores<FirstAppDemoDbContext>();
步骤 11 – 我们还需要添加中间件。我们插入中间件的位置很重要,因为如果我们在管道中插入中间件太晚,它将永远没有机会处理请求。
如果我们需要在 MVC 控制器内部进行授权检查,我们需要在 MVC 框架之前插入 Identity 中间件,以确保 cookie 和 401 错误得到成功处理。
public void Configure(IApplicationBuilder app) { app.UseIISPlatformHandler(); app.UseDeveloperExceptionPage(); app.UseRuntimeInfoPage(); app.UseFileServer(); app.UseIdentity(); app.UseMvc(ConfigureRoute); app.Run(async (context) => { var msg = Configuration["message"]; await context.Response.WriteAsync(msg); }); }
步骤 12 – 我们插入中间件的位置是我们将添加身份中间件的位置。下面是Startup.cs文件的完整实现。
using Microsoft.AspNet.Builder; using Microsoft.AspNet.Hosting; using Microsoft.AspNet.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Configuration; using FirstAppDemo.Services; using Microsoft.AspNet.Routing; using System; using FirstAppDemo.Entities; using Microsoft.Data.Entity; using FirstAppDemo.Models; using Microsoft.AspNet.Identity.EntityFramework; namespace FirstAppDemo { public class Startup { public Startup() { var builder = new ConfigurationBuilder() .AddJsonFile("AppSettings.json"); Configuration = builder.Build(); } public IConfiguration Configuration { get; set; } // This method gets called by the runtime. // Use this method to add services to the container. // For more information on how to configure your application, // visit http://go.microsoft.com/fwlink/?LinkID = 398940 public void ConfigureServices(IServiceCollection services) { services.AddMvc(); services.AddEntityFramework() .AddSqlServer() .AddDbContext<FirstAppDemoDbContext>(option => option.UseSqlServer(Configuration["database:connection"])); services.AddIdentity<User, IdentityRole>() .AddEntityFrameworkStores<FirstAppDemoDbContext>(); } // This method gets called by the runtime. // Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app) { app.UseIISPlatformHandler(); app.UseDeveloperExceptionPage(); app.UseRuntimeInfoPage(); app.UseFileServer(); app.UseIdentity(); app.UseMvc(ConfigureRoute); app.Run(async (context) => { var msg = Configuration["message"]; await context.Response.WriteAsync(msg); }); } private void ConfigureRoute(IRouteBuilder routeBuilder) { //Home/Index routeBuilder.MapRoute("Default", "{controller=Home}/{action=Index}/{id?}"); } // Entry point for the application. public static void Main(string[] args) => WebApplication.Run<Startup>(args); } }
第 13 步– 现在让我们继续构建应用程序。在下一章中,我们需要添加另一个实体框架迁移,以确保我们的 SQL Server 数据库中有 Identity 架构。