2016-08-10 23 views
5

Środowisko: .Net Core 1, EF, przy użyciu Identity for authentication, tokeny JWT do autoryzacji.. .NET Core 1 Tożsamość UserManager - buforowana lista użytkowników nie aktualizująca się

Występuje problem polegający na tym, że za pomocą metody UserManager.ChangePasswordAsync() Uaktualniono poprawnie bazę danych, ale NIE aktualizuje ona listy UserManager.Users (przy założeniu).

W pliku Startup.cs, po prostu używamy app.UseIdentity(), aw konstruktorze ApplicationUserService wstrzykujemy UserManager<ApplicationUser>. Nie robimy niczego poza tym.

Na przykład: Powiedzmy, że użytkownik zmienia swoje hasło z "password1" na "password2". Jeśli ten użytkownik się wyloguje i ponownie zaloguje, menedżer użytkowników nadal uważa, że ​​hasło to "password1". Jeśli zrestartuję serwer WebAPI, spróbuj się zalogować; działa tak, jak można by się spodziewać po "password2". Z pewnością aktualizuje bazę danych, ale zakres/pamięć podręczna UserManagera nie jest aktualizowana.

Zastanawiam się, czy domyślny zakres DI menedżera UserManager jest singleton (a nie na żądanie)? Mogłem zobaczyć, że przyczyną tego problemu, jeśli nie jest aktualizowanie buforowanej listy użytkowników UserStore.

Wszelkie sugestie? Potrzebujesz więcej kodu?

ApplicationUserService (uproszczony):

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

[EDIT]

Nie jestem pewien, dlaczego tak jest całkiem jeszcze, ale zdałem sobie sprawę, że jeśli wstrzyknąć UserManager i SignInManager bezpośrednio do konstruktora kontrolera (zamiast do warstwy Service), wydaje się działać dobrze.

[EDIT 2]

Podsumowanie wyników:

1) Wstrzyknięcie UserManager i SignInManager do konstruktora usługi, a następnie wstrzykując że usługi do konstruktora sterownik nie działa w pełni.

2) Wstrzykuje menedżera UserManager i SignInManager do konstruktora kontrolera.

3) Przetestowałem również użycie IServiceProvider w konstruktorze Controller. Wstrzyknąłem IServiceProvider, a następnie ustawiono menedżerów za pomocą metody GetService: _userManager = serviceProvider.GetService<UserManager<ApplicationUser>>();. Miało to taki sam wynik jak nr 1.

W # 1 & # 3: Zapisałby się w bazie danych, ale menedżerowie wydawali się nie wiedzieć o zmianie danych, gdy są używane później. W obu przypadkach musiałem ponownie uruchomić aplikację (zatrzymać i uruchomić serwer), aby zaktualizować dane w pamięci podręcznej.

Czy numer 3 nie powinien być taki sam jak nr 2?

Odpowiedz

1

[Uwaga: poniższy kod nie ma zastosowania do Asp.Net Core. Aby uzyskać uwierzytelnienie w Asp.Net Core, spójrz na: this documentation.]

Jestem nowy w Asp.Net, ale próbowałem zrobić to, co opisałeś. Dla mnie działa zgodnie z oczekiwaniami. Może mój kod może dla ciebie zainspirować pomysł.

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

+0

Kiedy próbuję zainicjować nową UserManager ręcznie, skończę konieczności przejścia w pęczek zmiennych. Jedynym konstruktor widzę od klasy UserManager to: 'UserManager publicznych (IUserStore sklep, nazwami opcji optionsAccessor, IPasswordHasher passwordHasher, IEnumerable > userValidators, IEnumerable > passwordValidators, ILookupNormalizer keyNormalizer, IdentityErrorDescriber błędy, usługi IServiceProvider, ILogger > logger); ' – Kizmar

+0

Jeśli jesteśmy w Core, czy nie powinniśmy używać' nowego Microsoft.AspNetCore.Identity.UserManager () '? – Kizmar

+0

Przepraszamy, użyłem niewłaściwej wersji Asp.Net. Otworzyłem nowy projekt ASP.Net Core WebApplication w Visual Studio i nie mogę nawet znaleźć usługi ApplicationUserService, o którą chodziło. Zmiana hasła projektu zadziałała. Jeśli jej potrzebujesz, oto dokumentacja: https://docs.asp.net/en/latest/security/authentication/identity.html –