No se pudo resolver el servicio para el tipo 'Microsoft.AspNetCore.Identity.UserManager` al intentar activar' AuthController '

95

Recibo este error en el controlador de inicio de sesión.

InvalidOperationException: no se puede resolver el servicio para el tipo 'Microsoft.AspNetCore.Identity.UserManager`1 [Automobile.Models.Account]' al intentar activar 'Automobile.Server.Controllers.AuthController'.

aquí está el constructor 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;
    }

y aquí está ConfigureServices en 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
fuente
21
Me parece que se está registrando IdentityUsercomo clase de usuario básica pero luego está usando Automobile.Models.Account, que, por supuesto, no está registrado en ninguna parte por ASP.NET Identity
Federico Dipuma
@FedericoDipuma Muchas gracias :) Resuelto.
OMID
¿Cómo lo resolviste ...?
Rafael
4
@Lobato en services.AddIdentity simplemente reemplace IdentityUser con su clase de usuario de identidad
OMID
1
@OMID, ¿por qué no publicas tu comentario como respuesta? Esto me salvó, pero después de un serio dolor de cabeza de RnD ..
Null Pointer

Respuestas:

89

Debe utilizar el mismo modelo de datos de usuario en SignInManager, UserManager y services.AddIdentity. El mismo principio es cierto si está utilizando su propia clase de modelo de rol de aplicación personalizada.

Entonces, cambia

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

a

services.AddIdentity<Automobile.Models.Account, IdentityRole>(options =>
    {
        options.User.RequireUniqueEmail = false;
    })
    .AddEntityFrameworkStores<Providers.Database.EFProvider.DataContext>()
    .AddDefaultTokenProviders();
HojjatK
fuente
2
Tengo un problema similar, tengo el usuario y el rol de mi cliente definidos en el método AddIdentity y sigo recibiendo el mismo error. ¿Alguna idea de por qué? Podría publicar mi código en un hilo separado.
devC
1
En realidad, resolví ese problema, pero ahora tengo un problema con la creación de la conexión DB. Publicaré el problema.
devC
parece que su cadena de conexión no se ha configurado correctamente, consulte mi respuesta en su publicación.
HojjatK
49

Solo para tener clara la respuesta:

Si usa la clase ApplicationUseren startup.cs:services.AddIdentity<ApplicationUser, IdentityRole>()

entonces debes usar la misma clase en tu controlador al inyectarlo:

public AccountController(UserManager<ApplicationUser> userManager)

Si usa alguna otra clase como:

public AccountController(UserManager<IdentityUser> userManager)

entonces obtendrás este error:

InvalidOperationException: no se puede resolver el servicio para el tipo 'Microsoft.AspNetCore.Identity.UserManager`1 [IdentityUser]'

debido a que usó ApplicationUseren el inicio, no IdentityUserasí este tipo no está registrado con el sistema de inyección.

Greg Gum
fuente
6
Esto cuenta para todas las referencias, por lo que si implementa la nueva identidad de Razor para asp.net core 2.1 para reemplazar su antiguo sistema de identidad, debe reemplazar su implementación automática de cosas como SignInManager <IdentityUser> a SignInManager <ApplicationUser> donde sea que se use. Esto puede resultar molesto. También debe cambiar la ruta normal / Cuenta / Iniciar sesión a / Identidad / Cuenta / Iniciar sesión, etc., solo algunos consejos para ayudar;)
Johan Herstad
14

Esto no tiene nada que ver con la publicación original, pero como Google lo trae aquí ... si está recibiendo este error y está usando:

services.AddIdentityCore<YourAppUser>()

Luego, deberá registrar manualmente las cosas que lo AddIdentityhacen, que se pueden encontrar aquí: 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>>();

Deberá reemplazar TUsery TRolecon sus implementaciones de esos, o el predeterminado IdentityUser,IdentityRole

Serj Sagan
fuente
Tuve que crear un SignInManager personalizado y esto lo solucionó, si planea hacerlo, consulte github.com/dotnet/docs/issues/14828
perustaja
Originalmente comencé por esta ruta, pero encontré la solución aquí ( stackoverflow.com/a/60752194/1146862 ) más sencillo; El único cambio que tuve que hacer (después de reordenar AddIdentityy AddJwtBearerfue configurar las tres opciones que se muestran en el ejemplo; solo lo había estado usando DefaultAuthenticationScheme. Todavía obtengo la cookie al iniciar sesión, pero [Authorize]ahora funciona para los tokens JWT sin especificar un AuthenticationSchema.
Aaron
4

no olvide agregar el administrador de roles en ConfigureServices

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

Puede configurar IdentityUser e IdentityRole en ConfigureServices dentro de la clase Startup individualmente como se muestra a continuación:

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

O

puede configurar directamente en AddIdentity:

services.AddIdentity<IdentityUser, IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>();
Mahavirsinh Padhiyar
fuente
4
Con una respuesta de solo código, OP y otros difícilmente aprenderán sobre el problema, considere editar su respuesta y agregar una explicación
Cleptus
0

Si está utilizando "IdentityServer", entonces IdentityServer autentica al usuario y autoriza al cliente. De forma predeterminada, IdentityServer no se trata de administración de usuarios. Pero hay algo de soporte para asp.net Identity

Entonces necesitas agregar:

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

Necesita actualizar su clase Statup.cs a continuación

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

Aquí: ApplicationUser es mi clase de modelo personalizado.

Gaurav Joshi
fuente