Невозможно разрешить службу для типа Microsoft.AspNetCore.Identity.UserManager при попытке активировать AuthController

95

Я получаю эту ошибку в контроллере входа.

InvalidOperationException: не удалось разрешить службу для типа «Microsoft.AspNetCore.Identity.UserManager`1 [Automobile.Models.Account]» при попытке активировать «Automobile.Server.Controllers.AuthController».

вот конструктор Auth Controller:

private SignInManager<Automobile.Models.Account> _signManager;
    private UserManager<Automobile.Models.Account> _userManager;

    public AuthController(UserManager<Models.Account> userManager,
                          SignInManager<Automobile.Models.Account> signManager)
    {
        this._userManager = userManager;
        this._signManager = signManager;
    }

и вот ConfigureServices в startup.cs:

public void ConfigureServices(IServiceCollection services)
    {
        // Add framework services.
        services.AddApplicationInsightsTelemetry(Configuration);
        services.Configure<AppConfig>(Configuration.GetSection("AppSettings"));

        //var provider = HttpContext.ApplicationServices;
        //var someService = provider.GetService(typeof(ISomeService));


        services.AddDbContext<Providers.Database.EFProvider.DataContext>(options => options
            .UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),
                 b => b.MigrationsAssembly("Automobile.Server")
            ));


        services.AddIdentity<IdentityUser, IdentityRole>(options =>
        {
            options.User.RequireUniqueEmail = false;
        })
        .AddEntityFrameworkStores<Providers.Database.EFProvider.DataContext>()
        .AddDefaultTokenProviders(); 
        //services.AddScoped<SignInManager<Automobile.Models.Account>, SignInManager<Automobile.Models.Account>>();
        //services.AddScoped<UserManager<Automobile.Models.Account>, UserManager<Automobile.Models.Account>>();

        services.AddMvc();
        App.Service = services.BuildServiceProvider();

        // Adds a default in-memory implementation of IDistributedCache.
        services.AddDistributedMemoryCache();

        services.AddSession(options =>
        {
            // Set a short timeout for easy testing.
            options.IdleTimeout = TimeSpan.FromSeconds(10);
            options.CookieHttpOnly = true;
        });

    }
OMID
источник
21
Мне кажется, что вы регистрируетесь IdentityUserкак базовый пользовательский класс, но затем используете Automobile.Models.Account, который, конечно же, нигде не регистрируется ASP.NET Identity
Федерико Дипума
@FedericoDipuma Большое спасибо :) Решено.
OMID
Как ты это решил ..?
Rafael
4
@Lobato в services.AddIdentity просто замените IdentityUser своим классом Identity User
OMID
1
@OMID, почему бы тебе не опубликовать свой комментарий в качестве ответа, это спасло меня, но после серьезной головной боли от RnD ..
Null Pointer

Ответы:

89

Вам необходимо использовать одну и ту же модель пользовательских данных в SignInManager, UserManager и services.AddIdentity. Тот же принцип справедлив, если вы используете свой собственный класс ролевой модели приложения.

Итак, меняем

services.AddIdentity<IdentityUser, IdentityRole>(options =>
    {
        options.User.RequireUniqueEmail = false;
    })
    .AddEntityFrameworkStores<Providers.Database.EFProvider.DataContext>()
    .AddDefaultTokenProviders();

к

services.AddIdentity<Automobile.Models.Account, IdentityRole>(options =>
    {
        options.User.RequireUniqueEmail = false;
    })
    .AddEntityFrameworkStores<Providers.Database.EFProvider.DataContext>()
    .AddDefaultTokenProviders();
HojjatK
источник
2
У меня аналогичная проблема, у меня есть пользователь и роль клиента, определенные в методе AddIdentity, и я все еще получаю ту же ошибку. Есть идеи, почему? Я мог бы опубликовать свой код в отдельной теме.
devC 07
1
Фактически, я решил эту проблему, но теперь столкнулся с проблемой создания соединения с БД. Выложу проблему.
devC 09
Кажется, ваша строка подключения установлена ​​неправильно, посмотрите мой ответ в своем сообщении.
HojjatK
49

Просто чтобы прояснить ответ:

Если вы используете класс ApplicationUserв startup.cs:services.AddIdentity<ApplicationUser, IdentityRole>()

тогда вы должны использовать тот же класс в своем контроллере при его введении:

public AccountController(UserManager<ApplicationUser> userManager)

Если вы используете какой-то другой класс, например:

public AccountController(UserManager<IdentityUser> userManager)

тогда вы получите эту ошибку:

InvalidOperationException: невозможно разрешить службу для типа «Microsoft.AspNetCore.Identity.UserManager`1 [IdentityUser]»

