大家好,我是张飞洪,感谢您的阅读,我会不定期和你分享学习心得,希望我的文章能成为你成长路上的垫脚石,让我们一起精进。

在本章,我们将学习如何定制ASP.NET Core认证机制。微软把安全认证当做ASP.NET Core框架的一部分,足以看见它是应用程序非常最重要的内容。在文将介绍如何定制ASP.NET Core认证UI的基本实现,以及如何向IdentityUser添加自定义信息。我们将介绍以下几点:

  • 介绍ASP.NET Core身份认证
  • 自定义IdentityUser
  • 自定义Identity视图(views)
  • 该主题所属ASP.NET Core架构的MVC层:

技术准备

创建一个ASP.NET Core应用程序并用VS Code打开:

dotnet new mvc -n AuthSample -o AuthSample --auth Individual
cd AuthSample
code .

ASP.NET Core身份认证介绍

用户身份是表示用户对象,也可以是用户组。通过它我们可以了解用户及其所属的权限。可以给身份或者叫用户分配包含权限的角色。例如,可以给一个名为仓库管理员的角色只分配写入的权限。用户身份也可以嵌套。一个用户可以是一个组的一部分,一个组可以是另一个组的一部分,依此类推。

ASP.NET Core Identity是一个框架,它在.NET中用来存储和读取用户信息。该框架还提供了添加登录表单、注册表单、会话处理等机制。它还提供以加密和安全的方式存储凭据。ASP.NET Core Identity还提供了多种验证用户身份的方法:

  • Individual(个人):应用程序自行管理身份。它有一个存储用户信息的数据库,并自行管理登录、注销、注册等。
  • IndividualB2C:自行管理用户数据,但从Azure B2C获取数据。
  • SingleOrg:身份由Azure Active Directory(AD)管理;登录、注销等等都是由Azure AD完成的。应用程序只需从web服务器获取一个随时可用的身份。
  • 多组织:与上一个相同,但为多个Azure AD组织启用。
  • Windows:经典的Windows身份验证,仅当应用程序由IIS托管时才可用。用户还可以从web服务器获得一个随时可用的身份。
  • 本文不是关于不同的身份验证方法,因为这个主题太大了。

上面命令行里的--auth标志设置为Individual,用于启用个人身份验证,并创建ASP.NET Core MVC应用程序。这意味着它附带了一个数据库来存储用户。--auth标志会添加所有相关的代码和依赖项。

--auth标志创建了一个名为Identity的区域,其中包含_ViewStart.cshtml文件,它引用新项目的_Layout.cshtml文件。实际的登录或注册界面在引用此项目的类库中提供。

该案例项目包含一个Data文件夹,其中包含EF Core的DbContext,以及用于创建和更新的数据库迁移。

除了Program.cs外,所有其他部分常规MVC应用完全相同。

如果您使用.NET CLI创建了应用程序,默认则会使用SQLite数据库。如果使用Visual Studio创建此应用程序,则会使用SQL Server存储用户数据。

在启动应用程序之前,在终端中调用以下命令创建和更新数据库:

dotnet ef database update

如果不起作用,您可能需要首先在.NET CLI中安装实体框架工具:

dotnet tool install -g dotnet-ef

然后执行:

dotnet watch

应用程序现在将在监视模式下启动,并启用热重新加载。它还将打开浏览器窗口并调用应用程序:

如您所见,右上方有一个菜单,其中包含此应用程序的“注册”和“登录”选项。单击登录链接可进入以下登录屏幕:



如上所述,该视图来自一个已编译的Razor库,它为Identity区域提供了必要的视图。我们会自动从框架中获取此UI。

最后,我们快速了解一下Program.cs,这也与我们在上一章中看到的文件不同。

在注册服务的上部,有几行代码用于注册DbContext以及数据库异常页:

var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options => options.UseSqlite(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true) .AddEntityFrameworkStores<ApplicationDbContext>();

还有添加身份认证的EntityFramework Core的注册。它被配置为只允许确认的帐户,这意味着:作为用户需要确认电子邮件才能登录。

在中间件的下部,我们看到使用了身份验证和授权:

app.UseAuthentication();
app.UseAuthorization();

身份验证通过读取身份验证cookie来识别用户,它还将所有相关信息添加到Identity对象。

