Implementé un UserStore personalizado, implementa IUserStore<DatabaseLogin, int> y IUserPasswordStore<DatabaseLogin, int> .
Mi método de acción de inicio de sesión es el siguiente:
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(); En la clase de autenticación personalizada que escribí, Authentication , tengo un método de inicio de sesión que funciona bien, también el método FindByName devuelve un usuario de la aplicación. Pero si intento iniciar sesión con ese inicio de sesión, el usuario no se reconoce como autenticado y HttpContext.User.Identity siempre es nulo, así que imagino que tengo UserManager.FindAsync SignIn
Este método llama a FindByNameAsync y GetPasswordHashAsync y siempre devuelve un valor nulo.
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); } Y la 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; }Como puede ver, estoy usando usuarios de la base de datos, no estoy seguro de cómo puedo recuperar una contraseña cifrada para ellos. ¡Por ahora, solo estoy almacenando el Base65 de la contraseña correcta!
No tengo idea de dónde me estoy equivocando, cualquier orientación es bienvenida.
Respuesta corta: no pasa nada. El usuario está autenticado en otros métodos de acción, pero aparentemente no en el método de acción actual.
Este es el proceso que seguí, tal vez te ayude a depurar tu aplicación.
Después de leer el código fuente , FindAsync primero llama a FindByNameAsync , seguido de CheckPasswordAsync , que hace referencia VerifyPasswordAsync . Entonces debería estar bien si pudiera anular VerifyPasswordAsync .
Creé un password hasher personalizado que implementa IPasswordHasher y lo registré en el método de create de mi UserManager de esta manera:
manager.PasswordHasher = new DbPasswordHasher(); Entonces, a estas alturas, puedo obtener mi usuario de UserManager.FindAsync , pero resultó que no importa dónde obtenga el usuario, ya que HttpContext.User.Identity aún es nulo. Mi error fue que no noté que el usuario no está autenticado en la acción actual, ¡en otros métodos de acción funciona como se esperaba!