Поделиться через


Использование cookie проверки подлинности без ASP.NET Core Identity

Автор: Рик Андерсон (Rick Anderson)

ASP.NET Core Identity — это полный полнофункциональный поставщик проверки подлинности для создания и обслуживания имен входа. cookieОднако поставщик проверки подлинности на основе основе без ASP.NET Core Identity можно использовать. Дополнительные сведения см. в статье Введение в Identity в ASP.NET Core.

Просмотреть или скачать образец кода (описание загрузки)

Для демонстрационных целей в примере приложения учетная запись пользователя для гипотетического пользователя Maria Rodriguez жестко закодирована в приложение. Используйте адрес maria.rodriguez@contoso.com электронной почты и любой пароль для входа пользователя. Пользователь проходит проверку подлинности в методе AuthenticateUser Pages/Account/Login.cshtml.cs в файле. В реальном примере пользователь будет проходить проверку подлинности в хранилище данных.

  • Добавьте службы ПО промежуточного слоя проверки подлинности с AddAuthentication помощью методов и AddCookie методов.
  • Вызовите UseAuthentication и задайте HttpContext.User свойство и UseAuthorization запустите ПО промежуточного слоя авторизации для запросов. UseAuthentication и UseAuthorization должен вызываться перед Map такими методами, как MapRazorPages и MapDefaultControllerRoute
using Microsoft.AspNetCore.Authentication.Cookies;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie();

builder.Services.AddHttpContextAccessor();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseAuthentication();
app.UseAuthorization();

app.MapRazorPages();
app.MapDefaultControllerRoute();

app.Run();

AuthenticationScheme передается для AddAuthentication установки схемы проверки подлинности по умолчанию для приложения. AuthenticationSchemeполезно при наличии нескольких экземпляров cookie проверки подлинности, и приложению необходимо авторизовать определенную схему. AuthenticationScheme Параметр CookieAuthenticationDefaults.AuthenticationScheme предоставляет значение "Cookies" схемы. Любое строковое значение можно использовать, которое отличает схему.

Схема проверки подлинности приложения отличается от схемы проверки подлинности приложения cookie . cookie Если схема проверки подлинности не предоставляетсяAddCookie, она используетсяCookieAuthenticationDefaults.AuthenticationScheme. В источнике CookieAuthenticationDefaults.AuthenticationScheme GitHub показано, что для него задано "Cookies"значение .

Свойство проверки подлинности cookieIsEssential задано true по умолчанию. Файлы cookie проверки подлинности разрешены, если посетитель сайта не предоставил согласие на сбор данных. Дополнительные сведения см. в разделе Общий регламент по защите данных (GDPR), принятый в ЕС, в ASP.NET Core.

Класс CookieAuthenticationOptions используется для настройки параметров поставщика проверки подлинности.

Настройте CookieAuthenticationOptions в методе AddCookie :

using Microsoft.AspNetCore.Authentication.Cookies;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.ExpireTimeSpan = TimeSpan.FromMinutes(20);
        options.SlidingExpiration = true;
        options.AccessDeniedPath = "/Forbidden/";
    });

builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseAuthentication();
app.UseAuthorization();

app.MapRazorPages();
app.MapDefaultControllerRoute();

app.Run();

ПО Cookie промежуточного слоя политики (источник GitHub) UseCookiePolicy включает cookie возможности политики. ПО промежуточного слоя обрабатывается в том порядке, в который он добавлен:

app.UseCookiePolicy(cookiePolicyOptions);

Используйте CookiePolicyOptions по промежуточному Cookie слоя политики для управления глобальными характеристиками cookie обработки и перехватчика в cookie обработчики обработки при добавлении или удалении файлов cookie.

Значением по умолчанию MinimumSameSitePolicy является SameSiteMode.Lax разрешение проверки подлинности OAuth2. Чтобы строго применить ту же политику SameSiteMode.Strictсайта, задайте параметр MinimumSameSitePolicy. Хотя этот параметр нарушает OAuth2 и другие схемы межуровневой проверки подлинности, он повышает уровень cookie безопасности для других типов приложений, которые не используют обработку запросов между источниками.

