尝试激活“AuthController”时无法解析“Microsoft.AspNetCore.Identity.UserManager”类型的服务

Posted

技术标签:

【中文标题】尝试激活“AuthController”时无法解析“Microsoft.AspNetCore.Identity.UserManager”类型的服务【英文标题】:Unable to resolve service for type 'Microsoft.AspNetCore.Identity.UserManager` while attempting to activate 'AuthController' 【发布时间】:2017-06-11 11:57:48 【问题描述】:

我在登录控制器中收到此错误。

InvalidOperationException:尝试激活“Automobile.Server.Controllers.AuthController”时无法解析“Microsoft.AspNetCore.Identity.UserManager`1[Automobile.Models.Account]”类型的服务。

这里是 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;
    

这里是 startup.cs 中的 ConfigureServices:

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;
        );

    

【问题讨论】:

在我看来,您将IdentityUser 注册为基本用户类,但随后您使用的是Automobile.Models.Account,当然,ASP.NET Identity 并未在任何地方注册 @FedericoDipuma 非常感谢 :) 已解决。 你是怎么解决的……? @Lobato in services.AddIdentity 只需将 IdentityUser 替换为您的 Identity User 类 @OMID 你为什么不发表你的评论作为答案,这救了我,但在 RnD 的一些严重头痛之后...... 【参考方案1】:

您需要在 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();

【讨论】:

我有类似的问题,我在 AddIdentity 方法中定义了我的客户用户和角色,但我仍然遇到同样的错误。知道为什么吗?我可以在单独的线程中发布我的代码。 实际上,我解决了这个问题,但现在在创建数据库连接时遇到了问题。我会发布问题。 ***.com/questions/48161467/… 您的连接字符串似乎设置不正确,请查看我在您的帖子中的回答。【参考方案2】:

只是为了明确答案:

如果你在 startup.cs 中使用 ApplicationUser 类:services.AddIdentity&lt;ApplicationUser, IdentityRole&gt;()

那么你必须在注入控制器时使用相同的类:

public AccountController(UserManager<ApplicationUser> userManager)

如果您使用其他类,例如:

public AccountController(UserManager<IdentityUser> userManager)

那么你会得到这个错误:

InvalidOperationException:无法解析类型“Microsoft.AspNetCore.Identity.UserManager`1[IdentityUser]”的服务

因为你在启动时使用了ApplicationUser,而不是IdentityUser,所以这个类型没有在注入系统中注册。

【讨论】:

这适用于所有引用,因此,如果您为 asp.net core 2.1 实现新的 Razor 身份以替换旧的身份系统,则需要将其自动实现的诸如 SignInManager 之类的东西替换为 SignInManager 无论在何处使用。这可能很烦人。此外,您需要从正常的 /Account/Login 重新路由到 /Identity/Account/Login 等。只是一些帮助提示;)【参考方案3】:

这与原始帖子有点无关,但由于 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>>();

您需要将 TUserTRole 替换为您的实现,或默认的 IdentityUserIdentityRole

【讨论】:

必须创建一个自定义 SignInManager 并修复它,如果您打算这样做,请检查 github.com/dotnet/docs/issues/14828 我最初是沿着这条路线开始的,但在这里 (***.com/a/60752194/1146862) 找到了更直接的解决方案;我必须做的唯一改变(在重新订购AddIdentityAddJwtBearer 之后是设置示例中显示的所有三个选项;我只使用DefaultAuthenticationScheme。我仍然在登录时获得cookie,但是[Authorize] 现在适用于 JWT 令牌,无需指定 AuthenticationSchema。 这正是我所缺少的。将TryAddScoped&lt;UserManager&lt;TUser&gt;&gt;();services.TryAddScoped&lt;SignInManager&lt;TUser&gt;&gt;(); 添加到我的Startup.cs 解决了我的问题。【参考方案4】:

您可以在 Startup 类的 ConfigureServices 中分别设置 IdentityUser 和 IdentityRole,如下所示:

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

您可以直接配置到 AddIdentity 中:

services.AddIdentity<IdentityUser, IdentityRole>()
        .AddEntityFrameworkStores<ApplicationDbContext>();

【讨论】:

只有代码的答案,OP 和其他人很难了解这个问题,考虑编辑你的答案并添加解释【参考方案5】:

不要忘记在 ConfigureServices 中添加角色管理器

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

【讨论】:

【参考方案6】:

如果您使用“IdentityServer”,那么 IdentityServer 会验证用户并授权客户端。默认情况下,IdentityServer 实际上与用户管理无关。但是有一些对asp.net Identity的支持

所以你需要添加:

services.AddIdentityServer()
    .AddAspNetIdentity<ApplicationUser>();

【讨论】:

【参考方案7】:

您需要使用以下更新您的 Statup.cs 类

services.AddIdentity() .AddEntityFrameworkStores();

这里:ApplicationUser 是我的自定义模型类。

【讨论】:

以上是关于尝试激活“AuthController”时无法解析“Microsoft.AspNetCore.Identity.UserManager”类型的服务的主要内容,如果未能解决你的问题,请参考以下文章

如何解决“尝试激活''时无法解析类型''的服务”

.net Core 6 - 尝试激活时无法解析服务类型

InvalidOperationException:尝试激活“DocumentController”时无法解析“IDocumentService”类型的服务

尝试激活“AspNetCoreRateLimit.IpRateLimitMiddleware”时无法解析“AspNetCoreRateLimit.IProcessingStrategy”类型的服务

尝试激活“MyService”时无法解析“System.String”类型的服务

尝试激活“AuthenticateController”时无法解析“Microsoft.AspNetCore.Identity.UserManager”类型的服务