Использование куки без ASP.NET Core Identity

ASP.NET Core предоставляет связующее ПО куки, которое переводит пользовательские данные в зашифрованные куки, затем валидирует куки, пересоздает данные и присваивает их свойству User в HttpContext.

Выход

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

await HttpContext.Authentication.SignOutAsync("MyCookieMiddlewareInstance");

Реакция на изменения бэкэнда

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

После создания идентификационного куки он становится единственным источником идентификации - даже если вы отключите пользователя в своей системе бэкэнда, связующее ПО куки не будет об этом знать, и пользователь будет залогинен, пока валиден куки.

Связующее ПО куки предлагает набор событий в своем классе опций. Событие ValidateAsync() можно использовать для прерывания и переопределения валидации экземпляра куки.

Представьте себе пользовательскую бэкэнд БД, в которой есть колонка LastChanged. Чтобы аннулировать куки при изменении в БД, вы должны сперва добавить LastChanged, содержащую текущее значение. Затем при изменении в БД значение LastChanged также будет обновлено.

Чтобы переопределить событие ValidateAsync(), вы должны создать метод со следующей сигнатурой:

Task ValidateAsync(CookieValidatePrincipalContext context);

ASP.NET Identity реализует эту проверку как часть SecurityStampValidator. Простой пример выглядит примерно вот так:

public static class LastChangedValidator
{
    public static async Task ValidateAsync(CookieValidatePrincipalContext context)
    {
        // Pull database from registered DI services.
        var userRepository = context.HttpContext.RequestServices.GetRequiredService<IUserRepository>();
        var userPrincipal = context.Principal;

        // Look for the last changed claim.
        string lastChanged;
        lastChanged = (from c in userPrincipal.Claims
                       where c.Type == "LastUpdated"
                       select c.Value).FirstOrDefault();

        if (string.IsNullOrEmpty(lastChanged) ||
            !userRepository.ValidateLastChanged(userPrincipal, lastChanged))
        {
            context.RejectPrincipal();
            await context.HttpContext.Authentication.SignOutAsync("MyCookieMiddlewareInstance");
        }
    }
}

Это будет запускаться во время настройки связующего ПО куки:

app.UseCookieAuthentication(options =>
{
    options.Events = new CookieAuthenticationEvents
    {
        // Set other options
        OnValidatePrincipal = LastChangedValidator.ValidateAsync
    };
});

Если вы хотите внести обновления по-иному, например, сменить только имя пользователя и не затрагивать безопасность, то вам нужно вызвать context.ReplacePrincipal() и установить флажок context.ShouldRenew на true.

Постоянные куки и абсолютное истечение срока действия

Вы можете сделать так, чтобы срок истечения куки запоминался сессиями браузера. Также можно было использовать абсолютное истечение срока действия для идентификации и куки. Вы можете сделать это, использовав параметр AuthenticationProperties для метода HttpContext.Authentication.SignInAsync, который вызывается при входе и создании куки. Класс AuthenticationProperties находится в пространстве имен Microsoft.AspNet.Http.Authentication.

Например:

await HttpContext.Authentication.SignInAsync(
    "MyCookieMiddlewareInstance",
    principal,
    new AuthenticationProperties
    {
        IsPersistent = true
    });

Здесь создается идентификация и соответствующий куки. Любые настройки, ранее сконфигурированные через опции куки будут игнорироваться, если срок истечения куки завершается с закрытием браузера.

await HttpContext.Authentication.SignInAsync(
    "MyCookieMiddlewareInstance",
    principal,
    new AuthenticationProperties
    {
        ExpiresUtc = DateTime.UtcNow.AddMinutes(20)
    });

Здесь создается идентификация и соответствующий куки, который будет длиться 20 минут. Любые настройки, ранее сконфигурированные через опции куки будут игнорироваться.

Свойства ExpiresUtc и IsPersistent можно исключить вручную.

Поделись хорошей новостью с друзьями!
Следи за новостями!