потому что вы использовали ApplicationUserв автозагрузке, не IdentityUserзначит, что этот тип не зарегистрирован в системе впрыска.

Грег Гам
источник
6
Это учитывается для всех ссылок, поэтому, если вы реализуете новую идентификацию Razor для asp.net core 2.1, чтобы заменить вашу старую систему идентификации, вам необходимо заменить их автоматическую реализацию таких вещей, как SignInManager <IdentityUser> на SignInManager <ApplicationUser>, где бы он ни использовался. Это может раздражать. Кроме того , необходимо изменить маршрут от нормального / счета / Войти в / Удостоверение / Account / Войти и т.д. лишь некоторые советы , чтобы помочь;)
Йохан Herstad
14

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

services.AddIdentityCore<YourAppUser>()

Затем вам нужно будет вручную зарегистрировать то, что AddIdentityделает, что можно найти здесь: https://github.com/aspnet/Identity/blob/feedcb5c53444f716ef5121d3add56e11c7b71e5/src/Identity/IdentityServiceCollectionExtensions.cs#L79

        services.AddHttpContextAccessor();
        // Identity services
        services.TryAddScoped<IUserValidator<TUser>, UserValidator<TUser>>();
        services.TryAddScoped<IPasswordValidator<TUser>, PasswordValidator<TUser>>();
        services.TryAddScoped<IPasswordHasher<TUser>, PasswordHasher<TUser>>();
        services.TryAddScoped<ILookupNormalizer, UpperInvariantLookupNormalizer>();
        services.TryAddScoped<IRoleValidator<TRole>, RoleValidator<TRole>>();
        // No interface for the error describer so we can add errors without rev'ing the interface
        services.TryAddScoped<IdentityErrorDescriber>();
        services.TryAddScoped<ISecurityStampValidator, SecurityStampValidator<TUser>>();
        services.TryAddScoped<ITwoFactorSecurityStampValidator, TwoFactorSecurityStampValidator<TUser>>();
        services.TryAddScoped<IUserClaimsPrincipalFactory<TUser>, UserClaimsPrincipalFactory<TUser, TRole>>();
        services.TryAddScoped<UserManager<TUser>>();
        services.TryAddScoped<SignInManager<TUser>>();
        services.TryAddScoped<RoleManager<TRole>>();

Вам нужно будет заменить TUserи TRoleсвоими реализациями тех или по умолчанию IdentityUser,IdentityRole

Серж Саган
источник
Пришлось создать собственный SignInManager, и это исправило его, если вы планируете это сделать, проверьте github.com/dotnet/docs/issues/14828
perustaja
Первоначально я начал этот путь, но нашел решение здесь ( stackoverflow.com/a/60752194/1146862 ) более простым; Единственное изменение, которое мне пришлось сделать (после повторного заказа AddIdentityи AddJwtBearerустановки всех трех параметров, показанных в примере; я только использовал DefaultAuthenticationScheme. Я все еще получаю cookie обратно при входе в систему, но [Authorize]теперь работает для токенов JWT без указания AuthenticationSchema.
Аарон,
4

не забудьте добавить диспетчер ролей в ConfigureServices

services.AddDefaultIdentity<IdentityUser>()
    .AddRoles<IdentityRole>() // <--------
    .AddDefaultUI(UIFramework.Bootstrap4)
    .AddEntityFrameworkStores<ApplicationDbContext>();
Оззи
источник
3

Вы можете установить IdentityUser и IdentityRole в ConfigureServices внутри класса Startup по отдельности, как показано ниже:

services.AddDefaultIdentity<IdentityUser>()
    .AddRoles<IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>();

ИЛИ

вы можете настроить прямо в AddIdentity:

services.AddIdentity<IdentityUser, IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>();
Махавирсинх Падхияр
источник
4
Имея ответ только на код, OP и другие вряд ли узнают о проблеме, подумайте о том, чтобы отредактировать свой ответ и добавить объяснение
Клептус
0

Если вы используете «IdentityServer», тогда IdentityServer аутентифицирует пользователя и авторизует клиента. По умолчанию IdentityServer фактически не предназначен для управления пользователями. Но есть некоторая поддержка asp.net Identity

Итак, вам нужно добавить:

services.AddIdentityServer()
    .AddAspNetIdentity<ApplicationUser>();
Амирхосейн Яри
источник
0

Вам необходимо обновить свой класс Statup.cs следующим образом:

services.AddIdentity <ApplicationUser, IdentityRole> () .AddEntityFrameworkStores ();

Здесь: ApplicationUser - это мой собственный класс модели.

Гаурав Джоши
источник