Как получить идентификатор пользователя в том же запросе - Пользовательская проверка подлинности с использованием cookie в Net Core? - PullRequest
0 голосов
/ 14 апреля 2019

Я пытаюсь реализовать свою собственную аутентификацию cookie в .NET CORE 2.2.Я определил пользовательское событие cookie для проверки cookie и проверки того, был ли пользователь заблокирован или аналогичным образом с сервера.

Это событие вызывается сразу после входа пользователя (в том же запросе).У меня проблема User.Identity.isAuthenticated, и претензии пользователя здесь еще не установлены (по-видимому, этого не произойдет до следующего запроса)

Из аналогичных вопросов я убедился, что мой app.UseAuthentication(); подтвержден app.UseMvc();и что я создаю экземпляр моего ClaimsIdentity объекта с AuthenticationType как этот var userIdentity = new ClaimsIdentity(claims, "Basic");

Как я могу обойти значения UserIdentity, которые не были установлены во время того же запроса, когда событие вызывается сразу после входа в систему?

Примечание: мои разные менеджеры являются пользовательскими реализациями - я НЕ использую Microsoft.Identity

Startup.cs:

      services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).
        AddCookie((options) =>
        {
            options.LoginPath = new PathString("/account/login");
            options.LogoutPath = new PathString("/account/logout");
            options.EventsType = typeof(CustomCookieAuthenticationEvents);            
        });

        services.AddScoped<CustomCookieAuthenticationEvents>();

CustomCookieAuthenticationEvents:

    public class CustomCookieAuthenticationEvents : CookieAuthenticationEvents
{
    private readonly ISignInManager _signInManager;
    private readonly HttpContext _context;

    public CustomCookieAuthenticationEvents(ISignInManager signInManager, IHttpContextAccessor context)
    {
        _signInManager = signInManager;
        _context = context.HttpContext;
    }

    public override async Task ValidatePrincipal(CookieValidatePrincipalContext context)
    {
        //TODO retrieve user from database and check if he is locked out OR any values have changed
        var userPrincipal = context.Principal;

        var lastChangedClaim = userPrincipal.Claims.FirstOrDefault(x => x.Type == "Last Changed");

        if (lastChangedClaim == null || !await _signInManager.ValidateLastChanged(lastChangedClaim.Value))
        {
            context.RejectPrincipal();

            await _context.SignOutAsync(
                CookieAuthenticationDefaults.AuthenticationScheme);
        }
    }
}

SignInManager:

        public int GetCurrentUserId()
    {
        //returns false
        if (!_context.User.Identity.IsAuthenticated)
            return -1;

        Claim claim = _context.User.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier);

        if (claim == null)
            return -1;

        int.TryParse(claim.Value, out int currentId);

        return currentId;
    }

    public bool IsSignedIn(ClaimsPrincipal principal)
    {
        return _context.User.Identity.IsAuthenticated;
    }

    public async Task SignInAsync(string email, string password, bool isPersistent)
    {
        await _context.SignOutAsync();

        // validate password
        var result = await _userManager.ValidatePasswordAsync(email, password);

        if (!result.Success)
        {
            return;
            // invalid login attempt
        }

        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.Name, result.User.Name),
            new Claim(ClaimTypes.NameIdentifier, result.User.Id.ToString()),
            new Claim("Last Changed", result.User.LastChanged.ToLongDateString()),
        };

        var userIdentity = new ClaimsIdentity(claims, "Basic");
        var userPrincipal = new ClaimsPrincipal(userIdentity);

         await _context.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
        userPrincipal,
        new AuthenticationProperties
        {
            ExpiresUtc = DateTime.UtcNow.AddMinutes(20),
            IsPersistent = isPersistent,
            AllowRefresh = false
        });
    }

    public async Task<bool> ValidateLastChanged(string lastChanged)
    {
        var id = GetCurrentUserId();

        if (id == -1)
        {
            return false;
        }

        var user = await _userManager.GetUserByIdAsync(id, CancellationToken.None);

        if (user == null)
        {
            return false;
        }

        return user.LastChanged > DateTime.Parse(lastChanged);        
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...