Переопределите CheckPasswordAsync, когда пользователь входит в систему с Identity 2.0 - PullRequest
0 голосов
/ 28 июня 2018

Я реализовал аутентификацию с помощью ASP.NET Core Identity 2.0 в существующем приложении. Поскольку я использую свою собственную схему базы данных и классы, я использую свой собственный класс User, и мне пришлось создать собственный UserStore. Проблема в том, что когда я создавал пользователей, я хэшировал их пароль не тем же методом, который используется в Identity, и вход в систему не удался, когда вызывается эта функция:

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

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

CustomUserManager:

public class CustomUserManager<TUser> : UserManager<TUser> where TUser : class
{
    public CustomUserManager(IUserStore<TUser> store, IOptions<IdentityOptions> optionsAccessor,
IPasswordHasher<TUser> passwordHasher, IEnumerable<IUserValidator<TUser>> userValidators,
IEnumerable<IPasswordValidator<TUser>> passwordValidators, ILookupNormalizer keyNormalizer,
IdentityErrorDescriber errors, IServiceProvider services, ILogger<UserManager<TUser>> logger) : base(store, optionsAccessor, passwordHasher, userValidators, passwordValidators, keyNormalizer, errors, services, logger)
    {
    }

    public override Task<bool> CheckPasswordAsync(TUser user, string password)
    {
        return base.CheckPasswordAsync(user, password);
    }
}

Конструктор AccountController:

public AccountController(
        CustomUserManager<User> userManager,
        SignInManager<User> signInManager,
        ILogger<AccountController> logger)
    {
        _userManager = userManager;
        _signInManager = signInManager;
        _logger = logger;
    }

Я даже пытался добавить область в конфигурации служб:

services.AddIdentity<User, ProfileUser>().AddDefaultTokenProviders();
services.AddTransient<IUserStore<User>, UserIdentity>();
services.AddTransient<IRoleStore<ProfileUser>, ProfileIdentity>();
services.AddScoped< UserManager<User>, CustomUserManager>();

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

InvalidOperationException: Unable to resolve service for type 'CustomUserManager`1[Maquetteur.Entities.User]' while attempting to activate 'Maquetteur.Web.AccountController'.

С помощью UserManager по умолчанию я могу получить доступ к странице входа, но функция входа не работает. С пользовательским UserManager я не могу получить доступ к странице входа в систему.

У вас есть идея, что я делаю не так? Или, может быть, есть другой способ реализовать наш собственный способ проверки, похожи ли пароли, когда пользователь входит в систему?

1 Ответ

0 голосов
/ 28 июня 2018

Когда вы добавили эту строку, вы двигались в правильном направлении:

services.AddScoped<UserManager<User>, CustomUserManager>();

Эта строка в основном гласит: Если я прошу UserManager<User>, пожалуйста, дайте мне CustomUserManager. Однако, это не совсем то, что вы намеревались здесь. Вместо этого вы хотели сказать: Если я попрошу CustomUserManager, просто дайте мне CustomUserManager.

На самом деле это довольно легко исправить - вы можете просто зарегистрировать его, когда добавляете сервисы Identity. e.g.:

services
    .AddIdentity<User, ProfileUser>()
    .AddUserManager<CustomUserManager<User>>()
    .AddDefaultTokenProviders();

Примечание. Существуют также дополнительные расширения для регистрации пользовательских реализаций IUserStore и IRoleStore.

...