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

在本章,我们将学习如何定制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. 第七十八篇:写一个按需展示的文本框和按钮(使用ref)

    好家伙, 我们又又又来了一个客户 用户说: 我想我的页面上有一个搜索框, 当我不需要他的时候,它就是一个按钮 当我想要搜索的时候,我就点一下它, 然后按钮消失,搜索框出现, 当我在浏览其他东西时,这个 ...

  2. C语言怎么给函数添加形参的默认值

    以下内容为本人的著作,如需要转载,请声明原文链接微信公众号「englyf」https://www.cnblogs.com/englyf/p/16637890.html 如果不是机缘巧合,当年转到C++ ...

  3. KingbaseES V8R6 vacuum index_cleanup 选项

    描述: 由于索引页的复用不像HEAP TABLE的PAGE复用机制那么简单只要有空闲空间就可以插入.索引页的空闲空间被复用,必须是PAGE的边界内的值才允许插入. 因此索引一旦膨胀,很难收缩,常用的方 ...

  4. EFK-2:ElasticSearch高性能高可用架构

    转载自:https://mp.weixin.qq.com/s?__biz=MzUyNzk0NTI4MQ==&mid=2247483811&idx=1&sn=a413dea65f ...

  5. kvm里的虚拟机硬盘和网卡使用virtio驱动

    1.首先从虚拟机的xml文件中找到已经使用virtio驱动的硬件,复制里面的address这行参数出来 <address type='pci' domain='0x0000' bus='0x00 ...

  6. Elasticsearch基础但非常有用的功能之二:模板

    文章转载自: https://mp.weixin.qq.com/s?__biz=MzI2NDY1MTA3OQ==&mid=2247484584&idx=1&sn=accfb65 ...

  7. css 悬停图片改变图片的样式

    <style> #div{ text-align: center; } .img{ width: 200px; clip-path: polygon(50% 0,100% 50%,50% ...

  8. Redis实现布隆过滤器解析

    布隆过滤器原理介绍 [1]概念说明 1)布隆过滤器(Bloom Filter)是1970年由布隆提出的.它实际上是一个很长的二进制向量和一系列随机映射函数.布隆过滤器可以用于检索一个元素是否在一个集合 ...

  9. 这些不知道,别说你熟悉 Spring

    大家好,这篇文章跟大家来聊下 Spring 中提供的常用扩展点.Spring SPI 机制.以及 SpringBoot 自动装配原理,重点介绍下 Spring 基于这些扩展点怎么跟配置中心(Apoll ...

  10. Period of an Infinite Binary Expansion 题解

    Solution 简单写一下思考过程,比较水的数论题 第一个答案几乎已经是可以背下来的,在此不再赘述 考虑我们已经知道了\((p,q)\),其中\((p \perp q) \wedge (q \per ...