Я пытаюсь реализовать свою собственную аутентификацию 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);
}