var cookiePolicyOptions = new CookiePolicyOptions
{
    MinimumSameSitePolicy = SameSiteMode.Strict,
};

Параметр Cookie MinimumSameSitePolicy ПО промежуточного Cookie.SameSite слоя политики может повлиять на настройку параметров в CookieAuthenticationOptions соответствии с приведенной ниже матрицой.

MinimumSameSitePolicy Cookie. SameSite Результирующий Cookie. Параметр SameSite
SameSiteMode.None SameSiteMode.None
SameSiteMode.Lax
SameSiteMode.Strict
SameSiteMode.None
SameSiteMode.Lax
SameSiteMode.Strict
SameSiteMode.Lax SameSiteMode.None
SameSiteMode.Lax
SameSiteMode.Strict
SameSiteMode.Lax
SameSiteMode.Lax
SameSiteMode.Strict
SameSiteMode.Strict SameSiteMode.None
SameSiteMode.Lax
SameSiteMode.Strict
SameSiteMode.Strict
SameSiteMode.Strict
SameSiteMode.Strict

Чтобы создать удерживаемую cookie информацию пользователя, создайте объект ClaimsPrincipal. Сведения о пользователе сериализуются и хранятся в объекте cookie.

Создайте все необходимые ClaimsIdentity Claims и вызов SignInAsync для входа пользователя. Login.cshtml.cs В примере приложения содержится следующий код:

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    ReturnUrl = returnUrl;

    if (ModelState.IsValid)
    {
        // Use Input.Email and Input.Password to authenticate the user
        // with your custom authentication logic.
        //
        // For demonstration purposes, the sample validates the user
        // on the email address maria.rodriguez@contoso.com with 
        // any password that passes model validation.

        var user = await AuthenticateUser(Input.Email, Input.Password);

        if (user == null)
        {
            ModelState.AddModelError(string.Empty, "Invalid login attempt.");
            return Page();
        }

        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.Name, user.Email),
            new Claim("FullName", user.FullName),
            new Claim(ClaimTypes.Role, "Administrator"),
        };

        var claimsIdentity = new ClaimsIdentity(
            claims, CookieAuthenticationDefaults.AuthenticationScheme);

        var authProperties = new AuthenticationProperties
        {
            //AllowRefresh = <bool>,
            // Refreshing the authentication session should be allowed.

            //ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(10),
            // The time at which the authentication ticket expires. A 
            // value set here overrides the ExpireTimeSpan option of 
            // CookieAuthenticationOptions set with AddCookie.

            //IsPersistent = true,
            // Whether the authentication session is persisted across 
            // multiple requests. When used with cookies, controls
            // whether the cookie's lifetime is absolute (matching the
            // lifetime of the authentication ticket) or session-based.

            //IssuedUtc = <DateTimeOffset>,
            // The time at which the authentication ticket was issued.

            //RedirectUri = <string>
            // The full path or absolute URI to be used as an http 
            // redirect response value.
        };

        await HttpContext.SignInAsync(
            CookieAuthenticationDefaults.AuthenticationScheme, 
            new ClaimsPrincipal(claimsIdentity), 
            authProperties);

        _logger.LogInformation("User {Email} logged in at {Time}.", 
            user.Email, DateTime.UtcNow);

        return LocalRedirect(Url.GetLocalUrl(returnUrl));
    }

    // Something failed. Redisplay the form.
    return Page();
}

Если вы хотите увидеть комментарии к коду, переведенные на языки, отличные от английского, сообщите нам на странице обсуждения этой проблемы на сайте GitHub.

SignInAsync создает зашифрованный cookie и добавляет его в текущий ответ. Если AuthenticationScheme не указано, используется схема по умолчанию.

RedirectUri используется только для нескольких определенных путей по умолчанию, например пути входа и пути выхода. Дополнительные сведения см. в источнике CookieAuthenticationHandler.

