.NET 7集成JWT时出现“无法构造某些服务”错误求助
错误信息
System.AggregateException: 'Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: Microsoft.AspNetCore.Identity.IUserClaimsPrincipalFactory
1[Microsoft.AspNetCore.Identity.IdentityUser] Lifetime: Scoped ImplementationType: Microsoft.AspNetCore.Identity.UserClaimsPrincipalFactory1[Microsoft.AspNetCore.Identity.IdentityUser]': Unable to resolve service for type 'Microsoft.AspNetCore.Identity.IUserStore1[Microsoft.AspNetCore.Identity.IdentityUser]' while attempting to activate 'Microsoft.AspNetCore.Identity.UserManager1[Microsoft.AspNetCore.Identity.IdentityUser]'.) (Error while validating the service descriptor 'ServiceType: Microsoft.AspNetCore.Identity.UserManager1[Microsoft.AspNetCore.Identity.IdentityUser] Lifetime: Scoped ImplementationType: Microsoft.AspNetCore.Identity.UserManager1[Microsoft.AspNetCore.Identity.IdentityUser]': Unable to resolve service for type 'Microsoft.AspNetCore.Identity.IUserStore1[Microsoft.AspNetCore.Identity.IdentityUser]' while attempting to activate 'Microsoft.AspNetCore.Identity.UserManager1[Microsoft.AspNetCore.Identity.IdentityUser]'.)'
核心问题分析
错误根源是依赖注入容器无法解析IUserStore<IdentityUser>服务,原因包括:
- 未将
UsersDbContext注册到服务容器 - 使用
AddIdentityCore但未补充完整的用户存储服务配置 - 启用了角色功能,但
UsersDbContext继承的IdentityUserContext不包含角色表结构 - 认证与授权中间件顺序颠倒
修复步骤
1. 注册UsersDbContext到服务容器
取消Program.cs中DbContext注册代码的注释,采用DI方式配置连接字符串(不依赖DbContext内部的OnConfiguring方法):
#region DbContext builder.Services.AddDbContext<UsersDbContext>(options => { options.UseSqlServer(builder.Configuration.GetConnectionString("SurveyConnection")); }); #endregion
2. 修改UsersDbContext的继承关系
因代码中启用了角色功能,将UsersDbContext从IdentityUserContext改为IdentityDbContext,以包含角色相关表结构:
using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; namespace survey.Data { public class UsersDbContext : IdentityDbContext<IdentityUser, IdentityRole, string> { public UsersDbContext(DbContextOptions<UsersDbContext> options) : base(options) { } protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); } } }
3. 调整Identity服务配置
如果需要完整的Identity功能,替换AddIdentityCore为AddIdentity(更简洁):
#region users builder.Services.AddIdentity<IdentityUser, IdentityRole>(options => { options.SignIn.RequireConfirmedAccount = false; options.User.RequireUniqueEmail = true; options.Password.RequireDigit = false; options.Password.RequiredLength = 6; options.Password.RequireNonAlphanumeric = false; options.Password.RequireUppercase = false; options.Password.RequireLowercase = false; }) .AddEntityFrameworkStores<UsersDbContext>() .AddDefaultTokenProviders(); #endregion
若坚持使用AddIdentityCore,需补充必要的服务注册:
builder.Services .AddIdentityCore<IdentityUser>(options => { // 保留原配置项 }) .AddRoles<IdentityRole>() .AddEntityFrameworkStores<UsersDbContext>() .AddUserManager<UserManager<IdentityUser>>() .AddRoleManager<RoleManager<IdentityRole>>() .AddDefaultTokenProviders();
4. 修正中间件顺序
认证中间件必须在授权中间件之前执行,调整Program.cs中的中间件顺序:
app.UseHttpsRedirection(); app.UseAuthentication(); // 先执行认证 app.UseAuthorization(); // 再执行授权 app.MapControllers();
5. 执行数据库迁移
生成并执行迁移,创建Identity所需的用户、角色等表:
Add-Migration InitialIdentitySetup Update-Database
内容的提问来源于stack exchange,提问作者Diego Perez

