Não foi possível resolver o serviço para o tipo 'Microsoft.AspNetCore.Identity.UserManager` ao tentar ativar' AuthController '

97

Estou recebendo este erro no Login Controller.

InvalidOperationException: Não foi possível resolver o serviço para o tipo 'Microsoft.AspNetCore.Identity.UserManager`1 [Automobile.Models.Account]' ao tentar ativar 'Automobile.Server.Controllers.AuthController'.

aqui está o construtor 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;
    }

e aqui está ConfigureServices em 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
fonte
22
Parece-me que você está se registrando IdentityUsercomo uma classe de usuário básica, mas está usando Automobile.Models.Account, o que, é claro, não está registrado em nenhum lugar pelo ASP.NET Identity
Federico Dipuma
@FedericoDipuma Muito obrigado :) Resolvido.
OMID
Como você resolveu isso ..?
Rafael
4
@Lobato em services.AddIdentity apenas substitua IdentityUser por sua classe Identity User
OMID
1
@OMID por que você não posta seu comentário como resposta, isso me salvou, mas depois de uma séria dor de cabeça de RnD ..
Null Pointer

Respostas:

92

Você precisa usar o mesmo modelo de dados do usuário em SignInManager, UserManager e services.AddIdentity. O mesmo princípio é verdadeiro se você estiver usando sua própria classe de modelo de função de aplicativo personalizado.

Então mude

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

para

services.AddIdentity<Automobile.Models.Account, IdentityRole>(options =>
    {
        options.User.RequireUniqueEmail = false;
    })
    .AddEntityFrameworkStores<Providers.Database.EFProvider.DataContext>()
    .AddDefaultTokenProviders();
HojjatK
fonte
2
Eu tenho o problema semelhante, tenho meu usuário cliente e função definidos no método AddIdentity e ainda estou recebendo o mesmo erro. Alguma ideia do porquê? Eu poderia postar meu código em um segmento separado.
devC de
1
Na verdade, resolvi esse problema, mas agora estou enfrentando um problema com a criação da conexão DB. Vou postar o problema.
devC de
parece que sua string de conexão não foi configurada corretamente, verifique minha resposta em sua postagem.
HojjatK
50

Só para esclarecer a resposta:

Se você usar a classe ApplicationUser em startup.cs:services.AddIdentity<ApplicationUser, IdentityRole>()

então você deve usar a mesma classe em seu controlador ao injetá-lo:

public AccountController(UserManager<ApplicationUser> userManager)

Se você usar alguma outra classe, como:

public AccountController(UserManager<IdentityUser> userManager)

então você obterá este erro:

InvalidOperationException: Não foi possível resolver o serviço para o tipo 'Microsoft.AspNetCore.Identity.UserManager`1 [IdentityUser]'

porque vc usou ApplicationUserna inicialização, não IdentityUserso esse tipo não é cadastrado com o sistema de injeção.

Greg Gum
fonte
6
Isso conta para todas as referências, portanto, se você implementar a nova identidade Razor para asp.net core 2.1 para substituir seu antigo sistema de identidade, será necessário substituir sua implementação automática de coisas como SignInManager <IdentityUser> para SignInManager <ApplicationUser> onde quer que seja usado. Isso pode ser irritante. Além disso, você precisa redirecionar do normal / Conta / Login para / Identidade / Conta / Login etc. apenas algumas dicas para ajudar;)
Johan Herstad
16

Isso não tem relação com a postagem original, mas como o Google traz você aqui ... se você está recebendo este erro e está usando:

services.AddIdentityCore<YourAppUser>()

Em seguida, você precisará registrar manualmente o que AddIdentityfaz, que pode ser encontrado aqui: 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>>();

Você precisará substituir TUsere TRolepor suas implementações daqueles, ou o padrão IdentityUser,IdentityRole

Serj Sagan
fonte
Tive que criar um SignInManager personalizado e isso corrigiu, se você planeja fazer isso, verifique github.com/dotnet/docs/issues/14828
perustaja
Eu comecei originalmente por essa rota, mas encontrei a solução aqui ( stackoverflow.com/a/60752194/1146862 ) mais direta; A única alteração que tive de fazer (depois de reordenar AddIdentitye AddJwtBearerdefinir todas as três opções mostradas no exemplo; eu só estava usando DefaultAuthenticationScheme. Ainda recebo o cookie de volta no login, mas [Authorize]agora funciona para os tokens JWT sem especificar um AuthenticationSchema.
Aaron de
Isso é exatamente o que eu estava perdendo. Adicionar TryAddScoped<UserManager<TUser>>();e services.TryAddScoped<SignInManager<TUser>>();ao meu Startup.cs corrigiu meu problema.
MorganR
4

não se esqueça de adicionar gerenciador de funções em ConfigureServices

services.AddDefaultIdentity<IdentityUser>()
    .AddRoles<IdentityRole>() // <--------
    .AddDefaultUI(UIFramework.Bootstrap4)
    .AddEntityFrameworkStores<ApplicationDbContext>();
Ozzy
fonte
3

Você pode definir IdentityUser e IdentityRole em ConfigureServices dentro da classe Startup individualmente, conforme mostrado abaixo:

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

OU

você pode configurar diretamente em AddIdentity:

services.AddIdentity<IdentityUser, IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>();
Mahavirsinh Padhiyar
fonte
4
Com uma resposta apenas em código, OP e outros dificilmente aprenderão sobre o problema, considere editar sua resposta e adicionar uma explicação
Cleptus,
0

Se você estiver usando "IdentityServer", então IdentityServer autentica o usuário e autoriza o cliente. Por padrão, IdentityServer não trata de gerenciamento de usuários. Mas há algum suporte para identidade asp.net

Então você precisa adicionar:

services.AddIdentityServer()
    .AddAspNetIdentity<ApplicationUser>();
Amirhossein Yari
fonte
0

Você precisa atualizar sua classe Statup.cs com abaixo

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

Aqui: ApplicationUser é minha classe de modelo personalizado.

Gaurav Joshi
fonte