ASP.NET система защиты данных Core используется для шифрования. Для приложения, размещенного на нескольких компьютерах, балансировка нагрузки между приложениями или использование веб-фермы, настройка защиты данных для использования одного и того же ключа и идентификатора приложения.

Выйти

Чтобы выйти из текущего пользователя и удалить его cookie, вызовите SignOutAsync:

public async Task OnGetAsync(string returnUrl = null)
{
    if (!string.IsNullOrEmpty(ErrorMessage))
    {
        ModelState.AddModelError(string.Empty, ErrorMessage);
    }

    // Clear the existing external cookie
    await HttpContext.SignOutAsync(
        CookieAuthenticationDefaults.AuthenticationScheme);

    ReturnUrl = returnUrl;
}

Если CookieAuthenticationDefaults.AuthenticationScheme или "Файлы cookie" не используются в качестве схемы, укажите схему, используемую при настройке поставщика проверки подлинности. В противном случае используется схема по умолчанию. Например, если в качестве схемы используется contosoCookie, укажите схему, используемую при настройке поставщика проверки подлинности.

Когда браузер закрывает его автоматически, удаляет файлы cookie на основе сеанса (не постоянные файлы cookie), но при закрытии отдельной вкладки файлы cookie не удаляются. Сервер уведомляется о событиях закрытия вкладки или браузера.

Реагирование на внутренние изменения

cookie После создания cookie является единственным источником identity. Если учетная запись пользователя отключена в внутренних системах:

  • Система проверки подлинности приложения cookie продолжает обрабатывать запросы на основе проверки подлинности cookie.
  • Пользователь остается вошедшего в приложение до тех пор, пока проверка подлинности действительна cookie .

Событие ValidatePrincipal можно использовать для перехвата и переопределения проверки cookieidentity. Проверка cookie каждого запроса снижает риск отзываемых пользователей, обращаюющихся к приложению.

Один из подходов к cookie проверке основан на отслеживании изменений пользовательской базы данных. Если база данных не была изменена после выдачи пользователя cookie , вам не нужно повторно пройти проверку подлинности пользователя, если он cookie по-прежнему действителен. В примере приложения база данных реализуется IUserRepository и сохраняет LastChanged значение. При обновлении пользователя в базе данных LastChanged значение задается в текущее время.

Чтобы сделать недействительным, cookie когда база данных изменяется на LastChanged основе значения, создайте cookie утверждение с LastChanged текущим LastChanged значением из базы данных:

var claims = new List<Claim>
{
    new Claim(ClaimTypes.Name, user.Email),
    new Claim("LastChanged", {Database Value})
};

var claimsIdentity = new ClaimsIdentity(
    claims,
    CookieAuthenticationDefaults.AuthenticationScheme);

await HttpContext.SignInAsync(
    CookieAuthenticationDefaults.AuthenticationScheme, 
    new ClaimsPrincipal(claimsIdentity));

Чтобы реализовать переопределение для ValidatePrincipal события, напишите метод со следующей сигнатурой в классе, наследуемом от CookieAuthenticationEvents:

ValidatePrincipal(CookieValidatePrincipalContext)

Ниже приведен пример реализации CookieAuthenticationEvents:

using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;

public class CustomCookieAuthenticationEvents : CookieAuthenticationEvents
{
    private readonly IUserRepository _userRepository;

    public CustomCookieAuthenticationEvents(IUserRepository userRepository)
    {
        _userRepository = userRepository;
    }

    public override async Task ValidatePrincipal(CookieValidatePrincipalContext context)
    {
        var userPrincipal = context.Principal;

        // Look for the LastChanged claim.
        var lastChanged = (from c in userPrincipal.Claims
                           where c.Type == "LastChanged"
                           select c.Value).FirstOrDefault();

        if (string.IsNullOrEmpty(lastChanged) ||
            !_userRepository.ValidateLastChanged(lastChanged))
        {
            context.RejectPrincipal();

            await context.HttpContext.SignOutAsync(
                CookieAuthenticationDefaults.AuthenticationScheme);
        }
    }
}