我们可能还需要通过向用户添加更多属性来扩展用户配置文件。我们在下面介绍如何做到这一点。

自定义IdentityUser

IdentityUser具有以下字段:Id、用户名、密码、电子邮件和电话号码。

由于显示名称可能与用户名不同,我们会添加Name属性,另外,假设我们想向用户发送生日祝福,我们应该如何扩展他们的出生日期呢?

为此,需要添加一个名为WebAppUser.cs的文件到Data文件夹中:

using Microsoft.AspNetCore.Identity;
namespace AuthSample.Data;
public class WebAppUser : IdentityUser {
[PersonalData]
public string? Name { get; set; }
[PersonalData]
public DateTime DOB { get; set; }
}

如上所示,WebAppUser.cs派生自IdentityUser,并扩展两个属性。

在Program.cs,我们需要修改服务注册以使用新的WebAppUser:

builder.Services.AddDefaultIdentity<WebAppUser>

我们还需要更改DbContext,使用WebAppUser:

public class ApplicationDbContext :  IdentityDbContext<WebAppUser, IdentityRole, string>

您还需要将using语句添加到Microsoft.AspNetCore.Identity中。这是第一步。我们现在需要更新数据库:

dotnet ef migrations add CustomUserData
dotnet ef database update

一旦使用自定义属性扩展了IdentityUser,就可以在在ASP.NET Core Identity U的用户配置文件中使用它。

自定义Identity视图(views)

ASP.NET Core Identity视图来自编译的Razor库,我们应该如何自定义呢?

我们只需要在Area内的预定义文件夹结构中用自定义视图覆盖给定视图即可。前提是我们需要先创建一个自定义视图,添加扩展字段或更改布局。

如前所述,项目中已经有一个名为Identity的Area,内有一个Pages文件夹。在这里,我们需要创建一个名为Account的新文件夹,然后放置一个名为“注册”的新Register.cshtml页面在这个文件夹中,并将以下内容放在里面,以查看视图的覆盖是否有效:

@page @{ } <h1>Hello Register Form</h1>

运行应用程序并单击左上角的注册,您将看到以下页面:



实际上,我们不需要自己覆盖视图。有一个代码生成器可用于构建您想要覆盖的视图。

通过调用以下命令安装代码生成器:

dotnet tool install -g dotnet-aspnet-codegenerator

如果尚未完成,您还需要在项目中安装以下软件包:

dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design
dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Microsoft.AspNetCore.Identity.EntityFrameworkCore
dotnet add package Microsoft.AspNetCore.Identity.UI
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Tools

要了解代码生成器可以做什么,请运行以下命令:

dotnet aspnet-codegenerator identity -h

第一个更改是让用户在注册页面上填写name属性,我们先构建注册页面:

dotnet aspnet-codegenerator identity -dc AuthSample.Data.ApplicationDbContext --files "Account.Register" -sqlite

此命令告诉代码生成器使用现有的ApplicationDbContext和Sqlite。如果不指定此项,它将创建一个新的DbContext或注册现有的DbContext,以便与SQLServer而不是SQLite一起使用。

如果一切都OK了,代码生成器应该只添加Register.cshtml页面以及一些基础结构文件:



代码生成器还会知道项目正在使用自定义WebAppUser而不是IdentityUser,这意味着在生成的代码中使用了WebAppUser。

现在,我们更改一下Register.cshtml,将显示名称添加到表单中。在第15行电子邮件字段的表单元素之前添加以下行:

<div class="form-floating">
<input asp-for="Input.Name" class="form-control" autocomplete="name" aria-required="true" />
<label asp-for="Input.Name"></label>
<span asp-validation-for="Input.Name" class="text-danger"></span>
</div>

此外,Regiser.cshtml.cs需要更改。ImportModel类需要Name属性:

