由于项目中的许多因素,我需要手动创建UserManager
的实例,而无需使用 DI。我这样做如下:
var userstore = new UserStore<ApplicationUser>(_userContext);
IPasswordHasher<ApplicationUser> hasher = new PasswordHasher<ApplicationUser>();
var validator = new UserValidator<ApplicationUser>();
var validators = new List<UserValidator<ApplicationUser>> { validator };
var result = new UserManager<ApplicationUser>(userstore, null, hasher, validators, null, null, null, null, _userLogger);
这是在帮助程序类中完成的,result
返回到调用类,即我的控制器。
在我的控制器中,我进行以下调用:
var user = await _userManager.GetUserAsync(User);
。但是,user
始终为空。 我假设我传递给UserManager
构造函数的一些nulls
需要填写,但我只是猜测。我实际上从另一个 SO 问题中获得了此代码的基础,我现在无法找到这些问题。
我不认为我正在做的事情有任何魔力来配置其他一些依赖项。我使用一个名为ApplicationDbContext
的DbContext
,如下所示:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{ }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
}
}
我把它Startup.cs
连接起来,这样:
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("IdentityConnection")));
我有一个来自共享项目的AppliactionUser
。
当我做一个:
var users = userManager.Users.ToList();
我得到了所有预期用户的列表。
为什么调用GetUserAsync
返回null
?
编辑和更新
我只是想澄清一下,我确实在整个项目中都在使用 DI,我只是不能将其用于UserManager
.原因是依赖项通常通过.AddIdentity()
调用为其连接,而我们在此项目中没有使用。添加默认身份服务会胜过我们使用的 OIDC 配置,添加我们不使用的中间件,并阻止用户正确进行身份验证。
UserManager
确实是正常的 ASP.NET 核心。但不同的是,我们使用 OIDC 来登录用户。
ApplicationUser
作为null
返回,因为经过身份验证的用户上不存在预期的声明。UserManager
已正确连接,请保存允许用户通过不同名称的声明解析的配置更改。
我们使用 IdentityServer 4 作为项目的后备身份提供程序。标识用户的声明类型称为sub
,通常不由UserManager
检查。
最后,我创建了一个快速类(我可能会将其重构为内联内容),如下所示:
public class OptionsProvider : IOptions<IdentityOptions>
{
public IdentityOptions Value { get
{
var result = new IdentityOptions();
result.ClaimsIdentity = new ClaimsIdentityOptions { UserIdClaimType = "sub" };
return result;
}
}
}
接下来,我更新了UserManager
的实例化以包含以下选项:
var result = new UserManager<ApplicationUser>(
userstore,
new OptionsProvider(),
hasher,
validators,
null, null, null, null,
_userLogger);
这成功了。 再次感谢@trailmax指出我的源头,诚然,我应该更频繁地这样做。