Зарегистрируйте экземпляр событий во время cookie регистрации службы. Укажите регистрацию службы с областью действия для классаCustomCookieAuthenticationEvents:

using Microsoft.AspNetCore.Authentication.Cookies;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddRazorPages();
builder.Services.AddControllersWithViews();

builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.EventsType = typeof(CustomCookieAuthenticationEvents);
    });

builder.Services.AddScoped<CustomCookieAuthenticationEvents>();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseAuthentication();
app.UseAuthorization();

app.MapRazorPages();
app.MapDefaultControllerRoute();

app.Run();

Рассмотрим ситуацию, в которой имя пользователя обновляется— решение, которое не влияет на безопасность каким-либо образом. Если вы хотите неразрушительно обновить субъект пользователя, вызовите context.ReplacePrincipal и задайте context.ShouldRenew для trueсвойства значение .

Предупреждение

Описанный здесь подход активируется при каждом запросе. Проверка файлов cookie проверки подлинности для всех пользователей на каждом запросе может привести к большому штрафу за производительность приложения.

Постоянные файлы cookie

Возможно, cookie потребуется сохраниться в сеансах браузера. Эта сохраняемость должна быть включена только с явным согласием пользователя с флажком "Запомнить меня" для входа или аналогичного механизма.

В следующем фрагменте кода создается и соответствующий identity cookie код, который выживает с помощью закрытия браузера. Все параметры скользящего срока действия, настроенные ранее, учитываются. cookie Если срок действия истекает во время закрытия браузера, браузер очищает cookie его после перезапуска.

Задано IsPersistent вAuthenticationPropertiestrue:

// using Microsoft.AspNetCore.Authentication;

await HttpContext.SignInAsync(
    CookieAuthenticationDefaults.AuthenticationScheme,
    new ClaimsPrincipal(claimsIdentity),
    new AuthenticationProperties
    {
        IsPersistent = true
    });

Абсолютное время окончания срока действия можно задать с ExpiresUtcпомощью . Чтобы создать постоянный cookieобъект, IsPersistent также необходимо задать. cookie В противном случае создается с временем существования на основе сеанса и может истекнуть срок действия до или после запроса проверки подлинности, который он содержит. Если ExpiresUtc задано, он переопределяет значение ExpireTimeSpan параметра CookieAuthenticationOptions, если задано.

В следующем фрагменте кода создается identity и соответствующее cookie значение, которое длится 20 минут. Это игнорирует все параметры скользящего срока действия, настроенные ранее.

// using Microsoft.AspNetCore.Authentication;

await HttpContext.SignInAsync(
    CookieAuthenticationDefaults.AuthenticationScheme,
    new ClaimsPrincipal(claimsIdentity),
    new AuthenticationProperties
    {
        IsPersistent = true,
        ExpiresUtc = DateTime.UtcNow.AddMinutes(20)
    });

ASP.NET Core Identity — это полный полнофункциональный поставщик проверки подлинности для создания и обслуживания имен входа. cookieОднако поставщик проверки подлинности на основе основе без ASP.NET Core Identity можно использовать. Дополнительные сведения см. в статье Введение в Identity в ASP.NET Core.

Просмотреть или скачать образец кода (описание загрузки)

Для демонстрационных целей в примере приложения учетная запись пользователя для гипотетического пользователя Maria Rodriguez жестко закодирована в приложение. Используйте адрес maria.rodriguez@contoso.com электронной почты и любой пароль для входа пользователя. Пользователь проходит проверку подлинности в методе AuthenticateUser Pages/Account/Login.cshtml.cs в файле. В реальном примере пользователь будет проходить проверку подлинности в базе данных.

Настройка

В методе Startup.ConfigureServices создайте службы ПО промежуточного слоя проверки подлинности с AddAuthentication помощью методов и AddCookie методов:

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie();