public class InputModel {
[Required]
[Display(Name = "Display name")]
public string Name { get; set; }

在PostAsync方法中,将Name属性分配给新创建的用户:

var user = CreateUser();
user.Name = Input.Name;

启动申请后,您将看到以下注册表格:



由于用户可能需要更新名称,我们还需要更改配置文件页面上的视图。这里还需要添加出生日期:

dotnet aspnet-codegenerator identity -dc AuthSample.Data.ApplicationDbContext --files "Account.Manage.Index" -sqlite

打开新创建的Index.chtml.cs,并将以下属性放在InputModel类中:

public class InputModel {
[Required]
[Display(Name = "Display name")]
public string Name { get; set; }
[Display(Name = "Date of birth")]
public DateTime DOB { get; set; }
}

现在可以在相应的Index.chtml中使用这些属性。下面代码片段需要放在验证和用户名之间:

<div class="form-floating">
<input asp-for="Input.Name" class="form-control" autocomplete="name" aria-required="true" />
<label asp-for="Input.Name"></label>
<span asp-validation-for="Input.Name" class="text-danger">
</span>
</div>
<div class="form-floating">
<input asp-for="Input.DOB" class="form-control" type="date"/>
<label asp-for="Input.DOB" class="form-label"></label>
</div>

最后,还需要一些更改才能用保存的数据填充表单。在LoadAsync方法中,需要使用新属性扩展InputModel的实例化:

Input = new InputModel {
PhoneNumber = phoneNumber,
Name = user.Name,
DOB = user.DOB
};

用户保存表单时,还需要保存更改的值。将下一个代码段放在OnPostAsync方法中:

user.Name = Input.Name;
user.DOB = Input.DOB;
await _userManager.UpdateAsync(user);

将InputModel的值设置为WebAppUser属性,并将更改保存在数据库中。

我们在终端中调用dotnet watch来尝试一下。

Profile页面现在看起来类似于:

您现在可以更改显示名称并添加出生日期。如果用户填写了显示名称,他们可能会在登录后在左上角显示。

打开Views/Shared文件夹的_LoginPartial.cshtml,并将前四行替换为以下代码段:

@using Microsoft.AspNetCore.Identity
@using AuthSample.Data
@inject SignInManager<WebAppUser> SignInManager
@inject UserManager<WebAppUser> UserManager
@{ var user = await @UserManager.GetUserAsync(User); }

做using部分,将SignInManager和UserManager的泛型参数从IdentityUser类型更改为WebAppUser。

在代码块部分,通过传入当前用户,通过UserManager加载当前WebAppUser。

现在,需要更改用户名的输出以写入显示名称:

Hello @user?.Name!

当dotnet watch仍在运行时,浏览器中运行的应用程序应该已经更新。也许你需要重新登录。现在,您应该会在右上角看到显示名称:

总结

在本章中,我们学习了如何扩展ASP.NET Core Identity,通过添加其他属性来增强用户对象。我们还学习了如何增强Identity UI以加载、保存和更新新用户属性的值。

但是,应该如何管理应用程序用户的角色?我们将在下一章中学习的关于配置身份管理的内容。

定制ASP.NET Core的身份认证的更多相关文章

  1. ASP.NET Core的身份认证框架IdentityServer4--入门

    ASP.NET Core的身份认证框架IdentityServer4--入门 2018年08月11日 10:09:00 qq_42606051 阅读数 4002   https://blog.csdn ...

  2. ASP.NET Core的身份认证框架IdentityServer4(7)- 使用客户端证书控制API访问

    前言 今天(2017-9-8,写于9.8,今天才发布)一口气连续把最后几篇IdentityServer4相关理论全部翻译完了,终于可以进入写代码的过程了,比较累.目前官方的文档和Demo以及一些相关组 ...

  3. ASP.NET Core的身份认证框架IdentityServer4(1)-特性一览

    IdentityServer4是ASP.NET Core的一个包含OpenID和OAuth 2.0协议的框架.OpenID和OAuth 的区别请看 https://www.zhihu.com/ques ...

  4. ASP.NET Core的身份认证框架IdentityServer4(9)-使用OpenID Connect添加用户认证

    OpenID Connect OpenID Connect 1.0是OAuth 2.0协议之上的一个简单的身份层. 它允许客户端基于授权服务器执行的身份验证来验证最终用户的身份,以及以可互操作和类似R ...

  5. ASP.NET Core的身份认证框架IdentityServer4--(4)添加第三方快捷登录

    添加对外部认证的支持 接下来我们将添加对外部认证的支持.这非常简单,因为你真正需要的是一个兼容ASP.NET Core的认证处理程序. ASP.NET Core本身也支持Google,Facebook ...

  6. ASP.NET Core的身份认证框架IdentityServer4--(2)API跟WEB端配置

