2015-07-26 13 views
14

Zaimplementowałem niestandardowy UserStore, implementuje on IUserStore<DatabaseLogin, int> i IUserPasswordStore<DatabaseLogin, int>.Używanie UserManager.FindAsync z niestandardowym UserStore

Moja metoda Logowanie działanie jest jak poniżej:

if (ModelState.IsValid) 
{ 
    if (Authentication.Login(user.Username, user.Password)) 
    { 
     DatabaseLogin x = await UserManager.FindAsync(user.Username, user.Password); 
     DatabaseLogin Login = Authentication.FindByName(user.Username); 
     if (Login != null) 
     { 
      ClaimsIdentity ident = await UserManager.CreateIdentityAsync(Login, 
       DefaultAuthenticationTypes.ApplicationCookie); 
      AuthManager.SignOut(); 
      AuthManager.SignIn(new AuthenticationProperties 
      { 
       IsPersistent = false 
      }, ident); 
      return RedirectToAction("Index", "Home"); 
     } 
    } 
    else 
    { 
     ModelState.AddModelError("", "Invalid Login"); 
    } 
} 
return View(); 

W niestandardowej klasy uwierzytelnienia, które napisałem, Authentication, mam metodę logowania, który działa dobrze, także FindByName metoda zwraca użytkownikowi aplikacji. Ale jeśli spróbuję użyć tego loginu, to użytkownik nie jest rozpoznawany jako uwierzytelniony, a HttpContext.User.Identity ma zawsze wartość zerową, więc wyobrażam sobie, że muszę spróbować UserManager.FindAsync. Ta metoda wywołuje FindByNameAsync i GetPasswordHashAsync i zawsze zwraca wartość null.

public Task<DatabaseLogin> FindByNameAsync(string userName) 
{ 
    if (string.IsNullOrEmpty(userName)) 
     throw new ArgumentNullException("userName"); 
    return Task.FromResult<DatabaseLogin>(Authentication.FindByName(userName)); 
} 

public Task<string> GetPasswordHashAsync(DatabaseLogin user) 
{ 
    if (user == null) 
     throw new ArgumentNullException("user"); 
    return Task.FromResult<string>(user.Password); 
} 

A Authentication.FindByName

public static DatabaseLogin FindByName(string name) 
{ 
    string GetUserQuery = string.Format(
     "USE db;SELECT principal_id AS id, name as userName, create_date AS CreateDate, modify_date AS modifyDate FROM sys.database_principals WHERE type='S' AND authentication_type = 1 AND name = '{0}'" 
     , name); 
    DatabaseLogin user; 
    using (var db = new EFDbContext()) 
    { 
     user = db.Database.SqlQuery<DatabaseLogin>(GetUserQuery).FirstOrDefault(); 
    } 
    user.Password = Convert.ToBase64String(Encoding.ASCII.GetBytes("pass")); 
    return user; 
} 

Jak widać używam użytkowników baz danych, nie jestem pewien, w jaki sposób mogę odzyskać zaszyfrowaną hasło dla nich. Na razie przechowuję tylko Base65 poprawnego hasła!

Nie mam pojęcia, gdzie idę źle, wszelkie wskazówki są mile widziane.

+0

Czy mógłbyś przekazać swoją odpowiedź poza swoje pytanie i właściwą odpowiedź WR? Możesz odpowiedzieć sobie. :) –

Odpowiedz

5

Krótka odpowiedź: nic nie jest nie tak. Użytkownik jest uwierzytelniony w innych metodach działania, ale najwyraźniej nie w obecnej metodzie działania.

Jest to proces, którego przestrzegałem, może to pomoże w debugowaniu aplikacji.

Po przeczytaniu source code, FindAsync pierwsze zaproszenia FindByNameAsync, a następnie przez CheckPasswordAsync który odwołuje VerifyPasswordAsync. Więc powinno być dobrze, jeśli mogę przesłonić VerifyPasswordAsync.

I stworzył zwyczaj password hasher który implementuje IPasswordHasher i zarejestrował go w metodzie create z moich UserManager jak ten:

manager.PasswordHasher = new DbPasswordHasher(); 

Więc teraz, mogę dostać użytkownikowi UserManager.FindAsync, ale okazało się, że nie ma znaczenia, skąd bierzesz użytkownika, ponieważ HttpContext.User.Identity jest nadal pusty! Mój błąd polegał na tym, że nie zauważyłem, że użytkownik nie jest uwierzytelniony w bieżącej akcji, w innych metodach działania działa zgodnie z oczekiwaniami!

Powiązane problemy