AuthenticationScheme передается для AddAuthentication установки схемы проверки подлинности по умолчанию для приложения. AuthenticationSchemeполезно, если имеется несколько экземпляров cookie проверки подлинности, и требуется авторизовать определенную схему. AuthenticationScheme Параметр CookieAuthenticationDefaults.AuthenticationScheme предоставляет значение cookie для схемы. Можно указать любое строковое значение, которое отличает схему.

Схема проверки подлинности приложения отличается от схемы проверки подлинности приложения cookie . cookie Если схема проверки подлинности не предоставляетсяAddCookie, она использует CookieAuthenticationDefaults.AuthenticationScheme ("Файлы cookie").

Свойство проверки подлинности cookieIsEssential задано true по умолчанию. Файлы cookie проверки подлинности разрешены, если посетитель сайта не предоставил согласие на сбор данных. Дополнительные сведения см. в разделе Общий регламент по защите данных (GDPR), принятый в ЕС, в ASP.NET Core.

В Startup.Configure, вызов UseAuthentication и UseAuthorization задание свойства и запуск ПО промежуточного HttpContext.User слоя авторизации для запросов. UseAuthentication Вызовите методы и UseAuthorization методы перед вызовомUseEndpoints:

app.UseAuthentication();
app.UseAuthorization();

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
    endpoints.MapRazorPages();
});

Класс CookieAuthenticationOptions используется для настройки параметров поставщика проверки подлинности.

Задайте CookieAuthenticationOptions в конфигурации службы проверку подлинности в методе Startup.ConfigureServices :

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        ...
    });

Cookie ПО промежуточного слоя политики включает cookie возможности политики. Добавление ПО промежуточного слоя к конвейеру обработки приложений учитывает порядок. Это влияет только на подчиненные компоненты, зарегистрированные в конвейере.

app.UseCookiePolicy(cookiePolicyOptions);

Используйте CookiePolicyOptions по промежуточному Cookie слоя политики для управления глобальными характеристиками cookie обработки и перехватчика в cookie обработчики обработки при добавлении или удалении файлов cookie.

Значением по умолчанию MinimumSameSitePolicy является SameSiteMode.Lax разрешение проверки подлинности OAuth2. Чтобы строго применить ту же политику SameSiteMode.Strictсайта, задайте параметр MinimumSameSitePolicy. Хотя этот параметр нарушает OAuth2 и другие схемы межуровневой проверки подлинности, он повышает уровень cookie безопасности для других типов приложений, которые не используют обработку запросов между источниками.

var cookiePolicyOptions = new CookiePolicyOptions
{
    MinimumSameSitePolicy = SameSiteMode.Strict,
};

Параметр Cookie MinimumSameSitePolicy ПО промежуточного Cookie.SameSite слоя политики может повлиять на настройку параметров в CookieAuthenticationOptions соответствии с приведенной ниже матрицой.

MinimumSameSitePolicy Cookie. SameSite Результирующий Cookie. Параметр SameSite
SameSiteMode.None SameSiteMode.None
SameSiteMode.Lax
SameSiteMode.Strict
SameSiteMode.None
SameSiteMode.Lax
SameSiteMode.Strict
SameSiteMode.Lax SameSiteMode.None
SameSiteMode.Lax
SameSiteMode.Strict
SameSiteMode.Lax
SameSiteMode.Lax
SameSiteMode.Strict
SameSiteMode.Strict SameSiteMode.None
SameSiteMode.Lax
SameSiteMode.Strict
SameSiteMode.Strict
SameSiteMode.Strict
SameSiteMode.Strict

Чтобы создать удерживаемую cookie информацию пользователя, создайте объект ClaimsPrincipal. Сведения о пользователе сериализуются и хранятся в объекте cookie.

ClaimsIdentity Создайте все необходимые Claims и вызов SignInAsync для входа пользователя:

var claims = new List<Claim>
{
    new Claim(ClaimTypes.Name, user.Email),
    new Claim("FullName", user.FullName),
    new Claim(ClaimTypes.Role, "Administrator"),
};