    API配置 可以使用ASP.NET Core Web API模板.同样,我们建议您控制端口并使用与之前一样的方法来配置Kestrel和启动配置文件.端口配置为http://localhost:5001 ...

  7. ASP.NET Core的身份认证框架IdentityServer4--(1)服务配置

    官网文档地址:点我点我 准备 创建一个名为IdentityServer的ASP.NET Core Web Api 项目,端口5000 创建一个名为Api的ASP.NET Core Web Api 项目 ...

  8. ASP.NET Core的身份认证框架IdentityServer4--入门【转】

    原文地址 Identity Server 4是IdentityServer的最新版本,它是流行的OpenID Connect和OAuth Framework for .NET,为ASP.NET Cor ...

  9. ASP.NET Core的身份认证框架IdentityServer4(6)- 开始

    安装和概述 启动一个新的IdentityServer项目有两种基本方法: 从头开始 从Visual Studio中的ASP.NET身份模板开始 如果从头开始,我们提供了一些文档.项目帮助和内存存储支持 ...

  10. ASP.NET Core的身份认证框架IdentityServer4(5)- 包和构建

    包和构建 IdentityServer有许多nuget包 IdentityServer4 nuget | github 包含IdentityServer核心对象模型,服务和中间件. 仅支持内存配置和用 ...

随机推荐

  1. SpringMVC 03: 请求和响应的乱码解决 + SpringMVC响应Ajax请求

    请求或响应的中文乱码问题 tomcat9解决了get请求和响应的中文乱码问题,但是没有解决post请求或响应的中文乱码问题 tomcat10解决了get和post请求以及响应的中文乱码问题 考虑到实际 ...

  2. ABC266.

    D 设 \(f_{t,p}\) 代表在 \(t\) 时间点时人在 \(p\) 点的最大收益,在这一步他可以 \(p\) 增加,不动,\(p\) 减少.于是得出状态转移方程:\(f_{t,p} = \m ...

  3. JavaWeb核心篇(2)——Request和Response

    JavaWeb核心篇(2)--Request和Response 上篇文章中提及到了Servlet,在Servlet中我们主要继承了HTTPServlet类,在HTTPServlet类中我们会接触到两个 ...

  4. Java 多线程:线程池

    Java 多线程:线程池 作者:Grey 原文地址: 博客园:Java 多线程:线程池 CSDN:Java 多线程:线程池 工作原理 线程池内部是通过队列结合线程实现的,当我们利用线程池执行任务时: ...

  5. 在安装Windows时手动创建分区

    目前硬件都已经支持UEFI模式启动了,而且硬盘容量普遍大于MBR磁盘能支持的最大2TB的容量.所以在安装Windows系统的时候优先选用UEFI启用,并将磁盘配置为GPT模式以支持更大的容量.而且Wi ...

  6. Activiti 7 源码学习

    1.  启动分析 源码是 7.1.0.M6 首先从 ProcessEngineAutoConfiguration 开始 ProcessEngineAutoConfiguration 是activiti ...

  7. 第六章:Django 综合篇 - 13:发送邮件

    在Python中已经内置了一个smtp邮件发送模块,Django在此基础上进行了简单地封装,让我们在Django环境中可以更方便更灵活的发送邮件. 所有的功能都在django.core.mail中. ...

  8. 4.第三篇 PKI基础概念、cfssl工具介绍及kubernetes中证书

    文章转载自:https://mp.weixin.qq.com/s?__biz=MzI1MDgwNzQ1MQ==&mid=2247483787&idx=1&sn=08dd3404 ...

  9. POJ3311 Hie with the Pie(状压DP,Tsp)

    本题是经典的Tsp问题的变形,Tsp问题就是要求从起点出发经过每个节点一次再回到起点的距离最小值,本题的区别就是可以经过一个节点不止一次,那么先预处理出任意两点之间的最短距离就行了,因为再多走只会浪费 ...

  10. UVA12186 工人的请愿书 Another Crisis (树形DP)

    dp[i]表示要让i向上级发请愿书,最少需要多少个工人递交请愿书,因为要取前T%最小的,所以还要将i的子节点排序(这里用vector实现),取前c个最小的作为dp[i]的值. 这里用dfs可以省去dp ...