5

环境:.Net Core 1,EF,使用 Identity 进行身份验证,使用 JWT 令牌进行授权。

遇到使用该UserManager.ChangePasswordAsync()方法正确更新数据库但未更新UserManager.Users列表的问题(假设)。

在 Startup.cs 中,我们只是在使用app.UseIdentity(),在ApplicationUserService构造函数中,我们正在注入UserManager<ApplicationUser>. 除此之外,我们没有做任何定制的事情。

例如:假设用户将密码从“password1”更改为“password2”。如果该用户注销并重新登录,UserManager 仍然认为密码是“password1”。如果我重新启动 WebAPI 服务器,然后尝试登录;它可以按照您对“password2”的期望工作。所以它肯定在更新数据库,但 UserManager 的范围/缓存没有被更新。

我想知道 UserManager 的默认 DI 范围是否是单例(而不是每个请求)?如果不更新 UserStore 的缓存用户列表,我可以看到导致此问题。

有什么建议么?需要更多代码?

应用程序用户服务(简化):

private readonly UserManager<ApplicationUser> _userManager;

public ApplicationUserService(UserManager<ApplicationUser> userManager)
{
     _userManager = userManager;
}

public Task<IdentityResult> ChangePasswordAsync(ApplicationUser user, string currentPassword, string newPassword)
{
    return _userManager.ChangePasswordAsync(user, currentPassword, newPassword);
}

[编辑]

我不确定为什么会出现这种情况,但我刚刚意识到,如果我将 UserManager 和 SignInManager 直接注入到 Controller 的构造函数中(而不是注入到 Service 层中),它似乎工作得很好。

[编辑 2]

调查结果摘要:

1) 将 UserManager 和 SignInManager 注入到 Service 构造函数中,然后将该 Service 注入到 Controller 构造函数中并不能完全起作用。

2) 将 UserManager 和 SignInManager 注入到 Controller 构造函数中。

3)我还测试了Controller构造函数中IServiceProvider的使用。我注入了 IServiceProvider,然后使用 GetService 方法设置管理器:_userManager = serviceProvider.GetService<UserManager<ApplicationUser>>();。这与#1 的结果相同。

在 #1 & #3 中:它会保存到数据库中,但是管理人员在以后使用时似乎没有意识到数据的变化。在这两种情况下,我都必须重新初始化应用程序(停止并启动服务器)以更新缓存数据。

#3 不应该和 #2 一样工作吗?

4

1 回答 1

1

[注意:以下代码不适用于 Asp.Net Core。对于 Asp.Net Core 中的身份验证,请查看此文档。]

我是 Asp.Net 的新手,但我尝试制作您所描述的内容。对我来说,它按预期工作。也许我的代码可以激发你的想法。

internal static void Main(string[] args) { _userStore = new UserStore<ApplicationUser>(new IdentityDbContext<ApplicationUser>()); _userManager = new UserManager<ApplicationUser>(_userStore); var x = new ApplicationUser(); x.UserName = "Test"; foreach(string error in _userManager.Create(x, "password").Errors) { Console.WriteLine(error); } Console.WriteLine(_userManager.CheckPassword(x, "password")); var f = ChangePasswordAsync(x, "password", "pass12345"); f.ContinueWith(delegate { if (f.IsFaulted) { Console.WriteLine(f.Exception.Message); } }).ContinueWith(delegate { Console.WriteLine(_userManager.CheckPassword(x, "password")); }); Console.ReadKey(true); } private static UserStore<ApplicationUser> _userStore; public class ApplicationUser : IdentityUser { } private static UserManager<ApplicationUser> _userManager; public static Task<IdentityResult> ChangePasswordAsync(ApplicationUser user, string currentPassword, string newPassword) { return _userManager.ChangePasswordAsync(user.Id, currentPassword, newPassword); }

于 2016-08-10T15:36:15.293 回答