var claimsIdentity = new ClaimsIdentity(
    claims, CookieAuthenticationDefaults.AuthenticationScheme);

var authProperties = new AuthenticationProperties
{
    //AllowRefresh = <bool>,
    // Refreshing the authentication session should be allowed.

    //ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(10),
    // The time at which the authentication ticket expires. A 
    // value set here overrides the ExpireTimeSpan option of 
    // CookieAuthenticationOptions set with AddCookie.

    //IsPersistent = true,
    // Whether the authentication session is persisted across 
    // multiple requests. When used with cookies, controls
    // whether the cookie's lifetime is absolute (matching the
    // lifetime of the authentication ticket) or session-based.

    //IssuedUtc = <DateTimeOffset>,
    // The time at which the authentication ticket was issued.

    //RedirectUri = <string>
    // The full path or absolute URI to be used as an http 
    // redirect response value.
};

await HttpContext.SignInAsync(
    CookieAuthenticationDefaults.AuthenticationScheme, 
    new ClaimsPrincipal(claimsIdentity), 
    authProperties);

Если вы хотите увидеть комментарии к коду, переведенные на языки, отличные от английского, сообщите нам на странице обсуждения этой проблемы на сайте GitHub.

SignInAsync создает зашифрованный cookie и добавляет его в текущий ответ. Если AuthenticationScheme не указано, используется схема по умолчанию.

RedirectUri используется только для нескольких определенных путей по умолчанию, например пути входа и пути выхода. Дополнительные сведения см. в источнике CookieAuthenticationHandler.

ASP.NET система защиты данных Core используется для шифрования. Для приложения, размещенного на нескольких компьютерах, балансировка нагрузки между приложениями или использование веб-фермы, настройка защиты данных для использования одного и того же ключа и идентификатора приложения.

Выйти

Чтобы выйти из текущего пользователя и удалить его cookie, вызовите SignOutAsync:

await HttpContext.SignOutAsync(
    CookieAuthenticationDefaults.AuthenticationScheme);

Если CookieAuthenticationDefaults.AuthenticationScheme (или "Файлы cookie") не используется в качестве схемы (например, ContosoCookie), укажите схему, используемую при настройке поставщика проверки подлинности. В противном случае используется схема по умолчанию.

Когда браузер закрывает его автоматически, удаляет файлы cookie на основе сеанса (не постоянные файлы cookie), но при закрытии отдельной вкладки файлы cookie не удаляются. Сервер уведомляется о событиях закрытия вкладки или браузера.

Реагирование на внутренние изменения

cookie После создания cookie является единственным источником identity. Если учетная запись пользователя отключена в внутренних системах:

  • Система проверки подлинности приложения cookie продолжает обрабатывать запросы на основе проверки подлинности cookie.
  • Пользователь остается вошедшего в приложение до тех пор, пока проверка подлинности действительна cookie .

Событие ValidatePrincipal можно использовать для перехвата и переопределения проверки cookieidentity. Проверка cookie каждого запроса снижает риск отзываемых пользователей, обращаюющихся к приложению.

Один из подходов к cookie проверке основан на отслеживании изменений пользовательской базы данных. Если база данных не была изменена после выдачи пользователя cookie , вам не нужно повторно пройти проверку подлинности пользователя, если он cookie по-прежнему действителен. В примере приложения база данных реализуется IUserRepository и сохраняет LastChanged значение. При обновлении пользователя в базе данных LastChanged значение задается в текущее время.

Чтобы сделать недействительным, cookie когда база данных изменяется на LastChanged основе значения, создайте cookie утверждение с LastChanged текущим LastChanged значением из базы данных:

var claims = new List<Claim>
{
    new Claim(ClaimTypes.Name, user.Email),
    new Claim("LastChanged", {Database Value})
};

var claimsIdentity = new ClaimsIdentity(
    claims, 
    CookieAuthenticationDefaults.AuthenticationScheme);

