Не удалось разрешить службу для типа Identity.IdentityUserStore при попытке активировать Identity.IdentityUserManager. - PullRequest
0 голосов
/ 13 февраля 2020

Я пытаюсь использовать ASP. NET Core Identity 3.0 в проекте с существующей БД, которая не использовала Identity. Поэтому мне нужно выполнить некоторые настройки из-за этого и потому, что я хочу сделать более сложные операции.

Это делается с помощью. NET Core 3.1

Но когда я запускаю решение правильно теперь я получаю эти 2 исключения:

InvalidOperationException: Ошибка при проверке дескриптора службы 'ServiceType: Microsoft.AspNetCore.Identity.ISecurityStampValidator Срок действия: Ограниченная реализацияType: Microsoft.AspNetCore.Identity.SecurityStampaljectIDject .Data.Identity.IdentityForumUser] ': невозможно разрешить службу для типа' ForumProject.Data.Identity.IdentityUserStore 'при попытке активировать' ForumProject.Data.Identity.IdentityUserManager '.

InvalidOperationException: невозможно разрешить службу для типа «ForumProject.Data.Identity.IdentityUserStore» при попытке активировать «ForumProject.Data.Identity.IdentityUserManager».

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

У меня это настроено в ConfigureServices в startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<IPasswordHasher<IdentityForumUser>, IdentityPasswordHasher>();

    services.AddDbContext<DatabaseContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("ForumDatabase")));
    services.AddDbContext<IdentityDatabaseContext>(options =>
        options.UseSqlServer(Configuration.GetConnectionString("ForumDatabase")));
    //services.AddIdentity<AppUser, IdentityRole>().AddEntityFrameworkStores<AppIdentityDbContext>().AddDefaultTokenProviders();
    services.AddIdentity<IdentityForumUser, IdentityForumRole>(options =>
        {
            options.SignIn.RequireConfirmedAccount = false;
            options.Password.RequiredLength = 2;
            options.Password.RequireDigit = false;
            options.Password.RequireLowercase = false;
            options.Password.RequiredUniqueChars = 0;
            options.Password.RequireNonAlphanumeric = false;
            options.Password.RequireUppercase = false;
        })
        //.AddRoles<IdentityForumRole>()
        .AddUserStore<IdentityUserStore>()
        .AddUserManager<IdentityUserManager>()
        //.AddSignInManager<IdentitySignInManager>()
        .AddEntityFrameworkStores<IdentityDatabaseContext>();

    services.AddMvc();
    services.AddControllersWithViews();
    services.AddRazorPages();
}

И вот IdentityForumUser, IdentityForumRole, IdentityDatabaseContext:

public class IdentityForumUser : IdentityUser<int>
{
    [Column("Username")]
    public override string UserName { get; set; }

    [Column("Password")]
    public override string PasswordHash { get; set; }

    public int ThemeId { get; set; } = 1; /// TODO: Make it set to the picked default one

    public int ChatStatus { get; set; } = 0;

    public DateTime RegistrationDate { get; set; } = DateTime.UtcNow;

    public bool DynamicMode { get; set; } = false;

    public DateTime LastActivity { get; set; } = DateTime.UtcNow;
}

public class IdentityForumRole : IdentityRole<int>
{
}

public class IdentityDatabaseContext : IdentityDbContext<IdentityForumUser, IdentityForumRole, int>
{
    public IdentityDatabaseContext(DbContextOptions<IdentityDatabaseContext> options)
        : base(options)
    {
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        builder.Entity<IdentityForumUser>()
            .Ignore(c => c.LockoutEnd)
            .Ignore(c => c.TwoFactorEnabled)
            .Ignore(c => c.PhoneNumberConfirmed)
            .Ignore(c => c.PhoneNumber)
            .Ignore(c => c.ConcurrencyStamp)
            .Ignore(c => c.EmailConfirmed)
            .Ignore(c => c.NormalizedEmail)
            //.Ignore(c => c.NormalizedUserName)
            .Ignore(c => c.LockoutEnabled)
            .Ignore(c => c.AccessFailedCount)
            .ToTable("Users");
        builder.Entity<IdentityForumRole>()
            .Ignore(c => c.ConcurrencyStamp)
            .ToTable("Roles");
    }
}

А вот IdentityUserStore, IdentityUserManager:

public class IdentityUserStore : UserStore<IdentityForumUser, IdentityForumRole, IdentityDatabaseContext, int>
{
    public IdentityUserStore(IdentityDatabaseContext context, IdentityErrorDescriber describer = null) : base(context, describer)
    {
    }
}

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

    public override bool SupportsUserClaim
    {
        get
        {
            ThrowIfDisposed();
            return false;
        }
    }
}

Вот IdentityPasswordHasher, но только его части, я буду комментировать сама логика c, я не уверен, что это актуально:

public class IdentityPasswordHasher : PasswordHasher<IdentityForumUser>
{
    private readonly PasswordHasherCompatibilityMode _compatibilityMode;

    public IdentityPasswordHasher(IOptions<PasswordHasherOptions> optionsAccessor = null)
        : base(optionsAccessor)
    {
        var options = optionsAccessor?.Value ?? new PasswordHasherOptions();

        _compatibilityMode = options.CompatibilityMode;
    }

    public override string HashPassword(IdentityForumUser user, string password)
    {
        // custom hashing code
    }

    public override PasswordVerificationResult VerifyHashedPassword(IdentityForumUser user, string hashedPassword, string providedPassword)
    {
        // custom verification code
    }
}

1 Ответ

0 голосов
/ 13 февраля 2020

В конструкторе для IdentityUserManager я изменил его на IUserStore<IdentityForumUser> store вместо IdentityUserStore store (мой пользовательский класс).

Это заставило его работать и по-прежнему использовать мой собственный класс хранилища. Тем не менее, я не рад, что не могу быть явным, так как это облегчает понимание кода. Если есть способ сделать это явным, пожалуйста, ответьте тоже.

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