本文源代码获取:文末
启动一个新项目并从头开始处理身份验证和授权可能会筋疲力尽。它常日涉及创建登录和注册功能,这可能很耗时。管理刷新令牌和实现双成分身份验证等寻衅增加了繁芜性。
值得光彩的是,随着 .NET 8 的到来,这些任务大大简化,只须要最少的配置。

在本文中,我将辅导你完成各种标识配置方案,包括:
基本注册和登录。
利用持有者令牌保护闭幕点。
检索用户信息。
电子邮件确认。
重新发送电子邮件确认。
变动默认设置并添加自定义用户属性。
配置双成分身份验证 (MVC)。
先决条件:.NET 8 或更高版本。
在连续之前,让我概述一下我当前的环境设置:
.NET Web API 运用程序。
Visual Studio 2022 年。
利用SQLite仿照真实数据库,而不是内存数据库。
接下来,让我们安装必要的 NuGet 包。
dotnet add package Microsoft.AspNetCore.Identity.EntityFrameworkCore dotnet add package Microsoft.EntityFrameworkCore.Design dotnet add package Microsoft.EntityFrameworkCore.Sqlite dotnet add package Microsoft.EntityFrameworkCore.Tools
基本注册和登录。
首先,首先创建所有身份天生的表的存储位置。
// IdentityUser is the Microsoft base identity class. // creates empty scheme with just all the identity tables. class AppDbContext : IdentityDbContext<IdentityUser> { public AppDbContext(DbContextOptions options) : base(options) { } }
接下来,我们将注册身份验证和授权中间件,从而灵巧地在持有者令牌或 Cookie 之间进行选择。在此示例中,我们将选择持有者令牌,以便于在登录时检索持有者令牌。
// Program.cs builder.Services.AddAuthentication() .AddBearerToken(IdentityConstants.BearerScheme); builder.Services.AddAuthorizationBuilder();
之后,我们将注册我们的 ,在此示例中,它是一个 SQLite 数据库。
// Program.cs builder.Services.AddDbContext<AppDbContext>(options => { options.UseSqlite(\"大众DataSource=app.db\"大众); });
之后,我们须要将 作为身份存储连接,以便所有操作都指向 SQLite 数据库。
// Program.cs builder.Services.AddIdentityCore\<IdentityUser>() .AddEntityFrameworkStores\<AppDbContext>() .AddApiEndpoints();
末了,我们须要将所有端点添加为运用程序端点的一部分。这可以通过在构建天生器后映射标识闭幕点来实现。
app.MapIdentityApi<IdentityUser>();
您的Program.cs文件现在应类似于此构造。
using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.Services.AddAuthentication() .AddBearerToken(IdentityConstants.BearerScheme); builder.Services.AddAuthorizationBuilder(); builder.Services.AddDbContext<AppDbContext>(options => { options.UseSqlite(\公众DataSource=app.db\"大众); }); builder.Services.AddIdentityCore<IdentityUser>() .AddEntityFrameworkStores<AppDbContext>() .AddApiEndpoints(); var app = builder.Build(); app.MapIdentityApi<IdentityUser>(); app.UseSwagger(); app.UseSwaggerUI(); app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
在运行运用程序之前,请不要忘却添加新的迁移,并通过从包管理器掌握台实行以下命令来更新数据库。
Add-Migration initial Update-Database
现在,运行运用程序并打开 Swagger。您该当会看到自动天生的闭幕点凑集。
天生的身份闭幕点。
考试测验注册新用户。如果考试测验利用无效的电子邮件地址或不符合条件的密码创建新用户,则标识将返回缺点以及发生的详细详细信息。
现在,让我们连续登录过程。如果供应的电子邮件或密码无效,则身份将返回 401 未授权状态。
利用持有者令牌保护闭幕点。
将身份验证配置为返回持有者令牌后,我们须要将此持有者令牌用于任何必要授权的受保护闭幕点。
必须把稳的是,天生的令牌不是标准的 JSON Web 令牌 (JWT)。此决定是故意为之的,由于内置标识紧张用于大略方案。令牌选项并不虞味着充当功能完好的身份做事供应商或令牌做事器,而是无法利用 cookie 的客户真个 cookie 选项的替代方案。
现在,让我们考试测验访问授权端点,特殊是 /manage/info 端点。如果您考试测验从 Swagger 访问它,它将显示未经授权的缺点。接下来,利用 Postman 登录,保存 accessToken,并在调用 /manage/info 端点时包含它。这一次,它该当返回所需的结果。
检索用户信息
要随时检索当前登任命户的信息,请利用存储当前登任命户信息的类。ClaimsPrincipal
要利用最小 API 方法实现此目的,请实行以下操作:
app.Map(\"大众/\"大众, (ClaimsPrincipal user) => $\"大众Hello {user.Identity!.Name}\公众) .RequireAuthorization();
对付掌握器方法:
[ApiController] [Route(\"大众[controller]\"大众)] public class TestController: ControllerBase { [HttpGet] [Authorize] public string Get() { return User.Identity!.Name; } }
请务必把稳,上述示例利用“!
”运算符,这意味着标识应始终存在,而不可能为 。此假设成立,由于两者都是须要事先登录的授权端点。但是,建议验证标识是否存在,以防止潜在的 引用非常。
电子邮件确认
Microsoft建议利用SendGrid或其他电子邮件做事发送电子邮件,而不是SMTP。SMTP 很难保护和精确设置。
在本教程中,SendGrid 用于发送电子邮件。发送电子邮件须要 SendGrid 帐户和密钥。请参阅免费开始利用 SendGrid,注册免费的 SendGrid 帐户。
1- 在文件中配置 SendGrid 所需信息。避免将这些设置直接添加到appsettings.json文件中,以降落安全风险。secrets.json
{ \"大众SendGridKey\公众: \"大众your send-grid key\"大众, \公众From\"大众: \"大众your registered email\"大众, \公众Name\公众: \公众your registered name\公众 }
注册电子邮件和姓名
SendGrid API 密钥
2- 安装必要的 NuGet 包。
dotnet add package SendGrid dotnet add package SendGrid.Extensions.DependencyInjection
3-实现IEmailSender
要实现,请利用类似于以下内容的代码进行创建:IEmailSenderEmailSender.cs
using Microsoft.AspNetCore.Identity.UI.Services; using SendGrid; using SendGrid.Helpers.Mail; namespace Identity; public class EmailSender : IEmailSender { private readonly ILogger _logger; private readonly IConfiguration _configuration; public EmailSender(IConfiguration configuration, ILogger<EmailSender> logger) { _configuration = configuration; _logger = logger; } public async Task SendEmailAsync(string toEmail, string subject, string message) { var sendGridKey = _configuration[\"大众SendGridKey\"大众]; ArgumentException.ThrowIfOrEmpty(sendGridKey, nameof(sendGridKey)); await Execute(sendGridKey, subject, message, toEmail); } public async Task Execute(string apiKey, string subject, string message, string toEmail) { var client = new SendGridClient(apiKey); var msg = new SendGridMessage() { From = new EmailAddress(_configuration[\公众From\公众], _configuration[\"大众Name\"大众]), Subject = subject, PlainTextContent = message, HtmlContent = message }; msg.AddTo(new EmailAddress(toEmail)); // Disable click tracking. // See https://sendgrid.com/docs/User_Guide/Settings/tracking.html msg.SetClickTracking(false, false); var response = await client.SendEmailAsync(msg); _logger.LogInformation(response.IsSuccessStatusCode ? $\公众Email to {toEmail} queued successfully!\公众 : $\"大众Failure Email to {toEmail}\公众); } }
4- 将 EmailService 注入个中以启用其利用。Program.cs
// Program.cs builder.Services.AddTransient<IEmailSender, EmailSender>();
5- 逼迫登录确认并集成 SendGrid 做事。
现在,如果您考试测验再次注册,它将起浸染,但您会把稳到没有发送电子邮件确认。此外,用户无需任何确认即可登录。
为理解决这个问题并确保精确的流程,我们须要首先在署名过程中哀求电子邮件确认。然后,我们须要集成 SendGrid 做事,以便标识框架可以利用它。
// Program.cs builder.Services.AddIdentityCore<IdentityUser>(options => { options.SignIn.RequireConfirmedEmail = true; }) builder.Services.AddSendGrid(options => options.ApiKey = builder.Configuration[\公众SendGridKey\"大众]! );
您的文件现在应类似于此构造。Program.cs
using Identity; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Identity.UI.Services; using Microsoft.EntityFrameworkCore; using SendGrid.Extensions.DependencyInjection; using System.Security.Claims; var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.Services.AddAuthentication() .AddBearerToken(IdentityConstants.BearerScheme); builder.Services.AddSendGrid(options => options.ApiKey = builder.Configuration[\"大众SendGridKey\"大众]! ); builder.Services.AddTransient<IEmailSender, EmailSender>(); builder.Services.AddAuthorizationBuilder(); builder.Services.AddDbContext<AppDbContext>(options => { options.UseSqlite(\"大众DataSource=app.db\公众); }); builder.Services.AddIdentityCore<IdentityUser>(options => { options.SignIn.RequireConfirmedEmail = true; }) .AddEntityFrameworkStores<AppDbContext>() .AddApiEndpoints(); var app = builder.Build(); app.MapIdentityApi<IdentityUser>(); app.Map(\公众/\"大众, (ClaimsPrincipal user) => $\"大众Hello {user.Identity!.Name} from minimal apis.\"大众) .RequireAuthorization(); app.UseSwagger(); app.UseSwaggerUI(); app.UseHttpsRedirection(); app.UseAuthorization(); app.MapControllers(); app.Run();
现在,是时候测试我们的运用程序了。考试测验注册一个新用户,并检讨您的电子邮件以获取确认链接。单击该链接应将数据库中的确认状态变动为 TRUE。
请记住检讨您的垃圾邮件文件夹,由于电子邮件常日终极会在那里。此外,请把稳,电子邮件在发送之前会排队,因此估量会有几秒钟的轻微延迟。
注册新用户
Visual Studio 日志
在数据库中创建的用户
确认链接电子邮件
通过单击链接“单击此处”,它该当将您重定向回 localhost,并将用户在数据库中的确认状态更新为 TRUE。
确认
确认状态变动为 TRUE
末了,通过注入 SendGrid 做事,我们可以简化 EmailService,从而减少代码行数。
这是该版本的更新版本,可以有效处理所有测试方案。EmailService
using Microsoft.AspNetCore.Identity.UI.Services; using SendGrid; using SendGrid.Helpers.Mail; public class EmailSender : IEmailSender { private readonly ILogger _logger; private readonly IConfiguration _configuration; private readonly ISendGridClient _sendGridClient; public EmailSender(IConfiguration configuration, ILogger<EmailSender> logger, ISendGridClient sendGridClient) { _configuration = configuration; _logger = logger; _sendGridClient = sendGridClient; } public async Task SendEmailAsync(string toEmail, string subject, string message) { var msg = new SendGridMessage() { From = new EmailAddress(_configuration[\"大众From\"大众], _configuration[\"大众Name\"大众\]), Subject = subject, PlainTextContent = message, HtmlContent = message }; msg.AddTo(new EmailAddress(toEmail)); var response = await _sendGridClient.SendEmailAsync(msg); _logger.LogInformation(response.IsSuccessStatusCode ? $\公众Email to {toEmail} queued successfully!\公众 : $\"大众Failure Email to {toEmail}\"大众); } }
重新发送电子邮件确认
您当然须要重新发送确认电子邮件的选项,这对任何运用程序都至关主要。.NET 8 Identity 供应重新发送确认闭幕点:只需调用并设置正文,如下所示:.NET 8 Identity provides a resend confirmation endpoint: just call and set the body as follows:/resendConfirmationEmail
{\公众Email\"大众: \公众user email\"大众}
变动默认设置并添加自定义用户属性
Microsoft 标识还供应修正默认设置或引入新的自定义属性的功能。
调度默认设置。
builder.Services.Configure<IdentityOptions>(options => { // Password settings. options.Password.RequireDigit = true; options.Password.RequireLowercase = true; options.Password.RequireNonAlphanumeric = true; options.Password.RequireUppercase = true; options.Password.RequiredLength = 6; options.Password.RequiredUniqueChars = 1; // Lockout settings. options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5); options.Lockout.MaxFailedAccessAttempts = 5; options.Lockout.AllowedForNewUsers = true; // User settings. options.User.AllowedUserNameCharacters = \公众abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-.\_@+\"大众; options.User.RequireUniqueEmail = false; });
将新的自定义属性添加到用户属性中。这可以通过创建一个新的用户类来实现,该类继续自 。
class AppUser : IdentityUser { public int MyProperty { get; set; } }
随后,须要添加新的迁移,并且应将新属性集成到表中。
请记住将运用程序中涌现的每个项更新为IdentityUserAppUser
配置双成分身份验证 (MVC)在我们开始之前,这里有一些观点,在我们开始之前最好知道。
什么是多重身份验证 (MFA)?
多重身份验证 (MFA) 通过哀求用户在登录过程中供应其他形式的身份标识来增强安全性。这可能包括从手机输入代码、利用 FIDO2 密钥或供应指纹扫描。通过哀求第二种形式的身份验证,MFA 使攻击者更难得到未经授权的访问,由于附加成分不随意马虎得到或复制。
什么是双成分身份验证 (2FA)?
双成分身份验证 (2FA) 类似于 MFA 的子集,但不同之处在于 MFA 可能须要两个或多个成分来证明身份。
什么是TOTP(基于韶光的一次性密码算法)?
利用 ASP.NET Core Identity 时,默认支持利用 TOTP 的 MFA。此方法可与任何合规的身份验证器运用一起利用,包括:
Microsoft 身份验证器
谷歌身份验证器
什么是 MFA 短信?
与密码身份验证(独身只身分)比较,带有 SMS 的 MFA 大大提高了安全性。但是,不再建议利用 SMS 作为第二个成分。对付此类实现,存在太多已知的攻击媒介。
什么是在线快速身份识别 (FIDO)?FIDO 是无密码身份验证的开放标准,许可用户在没有密码的情形下登录。FIDO2 密钥(常日是 USB,但也包括蓝牙或 NFC)通过肃清密码风险来增强安全性。它们目前被认为是最安全的 MFA 方法。
现在,让我们开始配置 2FA。
我们将利用 2FA 与 MVC 项目的集成。首次创建新的 MVC 项目时,可以选择从一开始就天生标识系统,包括“注册”、“登录”和“2FA”。我们的第一步是创建一个新的 MVC 项目。
在 Visual Studio 2022 中,可以完成以下操作:
选择个人帐户标识选项。
或者,您可以利用命令行。
dotnet new mvc -n \"大众2FA\"大众 -au individual
创建的项目应如下所示。
现在,运行创建的项目。应显示一个带有登录和注册按钮的欢迎页面。
单击“注册”以创建新用户。
单击“单击此处确认您的帐户”以确认您的电子邮件。
接下来,注销,然后再次登录。点击右上角的电子邮件。
导航到“双成分身份验证”部分。
单击“添加身份验证器运用程序” 应显示双成分身份验证设置屏幕。
如您所见,它是开箱即用的,但没有扫描二维码的选项;它仅适用于代码。
现在,让我们添加二维码功能,许可用户只需扫描二维码即可自动添加密钥。
我们须要访问为我们创建的天生的 cshtml 页面。默认情形下,这些页面位于目录中。但是,如果尚未展开目录,则 dotnet 不会显示文件,除非天生了文件。Areas/Identity/Pages
为此,请运行该命令。
dotnet tool install -g dotnet-aspnet-codegenerator
接下来,我们须要安装所有必需的 NuGet 包。
dotnet add pacakge Microsoft.EntityFrameworkCore.Design dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design
然后,运行代码天生器并指定要检索的页面。默认情形下,如果将其留空,它将天生许多页面。但是,为了避免不必要的页面使您的项目混乱,我们将指定我们须要的特定页面。
cd \"大众your project directory\公众 dotnet aspnet-codegenerator identity -dc _2FA.Data.ApplicationDbContext --files \"大众Account.Manage.EnableAuthenticator\"大众
若要查看可天生的所有文件,请运行该命令。
dotnet aspnet-codegenerator identity -dc _2FA.Data.ApplicationDbContext -lf
以下是可以天生的所有文件的完全列表。
File List: Account.\_StatusMessage Account.AccessDenied Account.ConfirmEmail Account.ConfirmEmailChange Account.ExternalLogin Account.ForgotPassword Account.ForgotPasswordConfirmation Account.Lockout Account.Login Account.LoginWith2fa Account.LoginWithRecoveryCode Account.Logout Account.Manage.\_Layout Account.Manage.\_ManageNav Account.Manage.\_StatusMessage Account.Manage.ChangePassword Account.Manage.DeletePersonalData Account.Manage.Disable2fa Account.Manage.DownloadPersonalData Account.Manage.Email Account.Manage.EnableAuthenticator Account.Manage.ExternalLogins Account.Manage.GenerateRecoveryCodes Account.Manage.Index Account.Manage.PersonalData Account.Manage.ResetAuthenticator Account.Manage.SetPassword Account.Manage.ShowRecoveryCodes Account.Manage.TwoFactorAuthentication Account.Register Account.RegisterConfirmation Account.ResendEmailConfirmation Account.ResetPassword Account.ResetPasswordConfirmation
返回到 Visual Studio,现在该当会看到已添加的文件。EnableAuthenticator.cshtml
在编辑文件之前,我们须要下载qrcode.js JavaScript库,它将为我们渲染并天生QR码。将其保存在文件夹中。EnableAuthenticator.cshtmlwwwroot\lib
在这里,我将其重命名为qrcodejs
接下来,创建一个新文件,利用以下代码在 中调用它。qr.jswwwroot\js
window.addEventListener(\公众load\公众, () => { const uri = document.getElementById(\公众qrCodeData\"大众).getAttribute('data-url'); new QRCode(document.getElementById(\"大众qrCode\公众), { text: uri, width: 150, height: 150 }); });
末了,打开文件,然后:EnableAuthenticator.cshtml
更新该部分以添加对以前下载的库的引用。Scriptsqrcode.js
添加带有调用的文件以天生二维码。qr.js
@section Scripts { @await Html.PartialAsync(\公众_ValidationScriptsPartial\公众) <script type=\"大众text/javascript\"大众 src=\"大众~/lib/qrcodejs/qrcode.js\"大众></script> <script type=\公众text/javascript\"大众 src=\公众~/js/qr.js\"大众></script> }
再次运行运用程序,QR 码现在该当涌现。
利用Authenticator运用程序扫描它,它该当可以完美运行。
通过将其添加到身份验证器运用,可以从运用中天生的代码中验证代码。它该当显示 2FA 确认。
现在,考试测验注销,然后重新登录。将涌现 2FA 表单,提示您输入 2FA 代码。
恭喜,您的 2FA 设置完美。
源代码获取:"大众年夜众号回答【code:19129
】