await HttpContext.SignInAsync(
    CookieAuthenticationDefaults.AuthenticationScheme, 
    new ClaimsPrincipal(claimsIdentity));

Чтобы реализовать переопределение для ValidatePrincipal события, напишите метод со следующей сигнатурой в классе, наследуемом от CookieAuthenticationEvents:

ValidatePrincipal(CookieValidatePrincipalContext)

Ниже приведен пример реализации CookieAuthenticationEvents:

using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;

public class CustomCookieAuthenticationEvents : CookieAuthenticationEvents
{
    private readonly IUserRepository _userRepository;

    public CustomCookieAuthenticationEvents(IUserRepository userRepository)
    {
        // Get the database from registered DI services.
        _userRepository = userRepository;
    }

    public override async Task ValidatePrincipal(CookieValidatePrincipalContext context)
    {
        var userPrincipal = context.Principal;

        // Look for the LastChanged claim.
        var lastChanged = (from c in userPrincipal.Claims
                           where c.Type == "LastChanged"
                           select c.Value).FirstOrDefault();

        if (string.IsNullOrEmpty(lastChanged) ||
            !_userRepository.ValidateLastChanged(lastChanged))
        {
            context.RejectPrincipal();

            await context.HttpContext.SignOutAsync(
                CookieAuthenticationDefaults.AuthenticationScheme);
        }
    }
}

Зарегистрируйте экземпляр событий во время cookie регистрации службы в методе Startup.ConfigureServices . Укажите регистрацию службы с областью действия для классаCustomCookieAuthenticationEvents:

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddCookie(options =>
    {
        options.EventsType = typeof(CustomCookieAuthenticationEvents);
    });

services.AddScoped<CustomCookieAuthenticationEvents>();

Рассмотрим ситуацию, в которой имя пользователя обновляется— решение, которое не влияет на безопасность каким-либо образом. Если вы хотите неразрушительно обновить субъект пользователя, вызовите context.ReplacePrincipal и задайте context.ShouldRenew для trueсвойства значение .

Предупреждение

Описанный здесь подход активируется при каждом запросе. Проверка файлов cookie проверки подлинности для всех пользователей на каждом запросе может привести к большому штрафу за производительность приложения.

Постоянные файлы cookie

Возможно, cookie потребуется сохраниться в сеансах браузера. Эта сохраняемость должна быть включена только с явным согласием пользователя с флажком "Запомнить меня" для входа или аналогичного механизма.

В следующем фрагменте кода создается и соответствующий identity cookie код, который выживает с помощью закрытия браузера. Все параметры скользящего срока действия, настроенные ранее, учитываются. cookie Если срок действия истекает во время закрытия браузера, браузер очищает cookie его после перезапуска.

Задано IsPersistent вAuthenticationPropertiestrue:

// using Microsoft.AspNetCore.Authentication;

await HttpContext.SignInAsync(
    CookieAuthenticationDefaults.AuthenticationScheme,
    new ClaimsPrincipal(claimsIdentity),
    new AuthenticationProperties
    {
        IsPersistent = true
    });

Абсолютное время окончания срока действия можно задать с ExpiresUtcпомощью . Чтобы создать постоянный cookieобъект, IsPersistent также необходимо задать. cookie В противном случае создается с временем существования на основе сеанса и может истекнуть срок действия до или после запроса проверки подлинности, который он содержит. Если ExpiresUtc задано, он переопределяет значение ExpireTimeSpan параметра CookieAuthenticationOptions, если задано.

В следующем фрагменте кода создается identity и соответствующее cookie значение, которое длится 20 минут. Это игнорирует все параметры скользящего срока действия, настроенные ранее.

// using Microsoft.AspNetCore.Authentication;

await HttpContext.SignInAsync(
    CookieAuthenticationDefaults.AuthenticationScheme,
    new ClaimsPrincipal(claimsIdentity),
    new AuthenticationProperties
    {
        IsPersistent = true,
        ExpiresUtc = DateTime.UtcNow.AddMinutes(20)
    });