AspNet Identity Core - пользовательские претензии при входе в систему - PullRequest
0 голосов
/ 19 ноября 2018

Я пытаюсь расширить свою личность, добавив в базу данных логический столбец «удален».

Затем я хочу использовать это значение, чтобы добавить претензию пользователю, используя пользовательский UserClaimsPrincipalFactory.

Я хочу проверить претензию "Удалено" при входе в систему и отклонить пользователя, если его учетная запись была удалена.

Проблема: Когда я пытаюсь получить доступ к претензиям через User.Claims, у пользователя нет претензий.

Единственное, что я могу сделать, это перезаписать пользователя httpcontext

public class ApplicationClaimsIdentityFactory : UserClaimsPrincipalFactory<ApplicationUser, IdentityRole>
{
    private readonly IHttpContextAccessor _httpContext;

    public ApplicationClaimsIdentityFactory(UserManager<ApplicationUser> userManager, RoleManager<IdentityRole> roleManager, IOptions<IdentityOptions> options, IHttpContextAccessor httpContext) : base(userManager, roleManager, options)
    {
        _httpContext = httpContext;
    }

    public override async Task<ClaimsPrincipal> CreateAsync(ApplicationUser user)
    {
        ClaimsPrincipal principal = await base.CreateAsync(user);

        ClaimsIdentity claimsIdentity = (ClaimsIdentity) principal.Identity;

        claimsIdentity.AddClaim(new Claim("Deleted", user.Deleted.ToString().ToLower()));

        //I DON'T WANT TO HAVE TO DO THIS
        _httpContext.HttpContext.User = principal;


        return principal;
    }
}

Действие для входа:

public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
    {
        ViewData["ReturnUrl"] = returnUrl;
        if (ModelState.IsValid)
        {

            SignInResult result = await _signInManager.PasswordSignInAsync(model.Email, model.Password,
                model.RememberMe, lockoutOnFailure: false);

            if (result.Succeeded)
            {
                //No claims exists at this point unless I force the HttpContext user (See above)
                if (User.Claims.First(x => x.Type == "Deleted").Value.Equals("true", StringComparison.CurrentCultureIgnoreCase);)
                {
                    ModelState.AddModelError(string.Empty, "Invalid login attempt.");
                    await _signInManager.SignOutAsync();
                    return View(model);
                }

          .... Continue login code...

Мой класс ApplicationUser

public class ApplicationUser : IdentityUser
{
    public bool Deleted { get; set; }
}

И, наконец, моя стартовая регистрация

services.AddIdentity<ApplicationUser, IdentityRole>()
            .AddEntityFrameworkStores<DbContext>()
            .AddClaimsPrincipalFactory<ApplicationClaimsIdentityFactory>()
            .AddDefaultTokenProviders();

Спасибо

1 Ответ

0 голосов
/ 19 ноября 2018

Я думаю, что проблема в том, что вы пытаетесь сделать все это в одном запросе, когда публикуется действие входа в систему.

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

Метод входа создал новый аутентифицированный принцип утверждений и должен был сериализовать его в файл cookie аутентификации, поэтому при следующем запросе пользователь будет десериализован из файла cookie и будет аутентифицирован, но эта десериализация уже произошла длятекущий запросТаким образом, единственный способ изменить его для текущего запроса - сбросить пользователя на текущем httpcontext, как вы нашли.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...