Общие сведения о Identity ASP.NET Core
Автор: Рик Андерсон (Rick Anderson)
ASP.NET Core Identity:
- Api, поддерживающий функции входа в пользовательский интерфейс.
- Управляет пользователями, паролями, данными профиля, ролями, утверждениями, маркерами, подтверждением электронной почты и т. д.
Пользователи могут создать учетную запись с данными для входа, хранящимися в Identity ней, или использовать внешний поставщик входа. Поддерживаемые внешние поставщики входа включают Facebook, Google, Учетную запись Майкрософт и Twitter.
Дополнительные сведения о том, как глобально требовать проверку подлинности всех пользователей, см. в разделе Требовать проверку подлинности пользователей.
Исходный Identity код доступен на сайте GitHub. Identity Шаблон и просмотр созданных файлов для просмотра взаимодействия с Identityшаблоном.
Identity обычно настраивается с помощью базы данных SQL Server для хранения имен пользователей, паролей и данных профиля. Кроме того, можно использовать другое постоянное хранилище, например хранилище таблиц Azure.
В этом разделе описано, как Identity зарегистрировать, войти и выйти из него. Примечание. Шаблоны обрабатывают имя пользователя и электронную почту так же, как и для пользователей. Дополнительные инструкции по созданию приложений, которые используются Identity, см. в разделе "Дальнейшие действия".
ASP.NET Core Identity не связан с платформой Майкрософтidentity. Платформа Майкрософт identity :
- Эволюция платформы разработчиков Azure Active Directory (Azure AD).
- Альтернативное identity решение для проверки подлинности и авторизации в приложениях ASP.NET Core.
ASP.NET Core Identity позволяет использовать функцию входа в пользовательском интерфейсе для веб-приложений ASP.NET Core. Чтобы защитить веб-API и одностраничные приложения, используйте один из следующих способов:
- Microsoft Entra ID
- Azure Active Directory B2C (Azure AD B2C)
- Duende Identity Server
Duende Identity Server — это платформа OpenID Connect и OAuth 2.0 для ASP.NET Core. Duende Identity Server включает следующие функции безопасности:
- Проверка подлинности как услуга (AaaS)
- Единый вход (SSO) для нескольких типов приложений
- Контроль доступа для API
- Шлюз федерации
Внимание
Компания Duende Software может потребовать лицензионный сбор за использование Duende IdentityServer в рабочей среде. Дополнительные сведения см. в статье Миграция с ASP.NET Core 5.0 на 6.0.
Дополнительные сведения см. в документации по Duende Identity Server (на веб-сайте ПО Duende).
Просмотр или скачивание примера кода (как скачать).
Создание веб-приложения с проверкой подлинности
Создайте проект веб-приложения ASP.NET Core с отдельными учетными записями пользователей.
- Выберите шаблон Веб-приложение ASP.NET Core. Назовите проект WebApp1 тем же пространством имен, что и скачивание проекта. Щелкните OK.
- В поле входных данных Тип проверки подлинности выберите Отдельные учетные записи пользователей.
Созданный проект предоставляет ASP.NET Core Identityв виде библиотеки Razorклассов. Библиотека IdentityRazor классов предоставляет конечные точки с областью Identity
. Например:
- /Identity/Account/Login
- /Identity/Account/Logout
- /Identity/Account/Manage
Применение миграции
Примените миграции для инициализации базы данных.
Выполните следующую команду в консоли диспетчер пакетов (PMC):
Update-Database
Проверка регистрации и входа
Запустите приложение и зарегистрируйте пользователя. В зависимости от размера экрана может потребоваться выбрать кнопку переключателя навигации, чтобы просмотреть ссылки "Регистрация и вход ".
Identity Просмотр базы данных
- В меню "Вид" выберите SQL Server обозреватель объектов (SSOX).
- Перейдите к (localdb)MSSQLLocalDB(SQL Server 13). Щелкните правой кнопкой мыши dbo. AspNetUsers>view Data:
Настройка Identity служб
Службы добавляются в Program.cs
. Типичным шаблоном является вызов методов в следующем порядке:
Add{Service}
builder.Services.Configure{Service}
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using WebApp1.Data;
var builder = WebApplication.CreateBuilder(args);
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(connectionString));
builder.Services.AddDatabaseDeveloperPageExceptionFilter();
builder.Services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
.AddEntityFrameworkStores<ApplicationDbContext>();
builder.Services.AddRazorPages();
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;
});
builder.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;
});
var app = builder.Build();
if (app.Environment.IsDevelopment())
{
app.UseMigrationsEndPoint();
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
Предыдущий код настраивается Identity со значениями параметров по умолчанию. Службы становятся доступными для приложения с помощью внедрения зависимостей.
Identity включен путем вызова UseAuthentication. UseAuthentication
добавляет ПО промежуточного слоя проверки подлинности в конвейер запросов.
Созданное шаблоном приложение не использует авторизацию. app.UseAuthorization
включается, чтобы убедиться, что он добавлен в правильном порядке, если приложение добавит авторизацию. UseRouting
, UseAuthentication
и UseAuthorization
должен вызываться в порядке, приведенном в приведенном выше коде.
Дополнительные сведения см. в IdentityOptions
разделе IdentityOptions и запуске приложения.
Шаблон Register, Login, LogOut и RegisterConfirmation
Register
Добавьте , и LogOut
Login
RegisterConfirmation
файлы. identity Razor Следуйте инструкциям по созданию кода, показанного в этом разделе, в проекте с инструкциями по авторизации.
Проверка регистра
Когда пользователь нажимает кнопку "Зарегистрировать" на Register
странице, RegisterModel.OnPostAsync
вызывается действие. Пользователь создается CreateAsync(TUser) в объекте _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();
}
Отключение проверки учетной записи по умолчанию
При использовании шаблонов по умолчанию пользователь перенаправляется на Account.RegisterConfirmation
место, где можно выбрать ссылку, чтобы подтвердить учетную запись. Значение по умолчанию Account.RegisterConfirmation
используется только для тестирования, автоматическая проверка учетной записи должна быть отключена в рабочем приложении.
Чтобы требовать подтвержденную учетную запись и предотвратить немедленный вход при регистрации, задайте DisplayConfirmAccountLink = false
в /Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs
:
[AllowAnonymous]
public class RegisterConfirmationModel : PageModel
{
private readonly UserManager<IdentityUser> _userManager;
private readonly IEmailSender _sender;
public RegisterConfirmationModel(UserManager<IdentityUser> userManager, IEmailSender sender)
{
_userManager = userManager;
_sender = sender;
}
public string Email { get; set; }
public bool DisplayConfirmAccountLink { get; set; }
public string EmailConfirmationUrl { get; set; }
public async Task<IActionResult> OnGetAsync(string email, string returnUrl = null)
{
if (email == null)
{
return RedirectToPage("/Index");
}
var user = await _userManager.FindByEmailAsync(email);
if (user == null)
{
return NotFound($"Unable to load user with email '{email}'.");
}
Email = email;
// Once you add a real email sender, you should remove this code that lets you confirm the account
DisplayConfirmAccountLink = false;
if (DisplayConfirmAccountLink)
{
var userId = await _userManager.GetUserIdAsync(user);
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
EmailConfirmationUrl = Url.Page(
"/Account/ConfirmEmail",
pageHandler: null,
values: new { area = "Identity", userId = userId, code = code, returnUrl = returnUrl },
protocol: Request.Scheme);
}
return Page();
}
}
Вход в систему
Форма входа отображается в следующих случаях:
- Выбрана ссылка на вход .
- Пользователь пытается получить доступ к ограниченной странице, к ней не разрешен доступ или когда он не прошел проверку подлинности в системе.
При отправке OnPostAsync
формы на странице входа вызывается действие. PasswordSignInAsync
вызывается для _signInManager
объекта.
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();
}
Сведения о том, как принимать решения об авторизации, см. в разделе "Введение в авторизацию" в ASP.NET Core.
Выход
Ссылка выхода вызывает 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();
должен быть перенаправлен, чтобы браузер выполнял новый запрос, а identity пользователь обновляется.
SignOutAsync очищает утверждения пользователя, хранящиеся в объекте cookie.
Запись указана в следующих параметрах 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>
Тест Identity
Шаблоны веб-проектов по умолчанию разрешают анонимный доступ к страницам home . Чтобы проверить Identity, добавьте [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()
{
}
}
}
Если вы вошли, выйдите из нее. Запустите приложение и выберите ссылку Privacy . Вы перейдете на страницу входа.
Изучение Identity
Дополнительные сведения см. в следующем Identity разделе:
- Создание полного identity источника пользовательского интерфейса
- Изучите источник каждой страницы и выполните шаг через отладчик.
Identity Components
Все пакеты NuGet, зависящие от зависимогоIdentity, включены в общую платформу ASP.NET Core.
Основной пакет для Identity этого является Microsoft.AspNetCore.Identity. Этот пакет содержит основной набор интерфейсов для ASP.NET Core Identityи включается Microsoft.AspNetCore.Identity.EntityFrameworkCore
в него.
Миграция на ASP.NET Core Identity
Дополнительные сведения и рекомендации по переносу существующего Identity хранилища см. в разделе "Миграция проверки подлинности" и Identity"Миграция".
Настройка надежности пароля
См . пример конфигурации , который задает минимальные требования к паролям.
AddDefaultIdentity и AddIdentity
AddDefaultIdentity появилась в ASP.NET Core 2.1. Вызов аналогичен вызову AddDefaultIdentity
следующего:
Дополнительные сведения см . в источнике AddDefaultIdentity.
Запрет публикации статических Identity ресурсов
Чтобы предотвратить публикацию статических Identity ресурсов (таблиц стилей и файлов JavaScript для Identity пользовательского интерфейса) в корневой веб-сайт, добавьте следующее ResolveStaticWebAssetsInputsDependsOn
свойство и RemoveIdentityAssets
целевой объект в файл проекта приложения:
<PropertyGroup>
<ResolveStaticWebAssetsInputsDependsOn>RemoveIdentityAssets</ResolveStaticWebAssetsInputsDependsOn>
</PropertyGroup>
<Target Name="RemoveIdentityAssets">
<ItemGroup>
<StaticWebAsset Remove="@(StaticWebAsset)" Condition="%(SourceId) == 'Microsoft.AspNetCore.Identity.UI'" />
</ItemGroup>
</Target>
Next Steps
- Сведения о настройке Identity с помощью SQLite см. в этой проблеме с GitHub.
- Настройка Identity
- Создание приложения ASP.NET Core с защитой данных пользователя с помощью авторизации
- Добавление, скачивание и удаление пользовательских данных Identity в проект ASP.NET Core
- Включение создания QR-кодов для приложений проверки подлинности TOTP в ASP.NET Core
- Миграция проверки подлинности и Identity ASP.NET Core
- Подтверждение учетной записи и восстановление пароля в ASP.NET Core
- Двухфакторная проверка подлинности с помощью SMS в ASP.NET Core
- Узел ASP.NET Core в веб-ферме
Автор: Рик Андерсон (Rick Anderson)
ASP.NET Core Identity:
- Api, поддерживающий функции входа в пользовательский интерфейс.
- Управляет пользователями, паролями, данными профиля, ролями, утверждениями, маркерами, подтверждением электронной почты и т. д.
Пользователи могут создать учетную запись с данными для входа, хранящимися в Identity ней, или использовать внешний поставщик входа. Поддерживаемые внешние поставщики входа включают Facebook, Google, Учетную запись Майкрософт и Twitter.
Дополнительные сведения о том, как глобально требовать проверку подлинности всех пользователей, см. в разделе Требовать проверку подлинности пользователей.
Исходный Identity код доступен на сайте GitHub. Identity Шаблон и просмотр созданных файлов для просмотра взаимодействия с Identityшаблоном.
Identity обычно настраивается с помощью базы данных SQL Server для хранения имен пользователей, паролей и данных профиля. Кроме того, можно использовать другое постоянное хранилище, например хранилище таблиц Azure.
В этом разделе описано, как Identity зарегистрировать, войти и выйти из него. Примечание. Шаблоны обрабатывают имя пользователя и электронную почту так же, как и для пользователей. Дополнительные инструкции по созданию приложений, которые используются Identity, см. в разделе "Дальнейшие действия".
Платформа Майкрософтidentity:
- Эволюция платформы разработчиков Azure Active Directory (Azure AD).
- Альтернативное identity решение для проверки подлинности и авторизации в приложениях ASP.NET Core.
- Не связан с ASP.NET Core Identity.
ASP.NET Core Identity позволяет использовать функцию входа в пользовательском интерфейсе для веб-приложений ASP.NET Core. Чтобы защитить веб-API и одностраничные приложения, используйте один из следующих способов:
- Microsoft Entra ID
- Azure Active Directory B2C (Azure AD B2C)
- Duende IdentityServer. Duende IdentityServer — это сторонний продукт.
Duende IdentityServer — это платформа OpenID Connect и OAuth 2.0 для ASP.NET Core. Duende IdentityServer включает следующие функции безопасности:
- Проверка подлинности как услуга (AaaS)
- Единый вход (SSO) для нескольких типов приложений
- Контроль доступа для API
- Шлюз федерации
Дополнительные сведения см. в разделе "Обзор Duende IdentityServer".
Дополнительные сведения о других поставщиках проверки подлинности см. в разделе "Параметры проверки подлинности Community OSS" для ASP.NET Core
Просмотр или скачивание примера кода (как скачать).
Создание веб-приложения с проверкой подлинности
Создайте проект веб-приложения ASP.NET Core с отдельными учетными записями пользователей.
- Выберите File>New>Project ( Файл > Создать > Проект).
- Выберите Веб-приложение ASP.NET Core. Назовите проект WebApp1 тем же пространством имен, что и скачивание проекта. Щелкните OK.
- Выберите веб-приложение ASP.NET Core, а затем нажмите кнопку "Изменить проверку подлинности".
- Выберите отдельные учетные записи пользователей и нажмите кнопку "ОК".
Созданный проект предоставляет ASP.NET Core Identityв виде библиотеки Razorклассов. Библиотека IdentityRazor классов предоставляет конечные точки с областью Identity
. Например:
- /Identity/Account/Login
- /Identity/Account/Logout
- /Identity/Account/Manage
Применение миграции
Примените миграции для инициализации базы данных.
Выполните следующую команду в консоли диспетчер пакетов (PMC):
PM> Update-Database
Проверка регистрации и входа
Запустите приложение и зарегистрируйте пользователя. В зависимости от размера экрана может потребоваться выбрать кнопку переключателя навигации, чтобы просмотреть ссылки "Регистрация и вход ".
Identity Просмотр базы данных
- В меню "Вид" выберите SQL Server обозреватель объектов (SSOX).
- Перейдите к (localdb)MSSQLLocalDB(SQL Server 13). Щелкните правой кнопкой мыши dbo. AspNetUsers>view Data:
Настройка Identity служб
Службы добавляются в ConfigureServices
. По стандартному шаблону сначала вызываются все методы Add{Service}
, а затем все методы services.Configure{Service}
.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
// options.UseSqlite(
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;
});
}
Предыдущий выделенный код настраивается Identity со значениями параметров по умолчанию. Службы становятся доступными для приложения с помощью внедрения зависимостей.
Identity включен путем вызова 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();
});
}
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
// options.UseSqlite(
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDatabaseDeveloperPageExceptionFilter();
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;
});
}
Предыдущий код настраивается Identity со значениями параметров по умолчанию. Службы становятся доступными для приложения с помощью внедрения зависимостей.
Identity включен путем вызова UseAuthentication. UseAuthentication
добавляет ПО промежуточного слоя проверки подлинности в конвейер запросов.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseMigrationsEndPoint();
}
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 " Запуск приложения".
Шаблон Register, Login, LogOut и RegisterConfirmation
Register
Добавьте , и LogOut
Login
RegisterConfirmation
файлы. identity Razor Следуйте инструкциям по созданию кода, показанного в этом разделе, в проекте с инструкциями по авторизации.
Проверка регистра
Когда пользователь нажимает кнопку "Зарегистрировать" на Register
странице, RegisterModel.OnPostAsync
вызывается действие. Пользователь создается CreateAsync(TUser) в объекте _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();
}
Отключение проверки учетной записи по умолчанию
При использовании шаблонов по умолчанию пользователь перенаправляется на Account.RegisterConfirmation
место, где можно выбрать ссылку, чтобы подтвердить учетную запись. Значение по умолчанию Account.RegisterConfirmation
используется только для тестирования, автоматическая проверка учетной записи должна быть отключена в рабочем приложении.
Чтобы требовать подтвержденную учетную запись и предотвратить немедленный вход при регистрации, задайте DisplayConfirmAccountLink = false
в /Areas/Identity/Pages/Account/RegisterConfirmation.cshtml.cs
:
[AllowAnonymous]
public class RegisterConfirmationModel : PageModel
{
private readonly UserManager<IdentityUser> _userManager;
private readonly IEmailSender _sender;
public RegisterConfirmationModel(UserManager<IdentityUser> userManager, IEmailSender sender)
{
_userManager = userManager;
_sender = sender;
}
public string Email { get; set; }
public bool DisplayConfirmAccountLink { get; set; }
public string EmailConfirmationUrl { get; set; }
public async Task<IActionResult> OnGetAsync(string email, string returnUrl = null)
{
if (email == null)
{
return RedirectToPage("/Index");
}
var user = await _userManager.FindByEmailAsync(email);
if (user == null)
{
return NotFound($"Unable to load user with email '{email}'.");
}
Email = email;
// Once you add a real email sender, you should remove this code that lets you confirm the account
DisplayConfirmAccountLink = false;
if (DisplayConfirmAccountLink)
{
var userId = await _userManager.GetUserIdAsync(user);
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
EmailConfirmationUrl = Url.Page(
"/Account/ConfirmEmail",
pageHandler: null,
values: new { area = "Identity", userId = userId, code = code, returnUrl = returnUrl },
protocol: Request.Scheme);
}
return Page();
}
}
Вход в систему
Форма входа отображается в следующих случаях:
- Выбрана ссылка на вход .
- Пользователь пытается получить доступ к ограниченной странице, к ней не разрешен доступ или когда он не прошел проверку подлинности в системе.
При отправке OnPostAsync
формы на странице входа вызывается действие. PasswordSignInAsync
вызывается для _signInManager
объекта.
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();
}
Сведения о том, как принимать решения об авторизации, см. в разделе "Введение в авторизацию" в ASP.NET Core.
Выход
Ссылка выхода вызывает 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();
должен быть перенаправлен, чтобы браузер выполнял новый запрос, а identity пользователь обновляется.
SignOutAsync очищает утверждения пользователя, хранящиеся в объекте cookie.
Запись указана в следующих параметрах 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>
Тест Identity
Шаблоны веб-проектов по умолчанию разрешают анонимный доступ к страницам home . Чтобы проверить Identity, добавьте [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()
{
}
}
}
Если вы вошли, выйдите из нее. Запустите приложение и выберите ссылку Privacy . Вы перейдете на страницу входа.
Изучение Identity
Дополнительные сведения см. в следующем Identity разделе:
- Создание полного identity источника пользовательского интерфейса
- Изучите источник каждой страницы и выполните шаг через отладчик.
Identity Components
Все пакеты NuGet, зависящие от зависимогоIdentity, включены в общую платформу ASP.NET Core.
Основной пакет для Identity этого является Microsoft.AspNetCore.Identity. Этот пакет содержит основной набор интерфейсов для ASP.NET Core Identityи включается Microsoft.AspNetCore.Identity.EntityFrameworkCore
в него.
Миграция на ASP.NET Core Identity
Дополнительные сведения и рекомендации по переносу существующего Identity хранилища см. в разделе "Миграция проверки подлинности" и Identity"Миграция".
Настройка надежности пароля
См . пример конфигурации , который задает минимальные требования к паролям.
Запрет публикации статических Identity ресурсов
Чтобы предотвратить публикацию статических Identity ресурсов (таблиц стилей и файлов JavaScript для Identity пользовательского интерфейса) в корневой веб-сайт, добавьте следующее ResolveStaticWebAssetsInputsDependsOn
свойство и RemoveIdentityAssets
целевой объект в файл проекта приложения:
<PropertyGroup>
<ResolveStaticWebAssetsInputsDependsOn>RemoveIdentityAssets</ResolveStaticWebAssetsInputsDependsOn>
</PropertyGroup>
<Target Name="RemoveIdentityAssets">
<ItemGroup>
<StaticWebAsset Remove="@(StaticWebAsset)" Condition="%(SourceId) == 'Microsoft.AspNetCore.Identity.UI'" />
</ItemGroup>
</Target>
Next Steps
- исходный код ASP.NET Core Identity
- Источник AddDefaultIdentity
- Сведения о настройке Identity с помощью SQLite см. в этой проблеме с GitHub.
- Настройка Identity
- Создание приложения ASP.NET Core с защитой данных пользователя с помощью авторизации
- Добавление, скачивание и удаление пользовательских данных Identity в проект ASP.NET Core
- Включение создания QR-кодов для приложений проверки подлинности TOTP в ASP.NET Core
- Миграция проверки подлинности и Identity ASP.NET Core
- Подтверждение учетной записи и восстановление пароля в ASP.NET Core
- Двухфакторная проверка подлинности с помощью SMS в ASP.NET Core
- Узел ASP.NET Core в веб-ферме
ASP.NET Core