【问题标题】:.Net Core 1 Identity UserManager cached user list not updating.Net Core 1 Identity UserManager 缓存的用户列表未更新
【发布时间】:2016-12-17 00:24:27
【问题描述】:

环境:.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 的缓存用户列表,我可以看到导致此问题。

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

ApplicationUserService(简体):

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&lt;UserManager&lt;ApplicationUser&gt;&gt;();。这与#1 的结果相同。

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

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

【问题讨论】:

    标签: c# asp.net-core identity usermanager


    【解决方案1】:

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

    我是 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); }

    【讨论】:

    • 当我尝试手动初始化一个新的 UserManager 时,我最终不得不传入一堆变量。我在 UserManager 类上看到的唯一构造函数是:public UserManager(IUserStore&lt;TUser&gt; store, IOptions&lt;IdentityOptions&gt; optionsAccessor, IPasswordHasher&lt;TUser&gt; passwordHasher, IEnumerable&lt;IUserValidator&lt;TUser&gt;&gt; userValidators, IEnumerable&lt;IPasswordValidator&lt;TUser&gt;&gt; passwordValidators, ILookupNormalizer keyNormalizer, IdentityErrorDescriber errors, IServiceProvider services, ILogger&lt;UserManager&lt;TUser&gt;&gt; logger);
    • 如果我们在核心,我们不应该使用new Microsoft.AspNetCore.Identity.UserManager&lt;ApplicationUser&gt;()吗?
    • 抱歉,我使用了错误版本的 Asp.Net。我在 Visual Studio 中打开了一个新的 Asp.Net Core WebApplication 项目,我什至找不到您正在使用的 ApplicationUserService。该项目的密码更改工作。如果您需要,这里有一些文档:docs.asp.net/en/latest/security/authentication/identity.html
    • 我确实注意到我可以将 UserManager 和 SignInManager 直接注入到控制器中,这一切都按预期工作。出于某种原因,当我尝试在服务层中使用它们时,就会遇到问题。
    • 您是否有特定原因直接注入新的 UserManager?
    猜你喜欢
    • 2017-10-29
    • 2019-08-21
    • 2017-08-09
    • 1970-01-01
    • 2016-11-09
    • 2021-09-04
    • 1970-01-01
    • 1970-01-01
    • 2021-09-06
    相关资源
    最近更新 更多