- 通用
- 身份验证
- 授权
- 数据保护
- 机密管理
ASP.NET Core 上的标识简介
ASP.NET Core 标识:
- 是支持用户界面(UI)登录功能的 API。
- 管理用户、密码、配置文件数据、角色、声明、令牌、电子邮件确认等。
用户可以创建一个具有存储在标识中的登录信息的帐户,也可以使用外部登录提供程序。 支持的外部登录提供程序包括Facebook、Google、Microsoft 帐户和 Twitter。
GitHub 上提供了标识源代码。 基架标识并查看生成的文件以查看模板与标识的交互。
通常使用 SQL Server 数据库配置标识,以存储用户名、密码和配置文件数据。 另外,还可以使用另一个永久性存储,例如 Azure 表存储。
本主题介绍如何使用标识注册、登录和注销用户。 有关创建使用标识的应用的更多详细说明,请参阅本文末尾的后续步骤部分。
- Azure Active Directory (Azure AD)开发人员平台的演变。
- 与 ASP.NET Core 标识无关。
ASP.NET Core 标识将用户界面 (UI) 登录功能添加到 ASP.NET Core Web 应用。 若要保护 Web API 和 SPA,请使用以下项之一:
- Azure Active Directory
- Azure Active Directory B2C (Azure AD B2C)]
- IdentityServer4
IdentityServer4 是适用于 ASP.NET Core 3.0 的 OpenID Connect 和 OAuth 2.0 框架。 IdentityServer4 支持以下安全功能:
- 身份验证即服务 (AaaS)
- 跨多个应用程序类型的单一登录/注销 (SSO)
- API 的访问控制
- Federation Gateway
有关详细信息,请参阅欢迎使用 IdentityServer4。
创建具有身份验证的 Web 应用
使用单个用户帐户创建一个 ASP.NET Core Web 应用程序项目。
-
Visual Studio
- 选择 "文件" >新建>项目"。
- 选择“ASP.NET Core Web 应用程序”。 将项目命名为WebApp1 ,使其命名空间与项目下载相同。 单击“确定”。
- 选择 ASP.NET Core Web 应用程序,然后选择 "更改身份验证"。
- 选择单个用户帐户,然后单击 "确定" 。
-
.NET Core CLI
dotnet new webapp --auth Individual -o WebApp1
上述命令使用 SQLite 创建 Razor web 应用。 若要创建具有 LocalDB 的 web 应用,请运行以下命令:
dotnet new webapp --auth Individual -uld -o WebApp1
生成的项目提供ASP.NET Core 标识作为Razor 类库。 标识 Razor 类库公开 Identity
区域的终结点。 例如:
- /Identity/Account/Login
- /Identity/Account/Logout
- /Identity/Account/Manage
应用迁移
应用迁移以初始化数据库。
-
Visual Studio
在包管理器控制台中运行以下命令(PMC):
PM> Update-Database
-
.NET Core CLI
使用 SQLite 时,此步骤不需要迁移。 对于 LocalDB,请运行以下命令:
dotnet ef database update
测试注册和登录
运行应用并注册用户。 根据屏幕大小,你可能需要选择 "导航" 切换按钮以查看 "寄存器" 和 "登录" 链接。
查看标识数据库
-
Visual Studio
- 从视图菜单中,选择SQL Server 对象资源管理器(SSOX)。
- 导航到 (localdb) MSSQLLocalDB (SQL Server 13) 。 右键单击dbo。AspNetUsers > 查看数据:
-
.NET Core CLI
您可以下载许多第三方工具来管理和查看 SQLite 数据库,例如DB Browser for SQLite。
配置标识服务
在 ConfigureServices
中添加服务。 典型模式是调用所有 Add{Service}
方法,然后调用所有 services.Configure{Service}
方法。
public void ConfigureServices(IServiceCollection services) { services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer( Configuration.GetConnectionString("DefaultConnection"))); services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true) .AddEntityFrameworkStores<ApplicationDbContext>(); services.AddRazorPages(); 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; }); services.ConfigureApplicationCookie(options => { // Cookie settings options.Cookie.HttpOnly = true; options.ExpireTimeSpan = TimeSpan.FromMinutes(5); options.LoginPath = "/Identity/Account/Login"; options.AccessDeniedPath = "/Identity/Account/AccessDenied"; options.SlidingExpiration = true; }); }
前面突出显示的代码用默认选项值配置标识。 服务通过依赖关系注入提供给应用程序。
通过调用 UseAuthentication来启用标识。 UseAuthentication
将身份验证中间件添加到请求管道。
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseDatabaseErrorPage(); } else { app.UseExceptionHandler("/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthentication(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); }); }
模板生成的应用不使用授权。 包括 app.UseAuthorization
以确保在应用添加授权时,按正确的顺序添加。 必须按前面的代码中所示的顺序调用 UseRouting
、UseAuthentication
、UseAuthorization
和 UseEndpoints
。
有关 IdentityOptions
和 Startup
的详细信息,请参阅 IdentityOptions 和应用程序启动。
基架注册、登录和注销
-
Visual Studio
添加注册、登录和注销文件。 按照基架标识操作,并使用授权说明生成本部分中所示的代码。
-
.NET Core CLI
如果创建的项目的名称为WebApp1,请运行以下命令。 否则,请使用
ApplicationDbContext
的正确命名空间:dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design dotnet aspnet-codegenerator identity -dc WebApp1.Data.ApplicationDbContext --files "Account.Register;Account.Login;Account.Logout"
PowerShell 使用分号作为命令分隔符。 使用 PowerShell 时,请对文件列表中的分号进行转义,或将文件列表置于双引号中,如前面的示例所示。
有关基架标识的详细信息,请参阅使用授权将基架标识导入 Razor 项目。
检查注册
当用户单击 "注册" 链接时,将调用 RegisterModel.OnPostAsync
操作。 用户是通过CreateAsync对 _userManager
对象创建的。 _userManager
由依赖关系注入提供):
public async Task<IActionResult> OnPostAsync(string returnUrl = null) { returnUrl = returnUrl ?? Url.Content("~/"); ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()) .ToList(); if (ModelState.IsValid) { var user = new IdentityUser { UserName = Input.Email, Email = Input.Email }; var result = await _userManager.CreateAsync(user, Input.Password); if (result.Succeeded) { _logger.LogInformation("User created a new account with password."); var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code)); var callbackUrl = Url.Page( "/Account/ConfirmEmail", pageHandler: null, values: new { area = "Identity", userId = user.Id, code = code }, protocol: Request.Scheme); await _emailSender.SendEmailAsync(Input.Email, "Confirm your email", $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>."); if (_userManager.Options.SignIn.RequireConfirmedAccount) { return RedirectToPage("RegisterConfirmation", new { email = Input.Email }); } else { await _signInManager.SignInAsync(user, isPersistent: false); return LocalRedirect(returnUrl); } } foreach (var error in result.Errors) { ModelState.AddModelError(string.Empty, error.Description); } } // If we got this far, something failed, redisplay form return Page(); }
如果已成功创建用户,则会通过调用 _signInManager.SignInAsync
登录该用户。
请参阅帐户确认以了解在注册时要阻止立即登录的步骤。
Log in
发生下列情况时,会显示登录窗体:
- 选择 "登录" 链接。
- 用户尝试访问他们无权访问的受限制的页面,或未经系统的身份验证。
提交登录页上的窗体时,将调用 OnPostAsync
操作。 对 _signInManager
对象(由依赖关系注入提供)调用 PasswordSignInAsync
。
public async Task<IActionResult> OnPostAsync(string returnUrl = null) { returnUrl = returnUrl ?? Url.Content("~/"); if (ModelState.IsValid) { // This doesn't count login failures towards account lockout // To enable password failures to trigger account lockout, // set lockoutOnFailure: true var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: true); if (result.Succeeded) { _logger.LogInformation("User logged in."); return LocalRedirect(returnUrl); } if (result.RequiresTwoFactor) { return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, RememberMe = Input.RememberMe }); } if (result.IsLockedOut) { _logger.LogWarning("User account locked out."); return RedirectToPage("./Lockout"); } else { ModelState.AddModelError(string.Empty, "Invalid login attempt."); return Page(); } } // If we got this far, something failed, redisplay form return Page(); }
Base Controller
类公开可从控制器方法访问的 User
属性。 例如,可以枚举 User.Claims
并做出授权决策。 有关详情,请参阅在 ASP.NET Core 中授权简介。
Log out
"注销" 链接调用 LogoutModel.OnPost
操作。
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.Logging; using System.Threading.Tasks; namespace WebApp1.Areas.Identity.Pages.Account { [AllowAnonymous] public class LogoutModel : PageModel { private readonly SignInManager<IdentityUser> _signInManager; private readonly ILogger<LogoutModel> _logger; public LogoutModel(SignInManager<IdentityUser> signInManager, ILogger<LogoutModel> logger) { _signInManager = signInManager; _logger = logger; } public void OnGet() { } public async Task<IActionResult> OnPost(string returnUrl = null) { await _signInManager.SignOutAsync(); _logger.LogInformation("User logged out."); if (returnUrl != null) { return LocalRedirect(returnUrl); } else { return RedirectToPage(); } } } }
在前面的代码中,代码 return RedirectToPage();
需要是重定向,以便浏览器执行新请求并更新用户的标识。
SignOutAsync清除 cookie 中存储的用户声明。
Post 在Pages/Shared/_LoginPartial 中指定。 cshtml:
@using Microsoft.AspNetCore.Identity @inject SignInManager<IdentityUser> SignInManager @inject UserManager<IdentityUser> UserManager <ul class="navbar-nav"> @if (SignInManager.IsSignedIn(User)) { <li class="nav-item"> <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello @User.Identity.Name!</a> </li> <li class="nav-item"> <form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Page("/", new { area = "" })" method="post" > <button type="submit" class="nav-link btn btn-link text-dark">Logout</button> </form> </li> } else { <li class="nav-item"> <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Register">Register</a> </li> <li class="nav-item"> <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a> </li> } </ul>
测试标识
默认 web 项目模板允许匿名访问主页。 若要测试标识,请添加[Authorize]
:
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.Logging; namespace WebApp1.Pages { [Authorize] public class PrivacyModel : PageModel { private readonly ILogger<PrivacyModel> _logger; public PrivacyModel(ILogger<PrivacyModel> logger) { _logger = logger; } public void OnGet() { } } }
如果已登录,请注销。运行应用并选择 "隐私" 链接。 你将重定向到登录页。
浏览标识
更详细地了解标识:
- 创建完全标识 UI 源
- 检查每个页面的源,并单步执行调试程序。
标识组件
所有标识相关 NuGet 包都包含在ASP.NET Core 共享框架中。
标识的主包为AspNetCore。 此程序包包含用于 ASP.NET Core 标识的核心接口集,由 Microsoft.AspNetCore.Identity.EntityFrameworkCore
包含。
迁移到 ASP.NET Core 标识
有关迁移现有标识存储的详细信息和指南,请参阅迁移身份验证和标识。
设置密码强度
有关设置最小密码要求的示例,请参阅配置。
AddDefaultIdentity 和 AddIdentity
AddDefaultIdentity 是在 ASP.NET Core 2.1 中引入的。 调用 AddDefaultIdentity
类似于调用以下内容:
有关详细信息,请参阅AddDefaultIdentity 源。
禁止发布静态标识资产
若要防止将静态标识资产(用于标识 UI 的样式表和 JavaScript 文件)发布到 web 根目录,请将以下 ResolveStaticWebAssetsInputsDependsOn
属性和 RemoveIdentityAssets
目标添加到应用的项目文件中:
<PropertyGroup> <ResolveStaticWebAssetsInputsDependsOn>RemoveIdentityAssets</ResolveStaticWebAssetsInputsDependsOn> </PropertyGroup> <Target Name="RemoveIdentityAssets"> <ItemGroup> <StaticWebAsset Remove="@(StaticWebAsset)" Condition="%(SourceId) == 'Microsoft.AspNetCore.Identity.UI'" /> </ItemGroup> </Target>
后续步骤
ASP.NET Core 标识是将登录功能添加到 ASP.NET Core 应用的成员资格系统。 用户可以创建一个具有存储在标识中的登录信息的帐户,也可以使用外部登录提供程序。 支持的外部登录提供程序包括Facebook、Google、Microsoft 帐户和 Twitter。
可以使用 SQL Server 数据库配置标识,以存储用户名、密码和配置文件数据。 另外,还可以使用另一个永久性存储,例如 Azure 表存储。
本主题介绍如何使用标识注册、登录和注销用户。 有关创建使用标识的应用的更多详细说明,请参阅本文末尾的后续步骤部分。
AddDefaultIdentity 和 AddIdentity
AddDefaultIdentity 是在 ASP.NET Core 2.1 中引入的。 调用 AddDefaultIdentity
类似于调用以下内容:
有关详细信息,请参阅AddDefaultIdentity 源。
创建具有身份验证的 Web 应用
使用单个用户帐户创建一个 ASP.NET Core Web 应用程序项目。
-
Visual Studio
- 选择 "文件" >新建>项目"。
- 选择“ASP.NET Core Web 应用程序”。 将项目命名为WebApp1 ,使其命名空间与项目下载相同。 单击“确定”。
- 选择 ASP.NET Core Web 应用程序,然后选择 "更改身份验证"。
- 选择单个用户帐户,然后单击 "确定" 。
-
.NET Core CLI
dotnet new webapp --auth Individual -o WebApp1
生成的项目提供ASP.NET Core 标识作为Razor 类库。 标识 Razor 类库公开 Identity
区域的终结点。 例如:
- /Identity/Account/Login
- /Identity/Account/Logout
- /Identity/Account/Manage
应用迁移
应用迁移以初始化数据库。
-
Visual Studio
在包管理器控制台中运行以下命令(PMC):
Update-Database
-
.NET Core CLI
dotnet ef database update
测试注册和登录
运行应用并注册用户。 根据屏幕大小,你可能需要选择 "导航" 切换按钮以查看 "寄存器" 和 "登录" 链接。
查看标识数据库
-
Visual Studio
- 从视图菜单中,选择SQL Server 对象资源管理器(SSOX)。
- 导航到 (localdb) MSSQLLocalDB (SQL Server 13) 。 右键单击dbo。AspNetUsers > 查看数据:
-
.NET Core CLI
您可以下载许多第三方工具来管理和查看 SQLite 数据库,例如DB Browser for SQLite。
配置标识服务
在 ConfigureServices
中添加服务。 典型模式是调用所有 Add{Service}
方法,然后调用所有 services.Configure{Service}
方法。
public void ConfigureServices(IServiceCollection services) { services.Configure<CookiePolicyOptions>(options => { options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; }); services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer( Configuration.GetConnectionString("DefaultConnection"))); services.AddDefaultIdentity<IdentityUser>() .AddDefaultUI(UIFramework.Bootstrap4) .AddEntityFrameworkStores<ApplicationDbContext>(); 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; }); services.ConfigureApplicationCookie(options => { // Cookie settings options.Cookie.HttpOnly = true; options.ExpireTimeSpan = TimeSpan.FromMinutes(5); options.LoginPath = "/Identity/Account/Login"; options.AccessDeniedPath = "/Identity/Account/AccessDenied"; options.SlidingExpiration = true; }); services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); }
前面的代码用默认选项值配置标识。 服务通过依赖关系注入提供给应用程序。
通过调用UseAuthentication来启用标识。 UseAuthentication
将身份验证中间件添加到请求管道。
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseDatabaseErrorPage(); } else { app.UseExceptionHandler("/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseCookiePolicy(); app.UseAuthentication(); app.UseMvc(); }
有关详细信息,请参阅IdentityOptions 类和应用程序启动。
基架注册、登录和注销
按照基架标识操作,并使用授权说明生成本部分中所示的代码。
-
Visual Studio
添加注册、登录和注销文件。
-
.NET Core CLI
如果创建的项目的名称为WebApp1,请运行以下命令。 否则,请使用
ApplicationDbContext
的正确命名空间:dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design dotnet aspnet-codegenerator identity -dc WebApp1.Data.ApplicationDbContext --files "Account.Register;Account.Login;Account.Logout"
PowerShell 使用分号作为命令分隔符。 使用 PowerShell 时,请对文件列表中的分号进行转义,或将文件列表置于双引号中,如前面的示例所示。
检查注册
当用户单击 "注册" 链接时,将调用 RegisterModel.OnPostAsync
操作。 用户是通过CreateAsync对 _userManager
对象创建的。 _userManager
由依赖关系注入提供):
public async Task<IActionResult> OnPostAsync(string returnUrl = null) { returnUrl = returnUrl ?? Url.Content("~/"); if (ModelState.IsValid) { var user = new IdentityUser { UserName = Input.Email, Email = Input.Email }; var result = await _userManager.CreateAsync(user, Input.Password); if (result.Succeeded) { _logger.LogInformation("User created a new account with password."); var code = await _userManager.GenerateEmailConfirmationTokenAsync(user); var callbackUrl = Url.Page( "/Account/ConfirmEmail", pageHandler: null, values: new { userId = user.Id, code = code }, protocol: Request.Scheme); await _emailSender.SendEmailAsync(Input.Email, "Confirm your email", $"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>."); await _signInManager.SignInAsync(user, isPersistent: false); return LocalRedirect(returnUrl); } foreach (var error in result.Errors) { ModelState.AddModelError(string.Empty, error.Description); } } // If we got this far, something failed, redisplay form return Page(); }
如果已成功创建用户,则会通过调用 _signInManager.SignInAsync
登录该用户。
注意: 请参阅帐户确认以了解在注册时要阻止立即登录的步骤。
Log in
发生下列情况时,会显示登录窗体:
- 选择 "登录" 链接。
- 用户尝试访问他们无权访问的受限制的页面,或未经系统的身份验证。
提交登录页上的窗体时,将调用 OnPostAsync
操作。 对 _signInManager
对象(由依赖关系注入提供)调用 PasswordSignInAsync
。
public async Task<IActionResult> OnPostAsync(string returnUrl = null) { returnUrl = returnUrl ?? Url.Content("~/"); if (ModelState.IsValid) { // This doesn't count login failures towards account lockout // To enable password failures to trigger account lockout, // set lockoutOnFailure: true var result = await _signInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, lockoutOnFailure: true); if (result.Succeeded) { _logger.LogInformation("User logged in."); return LocalRedirect(returnUrl); } if (result.RequiresTwoFactor) { return RedirectToPage("./LoginWith2fa", new { ReturnUrl = returnUrl, RememberMe = Input.RememberMe }); } if (result.IsLockedOut) { _logger.LogWarning("User account locked out."); return RedirectToPage("./Lockout"); } else { ModelState.AddModelError(string.Empty, "Invalid login attempt."); return Page(); } } // If we got this far, something failed, redisplay form return Page(); }
Base Controller
类公开可从控制器方法访问的 User
属性。 例如,可以枚举 User.Claims
并做出授权决策。 有关详情,请参阅在 ASP.NET Core 中授权简介。
Log out
"注销" 链接调用 LogoutModel.OnPost
操作。
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.Logging; using System.Threading.Tasks; namespace WebApp1.Areas.Identity.Pages.Account { [AllowAnonymous] public class LogoutModel : PageModel { private readonly SignInManager<IdentityUser> _signInManager; private readonly ILogger<LogoutModel> _logger; public LogoutModel(SignInManager<IdentityUser> signInManager, ILogger<LogoutModel> logger) { _signInManager = signInManager; _logger = logger; } public void OnGet() { } public async Task<IActionResult> OnPost(string returnUrl = null) { await _signInManager.SignOutAsync(); _logger.LogInformation("User logged out."); if (returnUrl != null) { return LocalRedirect(returnUrl); } else { // This needs to be a redirect so that the browser performs a new // request and the identity for the user gets updated. return RedirectToPage(); } } } }
SignOutAsync清除 cookie 中存储的用户声明。
Post 在Pages/Shared/_LoginPartial 中指定。 cshtml:
@using Microsoft.AspNetCore.Identity @inject SignInManager<IdentityUser> SignInManager @inject UserManager<IdentityUser> UserManager <ul class="navbar-nav"> @if (SignInManager.IsSignedIn(User)) { <li class="nav-item"> <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello@User.Identity.Name!</a> </li> <li class="nav-item"> <form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Page("/", new { area = "" })" method="post"> <button type="submit" class="nav-link btn btn-link text-dark">Logout</button> </form> </li> } else { <li class="nav-item"> <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Register">Register</a> </li> <li class="nav-item"> <a class="nav-link text-dark" asp-area="Identity" asp-page="/Account/Login">Login</a> </li> } </ul>
测试标识
默认 web 项目模板允许匿名访问主页。 若要测试标识,请将[Authorize]
添加到 "隐私" 页。
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc.RazorPages; namespace WebApp1.Pages { [Authorize] public class PrivacyModel : PageModel { public void OnGet() { } } }
如果已登录,请注销。运行应用并选择 "隐私" 链接。 你将重定向到登录页。
浏览标识
更详细地了解标识:
- 创建完全标识 UI 源
- 检查每个页面的源,并单步执行调试程序。
标识组件
所有标识相关 NuGet 包都包含在AspNetCore 元包中。
标识的主包为AspNetCore。 此程序包包含用于 ASP.NET Core 标识的核心接口集,由 Microsoft.AspNetCore.Identity.EntityFrameworkCore
包含。
迁移到 ASP.NET Core 标识
有关迁移现有标识存储的详细信息和指南,请参阅迁移身份验证和标识。
设置密码强度
有关设置最小密码要求的示例,请参阅配置。
后续步骤
下一篇:Spa 的身份验证和授权