目录
介绍
文章系列
安装ASP.NET Core Identity
配置ASP.NET Core Identity
管理用户数据
使用Microsoft帐户,Google,Facebook等登录
结论
下载Part03.zip
介绍
文章系列
- ASP.NET核心之路微服务第01部分:构建视图
- ASP.NET核心之路微服务第02部分:查看组件
- ASP.NET核心之路微服务第03部分:ASP.NET核心身份
- 第04部分:SQLite
- 第05部分:Dapper
- 第06部分:SignalR
- 第07部分:单元测试Web API
- 第08部分:单元测试Web MVC应用程序
- 第09部分:监测健康检查
- 第10部分:Redis数据库
- 第11部分:IdentityServer4
- 第12部分:订购Web API
- 第13部分:Basket Web API
- 第14部分:Catalog Web API
- 第15部分:具有Polly的弹性HTTP客户端
- 第16部分:使用Swagger记录Web API
- 第17部分:Docker容器
- 第18部分:Docker配置
- 第19部分:使用Kibana进行中心日志
在这一系列文章的第2部分结尾处,我们有一个电子商务应用程序,其中包含用户可以从catalog中选择产品,将其放入购物篮并填写带有地址和其他个人数据的注册表单,用于将来的购物过程。当然,所有这些都是使用虚拟数据制作的。
我们的应用程序目前不需要用户登录或任何类型的密码。越来越多的电子商务网站也选择不要求此类信息,仅在结账页面要求客户的信用卡或其他付款方式。另一方面,许多电子商务网站需要登录和密码来验证用户。
两种模式都有优点和缺点。用用户体验的说法,一个不需要认证的电子商务网站对客户来说更方便,因为它减少了可能损害转换的摩擦。另一方面,身份验证使您能够识别用户并可能更好地分析他们的行为,并允许您为用户提供某些好处,例如显示先前在网站上购买的客户的订单历史记录。在本文中,我们将遵循第二种方法。
在本系列文章的第三部分中,我们将使用登录系统并确保只有经过身份验证的用户才能访问我们的应用程序。它允许您保护应用程序的敏感点免受匿名用户的攻击。通过身份验证,我们确保用户通过安全身份识别服务进入系统。这还使应用程序能够跟踪用户访问,识别使用模式,自动填写注册表单,查看客户订单历史记录和其他便利,从而增强用户体验。
如果您只需要一个包含登录名和密码列以及应用程序用户配置文件的用户表,那么ASP.NET Core Identity是您的最佳选择。
在本章中,我们将学习如何在我们的电子商务解决方案中安装ASP.NET Core Identity,并利用此框架提供的安全性,登录/注销,身份验证和用户配置文件功能。
默认情况下,Identity使用的数据库引擎是SQL Server。但是,我们将使用SQLite,这是一个比SQL Server更简单,更紧凑的数据库引擎。在安装Identity之前,我们将准备项目以使用这个新的数据库引擎。
右键单击MVC项目名称,选择Add NuGet Package子菜单,打开包安装页面,输入包名称: Microsoft.EntityFrameworkCore.SQLite
图片:项目上下文菜单
图片:添加Microsoft.EntityFrameworkCore.Sqlite包
现在单击“安装”按钮并等待安装包。
好的,现在该项目已准备好接收ASP.NET Core Identity脚手架。
安装ASP.NET Core Identity应用ASP.NET Core Identity脚手架
从头开始安装具有Identity的新ASP.NET Core与在现有项目中安装它不同。由于我们的项目没有Identity,我们将安装包含我们需要的功能的文件和程序集包。该过程类似于使用预制模块在建筑工地中建造墙壁。这个过程称为脚手架。
如果我们必须在我们的应用程序中手动创建登录/注销,身份验证和其他功能,则需要付出很多努力。我们正在讨论视图,业务逻辑,模型实体,数据访问,安全性等的开发,以及数小时的单元测试,功能测试,集成测试等。
幸运的是,我们的应用程序可以轻松地从身份验证和授权功能中受益。身份验证和授权在Web应用程序中无处不在。因此,Microsoft提供了一个可以透明地安装在缺少此类功能的ASP.NET Core项目中的软件包。它被称为ASP.NET Core Identity。
要在我们的解决方案中应用ASP.NET Core Identity,我们右键单击该项目,单击Add Scaffolded Item,然后选择Add选项。这将打开一个新的Add Scaffold对话框窗口。
图片:项目上下文菜单
在这里,我们将选择 Installed> Identity> Identity。
图片:添加脚手架对话框
ASP.NET Core Identity Scaffold将打开一个包含一系列配置参数的新对话窗口。在那里,您可以定义页面的布局,要包含的源代码,数据和用户上下文类,以及Identity将使用的数据库类型(SQL Server或SQLite)。
图片:添加标识对话框
我们选择以下选项:
- Layout:我们项目中已存在的_Layout.cshtml文件。它将定义一个基本标记,由Identity页面和我们的应用程序的其余部分共享。
- Identity pages:登录,注销,注册,外部登录。脚手架过程会将这些页面复制到我们的应用程序,您可以在其中编辑它们。请注意,您仍然可以导航到未标记的其他标识页,但您无法修改或自定义它们,因为它们不会出现在项目中。
- Context class:AppIdentityContext。
- User class:AppIdentityUser。表示identity 系统中的用户
确认这些参数后,脚手架将修改我们的项目。最值得注意的变化是 我们项目的Areas / Identity文件夹下的新文件结构 。
图片:Areas/Identity项目文件夹
观察Areas 文件夹下的新结构:
- AppIdentityContext类:这是用于ASP.NET Core Identity的实体框架数据库上下文的类。
- AppIdentityUser类:代表identity 系统中的用户。
- 在Pages / Account下面的页面:这些是包含Identity 网页上的标记代码页。它们是Razor Pages,即一种MVC结构类型,其中视图位于文件中,控制器和模板的操作位于单个文件中。正如我们所说,这些页面可以在我们的应用程序中进行修改和自定义,但其他Identity 页面可以访问,但不能更改,因为它们的文件不在项目中。
- 部分视图:_ValidationScriptPartial,_ViewImports,_ViewStart
- IdentityHostingStartup 类:ASP.NET Core WebHost在应用程序运行后立即执行此类。IdentityHostingStartup类配置Identity需要工作的数据库和其他服务。
创建和应用ASP.NET Core Identity 模型迁移
在我们的项目中安装ASP.NET Core Identity包是不够的。我们仍然需要生成数据库架构,其中包括ASP.NET Identity Core所需的表和初始数据。
当我们构建ASP.NET Identity Core的脚手架时,我们可以在IdentityHostingStartup.cs文件类中看到一个新的Identity数据模型自动添加到我们的项目中:
public void Configure(IWebHostBuilder builder)
{
builder.ConfigureServices((context, services) => {
services.AddDbContext(options =>
options.UseSqlite(
context.Configuration.GetConnectionString("AppIdentityContextConnection")));
services.AddDefaultIdentity()
.AddEntityFrameworkStores();
});
}
清单:在IdentityHostingStartup.cs文件中配置Identity
注意上面的Entity Framework配置(AddDbContext方法)是如何使用AppIdentityContext类的,这是我们在脚手架过程中选择的名称。
同样的过程还为appsettings.json配置文件添加了一个新的AppIdentityContextConnection 连接字符串。ASP.NET Core Identity将使用此连接字符串来访问SQLite数据库:
.
.
.
"AllowedHosts": "*",
"ConnectionStrings": {
"AppIdentityContextConnection": "DataSource=MVC.db"
}
清单:在appsettings.json上配置SQLite Connection
但请注意,脚手架过程本身并没有创建Identity SQLite数据库。这可以通过创建新的实体框架迁移来实现。
要添加新迁移,请打开“工具”>“程序包管理器控制台”菜单,然后键入控制台。
PM> Add-Migration Identity
上面的命令添加了包含迁移语句的类,但它没有创建数据库本身:
图片: 迁移项目文件夹
要创建SQLite数据库,必须通过执行以下Update-Database命令来应用迁移:
PM> Update-Database -verbose
此命令创建在appsettings.json配置文件中包含的连接字符串中定义的MVC.db数据库文件:
图片:SQLite数据库文件
现在让我们通过双击它来看看这个文件。这将打开我们在本文开头安装的SQLite应用程序的数据库浏览器:
图片:SQLite工具的数据库浏览器
就这些了!现在,我们的应用程序已具备执行身份验证和授权所需的所有组件。从现在开始,我们将开始使用这些组件在我们的应用程序中集成ASP.NET Core Identity功能。
配置ASP.NET Core Identity将Identity 组件添加到后端
Identity组件已存在于我们的项目中。但是,我们需要添加进一步的配置,将这些组件与应用程序的其余部分集成。
在软件架构中,这被称为中间件。
ASP.NET Core提供了一种标准方法,可将中间件集成到应用程序的正常执行中。这种机制类似于输水管道。每项新服务都进一步扩展了管道系统,将水带到一端,并将其传递到下一段。
图:ASP.NET Core Pipeline
同样,ASP.NET Core将沿着一系列中间件传递请求。收到请求后,每个中间件决定处理它或将请求传递给链中的下一个中间件。如果用户是匿名用户且资源需要授权,则Identity会将用户重定向到登录页面。
脚手架进程创建了IdentityHostingStartup类,该类已经配置了一些Identity服务。
public void Configure(IWebHostBuilder builder)
{
...
services.AddDefaultIdentity()
.AddEntityFrameworkStores();
...
}
清单:IdentityHostingStartup类
AddDefaultIdentity()方法向应用程序添加一组公共identity 服务,包括默认UI,令牌提供程序,以及配置身份验证以使用identity cookie。
通过调用UseAuthentication()扩展方法启用Identity 。此方法将身份验证中间件添加到请求管道:
...
app.UseStaticFiles();
app.UseAuthentication();
...
清单:包括ASP.NET Core管道的Identity
UseAuthentication()方法将身份验证中间件添加到指定的ApplicationBuilder,后者启用身份验证功能。
但是,上面的代码只配置了后端行为。对于前端,您可以通过在布局标记中包含允许用户登录或注册的部分视图,将ASP.NET Core Identity 视图与应用程序用户界面集成。我们来看下一节。
将Identity 组件添加到前端
ASP.NET Core Identity脚手架过程包括在Views\Shared文件夹中的LoginPartial文件。此文件包含部分视图,该部分视图显示经过身份验证的用户的名称或登录和注册的超链接。
图片:_LoginPartial.cshtml部分视图
@using Microsoft.AspNetCore.Identity
@using MVC.Areas.Identity.Data
@inject SignInManager SignInManager
@inject UserManager UserManager
@if (SignInManager.IsSignedIn(User))
{
-
Hello @UserManager.GetUserName(User)!
-
Logout
}
else
{
-
Register
-
Login
}
清单:_LoginPartial.cshtml部分视图
您可以将此组件添加到任何应用程序视图中,如下所示:
但是,多次添加此行会导致不合需要的代码重复。我们可以通过在应用程序(_Layout.cshtml 文件)的标准布局视图中包含上面的行来避免这种冗余,因为这将导致组件通过我们所有的电子商务视图可见。我们需要将它更具体地包括在应用程序的导航栏中,在包含“navbar collapse”类的元素中:
清单:包含在Layout.cshtml页面中的_LoginPartial部分视图
通过运行应用程序,我们现在可以在产品搜索页面的右上角看到注册和登录链接:
现在,我们将点击添加任何产品以导航到购物车页面。请注意登录和注册链接如何在此处出现:
Razor 页面
安装ASP.NET Core Identity脚手架时,项目中包含的新Identity组件不遵循MVC架构。相反,Identity组件基于Razor Pages。
但是MVC和Razor Pages之间的区别是什么?
我们可以从下面的屏幕截图中看到一个典型的MVC项目如何将一个页面的组件保存在一组文件中,这些文件分布在许多文件和文件夹中:
图:MVC项目结构
所以,在MVC中没有一个“网页”文件。向那些对这项技术不熟悉的人解释这个事实有点尴尬。
如果您使用MVC应用程序,然后将视图称为“页面”(例如在Index.cshtml文件中),并且您不仅集中了模型数据,还集中了与该页面相关的服务器端代码(以前驻留在您的Controller上)专用于该页面的类(在Index.cshtml.cs文件中)——您现在称为页面模型?
如果您已经在本机移动应用程序中工作过,那么您可能已经在Model-View-ViewModel(MVVM)模式中看到了类似的内容。
图片:Razor页面组件
尽管与MVC不同,Razor Pages仍然依赖于ASP.NET Core MVC Framework。使用Razor Pages模板创建新项目后,Visual Studio通过Startup.cs文件配置应用程序以启用ASP.NET Core MVC框架,如我们刚才所见。
该模板不仅为MVC使用配置新的Web应用程序,还为示例应用程序创建Page文件夹和一组Razor页面和页面模型:
图片:Razor页面文件
Razor的解剖
乍一看,Razor页面看起来非常像普通的ASP.NET MVC View文件。但Razor Page需要一个新的指令。每个Razor页面都必须以@page指令开头,该指令告诉ASP.NET Core将其视为Razor页面。下图显示了有关典型Razor页面的更多详细信息。
图片:Razor的解剖
- @page——将文件标识为Razor页面。没有它,ASP.NET Core无法访问该页面。
- @model——与MVC应用程序非常相似,它定义了从中生成绑定数据的类,以及页面请求的Get/Post方法。
- @using——定义命名空间的常规指令。
- @inject——配置应将哪个(些)接口实例注入页面模型类。 @ {}——Razor括号内的一段C#代码,在本例中用于定义页面标题。
创建新用户
由于我们创建了一个没有用户的新SQLite数据库,因此我们的客户需要填写Identity的Register页面。以下是Layout.cshtml页面中的_LoginPartial.cshtml部分视图呈现的链接:
现在,让我们创建一个名为alice@smith.com的新客户帐户 。
图片:注册页面
当客户单击“注册”链接时,会将其重定向到/Identity/Account/Register 页面。我们可以看到,ASP.NET Core Identity已经为常见的用户注册问题提供了强大的解决方案。此外,ASP.NET Core Identity页面与我们的电子商务前端无缝集成。
图片:登录页面
ASP.NET Core Identity还提供了需要付出很多努力才能实现的功能,例如“忘记密码?” 和用户锁定(在多次输入错误密码后阻止用户登录时)。
@if (User.Identity.IsAuthenticated)
{
-
Add-Migration UserProfileData
上面的命令创建“UserProfileData”迁移,其中包含添加新用户表字段的迁移语句:

图片:迁移项目文件夹
要创建SQLite数据库,必须通过执行以下Update-Database命令来应用迁移:
PM> Update-Database -verbose
此命令将当前模型与数据库快照进行比较,并将差异应用于数据库中。在我们的示例中,检测到的差异是缺少的用户属性。
从Identity 数据库中检索用户数据

图片:注册页面
填写表单字段总是一项繁琐的工作。但有些情况下无法避免或推迟。想想电子商务网站上的客户信息:如果没有所有正确的数据,则无法计算货物并且无法处理购物情况。但是有一些方法可以减轻客户对此程序的不满。例如,您可以保存客户数据以用于将来的订单。但是我们如何使用ASP.NET Core Identity保存用户数据?
幸运的是,Identity提供了一个名为 UserManager(其中T代表用户类或AppIdentityUser类)的类, 它提供用于管理持久性存储中的用户的API。也就是说,它公开了向数据库保存和检索用户数据所需的功能。
UserManager参数通过依赖注入传递。但不要担心在Startup类上配置它。一旦添加了Identity脚手架, IdentityHostingStartup类已经注册了依赖注入的UserManager 类型。
在RegistrationController中的Index方法中,我们可以看到GetUserAsync()方法如何用于从Identity存储(即SQLite数据库)异步检索当前用户。
[Authorize]
public class RegistrationController : BaseController
{
private readonly UserManager userManager;
public RegistrationController(UserManager userManager)
{
this.userManager = userManager;
}
public async Task Index()
{
var user = await userManager.GetUserAsync(this.User);
var viewModel = new RegistrationViewModel(
user.Id, user.Name, user.Email, user.Phone,
user.Address, user.AdditionalAddress, user.District,
user.City, user.State, user.ZipCode
);
return View(viewModel);
}
}
清单:/MVC/Controllers/RegistrationController.cs文件
之后,我们使用从AspNetUsers表中检索的用户数据填充RegistrationViewModel类。反过来,视图模型被传递到视图中以自动填充第二次客户的注册表单,我们可以在下面的字段中看到。
...
...
...
...
...
...
...
清单:/MVC/Views/Registration/Index.cshtml中的新标记助手
将用户数据保留到Identity 数据库
下面的代码显示了如何操作
- 检查模型是否有效,即是否满足RegistrationViewModel类验证规则。
- 使用GetUserAsync()方法异步检索用户
- 通过应用表单数据修改来自数据库的用户对象
- 使用UpdateAsync()方法更新SQLite数据库
- 如果模型无效,则重定向回注册视图
[Authorize]
public class CheckoutController : BaseController
{
private readonly UserManager userManager;
public CheckoutController(UserManager userManager)
{
this.userManager = userManager;
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task Index(RegistrationViewModel registration)
{
if (ModelState.IsValid)
{
var user = await userManager.GetUserAsync(this.User);
user.Email = registration.Email;
user.Phone = registration.Phone;
user.Name = registration.Name;
user.Address = registration.Address;
user.AdditionalAddress = registration.AdditionalAddress;
user.District = registration.District;
user.City = registration.City;
user.State = registration.State;
user.ZipCode = registration.ZipCode;
await userManager.UpdateAsync(user);
return View(registration);
}
return RedirectToAction("Index", "Registration");
}
}
清单:Part 03 /MVC/Controllers/CheckoutController.cs文件
下订单时,Checkout视图会显示订单确认,并显示网站上的“谢谢”消息。我们再一次为视图绑定使用RegistrationViewModel作为源。
@model RegistrationViewModel
...
Thank you very much, @Model.Name!
Your order has been placed.
Soon you will receive an e-mail at @Model.Email including all order details.
清单:/MVC/Views/Checkout/Index.cshtml中的绑定结账数据
请注意在更新数据库用户信息之前,CheckoutController类如何检查模型是否有效:
public async Task Index(RegistrationViewModel registration)
{
if (ModelState.IsValid)
{
服务器端需要进行此验证,以便我们不会使用不一致的信息更新数据库表。但这只是我们防护的最后一道防线。您永远不应该唯一依赖服务器端检查来进行数据验证。还有什么必须做的?您还应该进行早期验证,在用户尝试提交订单时执行客户端检查。幸运的是,ASPNET Core项目提供了客户端验证的部分视图:
清单:_ValidationScriptsPartial.cshtml部分视图
验证部分视图必须使用标记帮助程序包含在注册视图中:
@section Scripts
{
}
清单:包含在\MVC\Views\Registration\Index.cshtml中的表单客户端验证脚本
使用Microsoft帐户,Google,Facebook等登录
为什么允许外部帐户登录?
在Web应用程序中注册新用户和密码通常是一个繁琐的过程,在电子商务应用程序中不仅令客户失望,而且对业务也有害,因为任何额外的步骤都可能阻碍潜在的购买者。他们可能更喜欢另一个更友好,更少官僚主义的电子商务网站。简而言之:强迫用户注册可能会损害销售。
外部登录过程允许我们将identity过程与外部服务(如Microsoft,Google和Facebook)上的现有帐户集成,而无需创建新密码,可以为我们的客户提供更方便的注册过程。
但是,必须将此外部登录过程作为替代方法实现,而不是唯一的注册方法。
幸运的是,ASP.NET Core Identity提供了一种机制,允许用户通过外部提供程序(如Microsoft,Google,Facebook,Twitter等)执行登录。
使用Microsoft帐户配置外部登录
请记住,外部登录服务不了解您的应用程序,反之亦然。双方都需要一个配置来定义认证过程中涉及哪些应用程序/服务。
让我们创建所需的配置,以便我们的用户可以使用他们的Microsoft帐户(@ hotmail.com,@ outlook.com等)作为我们的应用程序的登录方式。
首先,Microsoft身份验证服务需要知道我们的应用程序。我们需要输入名为Microsoft Application Registration Portal https://apps.dev.microsoft.com的服务地址。并为我们的应用程序创建设置。
首先,您(开发人员)需要使用您的Microsoft帐户登录才能访问门户网站:

图:微软的登录提供商页面
在此开发人员门户中,您可以看到已注册的应用程序。如果您仍然没有Microsoft帐户,则可以创建一个。登录后,您将被重定向到“我的应用”页面:

图:Microsoft Developer Portal上的我的应用程序
在这里,您将注册一个新的应用程序。选择右上角的添加应用程序,然后输入应用程序的名称。
让我们给它一个有意义的名字,比如GroceryStore。

图片:注册新的应用程序
单击“创建应用程序”以继续注册页面。提供名称并记下应用程序标识的值,稍后您可以将其用作ClientId。

图片:生成新的应用密码

图片:定义应用程序平台
在此处,您将单击“平台”部分中的“添加平台”,然后选择“Web平台”。

图:可用的App平台
在Web平台下,输入您的开发URL,将/ signin-microsoft添加到重定向字段URL(例如: https://localhost:44320/signin-microsoft)。我们稍后将配置的Microsoft身份验证方案将自动处理/ signin-microsoft路由中的请求以实现OAuth流:

图片:配置应用程序的重定向URL
请注意,在此页面上,我们将单击“添加URL”以确保已添加URL。

如有必要,请填写任何其他应用程序设置,然后单击页面底部的“保存”以保存对应用程序配置的更改。

现在,查看注册页面上显示的Application Id。单击以在“应用程序机密”部分中生成新密码。这将显示一个框,您可以在其中复制应用程序密码:

图片:获取密码
我们在哪里存储此密码?在现实世界的商业应用程序中,我们必须使用某种形式的安全存储,例如环境变量或秘密管理器工具(https://docs.microsoft.com/aspnet/core/security/app-secrets?view = aspnetcore-2.2&tabs = windows)。
但是,为了让我们的生活更轻松,我们只需使用appsettings.json配置文件来存储在Microsoft Developer Portal上注册的应用程序密码。在这里,我们创建了两个新的配置键:
- ExternalLogin:Microsoft:ClientId:在Microsoft创建的Web应用程序ID
- ExternalLogin:Microsoft:ClientSecret:在Microsoft中创建的Web应用程序的密码
"ExternalLogin": {
"Microsoft": {
"ClientId": "nononononononononononnnononoon",
"ClientSecret": "nononononononononononnnononoon"
}
}
清单:appsettings.json上的外部登录配置
现在让我们将以下摘录添加到Startup类的CofigureServices方法中,以通过Microsoft帐户启用身份验证:
services.AddAuthentication()
.AddMicrosoftAccount(options =>
{
options.ClientId = Configuration["ExternalLogin:Microsoft:ClientId"];
options.ClientSecret = Configuration["ExternalLogin:Microsoft:ClientSecret"];
});
清单:Startup类的外部登录配置
再次运行我们的电子商务应用程序,我们可以在登录页面上看到一个右侧面板,您可以在其中找到一个允许您使用Microsoft外部提供程序登录的新按钮。

图:新的Microsoft外部登录选项
登录到Microsoft页面后,我们的用户将被重定向到ASP.NET Core Identity提供的“帐户关联页面”。在这里,我们将点击“注册”以完成Microsoft帐户与我们的电子商务帐户之间的关联:

图片:关联帐户
正如我们在下面看到的,客户端现在已在Microsoft的电子邮件中注册,我们的应用程序无需进一步的登录信息!

图片:使用Microsoft帐户登录
请注意,Identity直接创建的帐户可以与在Google,Microsoft,Facebook等外部机制中创建的用户帐户并存,我们可以在SQLite数据库MVC.db的用户表(AspNetUsers)中看到:

图片:AspNetUsers SQLite表
最后,我们可以调查在我们的系统之外创建了哪些用户帐户。只需从MVC.db数据库中打开AspNetUserLogins表:

图片:AspNetUserLogins SQLite表
使用Google帐户配置外部登录
现在让我们创建所需的配置,以便我们的用户可以使用Google帐户(@ gmail.com)作为我们应用程序的替代登录方式。
Google身份验证服务还需要了解我们的应用程序。首先我们需要去谷歌帐户即可访问网站 。在该页面,您必须单击以配置项目:
图片:将Google登录集成到您的网络应用中
现在,您必须为Google登录配置项目。在此输入项目的名称。让我们给它一个有意义的名字,比如GroceryStore:

图片:为Google登录配置项目
现在是时候配置您的OAuth客户端了。在用户使用自己的Google帐户登录时,键入要向用户显示的应用的友好名称:

图片:配置您的OAuth客户端
接下来,您告诉谷歌您的应用所在的位置。在这种情况下,我们使用Web服务器,因为它是我们的ASP.NET Core Web应用程序,它将调用Google外部登录提供程序进行用户身份验证。

图片:你在哪里调用?
Google还需要我们的应用重定向URI。只要我们的用户通过Google进行身份验证,就会使用授权码调用http://localhost:5001/signin-google URI进行访问。

图片:授权重定向URI
单击“创建”按钮后,您可以检查需要在应用程序中使用的新创建的客户端ID和客户端密钥值。
现在,让我们打开appsettings.json文件并插入以下键和值:
-
ExternalLogin:Google:ClientId:在Google上创建的Web应用程序ID
-
ExternalLogin:Google:ClientSecret:在Google中创建的Web应用程序的密码
"ExternalLogin": {
"Microsoft": {
"ClientId": "nononononononononononnnononoon",
"ClientSecret": "nononononononononononnnononoon"
},
"Google": {
"ClientId": "nononononononononononnnononoon",
"ClientSecret": "nononononononononononnnononoon"
}
}
清单:appsettings.json上的外部登录配置
现在让我们将以下摘录添加到Startup类的CofigureServices方法中,以通过Google帐户启用身份验证:
services.AddAuthentication()
.AddMicrosoftAccount(options =>
{
options.ClientId = Configuration["ExternalLogin:Microsoft:ClientId"];
options.ClientSecret = Configuration["ExternalLogin:Microsoft:ClientSecret"];
})
.AddGoogle(options =>
{
options.ClientId = Configuration["ExternalLogin:Google:ClientId"];
options.ClientSecret = Configuration["ExternalLogin:Google:ClientSecret"];
});
清单:Startup类的外部登录配置
再次运行我们的电子商务应用程序,我们可以在登录页面上看到一个右侧面板,您可以在其中找到一个允许您使用Google外部提供商登录的新按钮。

图片:新的Google外部登录选项
登录到Microsoft页面后,我们的用户将被重定向到ASP.NET Core Identity提供的“帐户关联页面”。在这里,我们将点击“注册”以完成Google帐户与我们的电子商务帐户之间的关联:

图片:关联帐户
如下所示,客户现在已在Google的电子邮件中注册,我们的应用程序无需再提供登录信息!

图片:选择Google帐户

使用Google帐户配置外部登录
最后,让我们将AddGoogle()扩展方法的调用添加到Startup类的CofigureServices方法,以通过Google帐户启用身份验证:
services.AddAuthentication()
.AddMicrosoftAccount(options =>
{
options.ClientId = Configuration["ExternalLogin:Microsoft:ClientId"];
options.ClientSecret = Configuration["ExternalLogin:Microsoft:ClientSecret"];
})
.AddGoogle(options =>
{
options.ClientId = Configuration["ExternalLogin:Google:ClientId"];
options.ClientSecret = Configuration["ExternalLogin:Google:ClientSecret"];
});
清单:在Startup类中添加外部Google登录提供程序
结论
我们完成了“ASP.NET核心之路微服务第3部分”。在本文中,我们了解了我们在上一课程结束时所使用的应用程序的用户身份验证需求。然后,我们决定使用ASP.NET Core Identity作为我们的电子商务Web应用程序的身份验证解决方案。
我们已经学习了如何使用ASP.NET Core Identity 标识创建过程来授权MVC应用程序,以便它可以利用用户身份验证,资源保护和敏感页面(如Basket,Registration和Checkout)的优势。
我们了解用户布局流如何工作,并且我们已经学习如何配置MVC Web应用程序以满足该流的要求。一旦理解了登录和注销过程,我们就开始修改我们的MVC应用程序以使用id和用户名,以及每个登录用户的其他注册信息,这些信息在我们的MVC应用程序的上下文中表示正在进行购买的客户。
最后,我们学习了如何执行外部登录过程,这使我们能够将identity 过程与外部服务(如Microsoft,Google和Facebook)中的现有帐户集成,从而为我们的客户提供更方便的注册流程。
原文地址:https://www.codeproject.com/Articles/5129264/ASP-NET-Core-Road-to-Microservices-Part-03-Identit