c# - mvc - ¿Cómo utilizar ActiveDirectoryMembershipProvider con ASP.Net Identity?
login identity c# (2)
Estoy tratando de aprender a usar ASP.Net Identity. Mi escenario es que tengo que autenticarme contra Active Directory. Para eso estoy tratando de usar ActiveDirecotoryMembershipProvider
. Lo que tengo que hacer es ...
- Autenticar usuario / contraseña contra Active Directory.
- Compruebe si el usuario está presente en mi propia base de datos.
La forma en que lo hice es configurarlo en mi web.config
para usar ActiveDirectoryMembershipProvider
como proveedor de membresía predeterminado. Luego, anulo el método PasswordSignInAsync
en mi clase ApplicationSignInManager
(que hereda SignInManager
) de la siguiente manera:
public override Task<SignInStatus> PasswordSignInAsync(string userName, string password, bool isPersistent, bool shouldLockout)
{
var adok = Membership.Provider.ValidateUser(userName, password);
if (adok)
{
var user = UserManager.FindByName(userName);
if (user == null)
return Task.FromResult<SignInStatus>(SignInStatus.Failure);
else
{
base.SignInAsync(user, isPersistent, shouldLockout);
return Task.FromResult<SignInStatus>(SignInStatus.Success);
}
}
else
return Task.FromResult<SignInStatus>(SignInStatus.Failure);
}
Esto parece funcionar. Pero creo que no es la forma correcta de hacerlo. ¿Alguien puede sugerir alguna manera mejor de lograr esto?
ACTUALIZAR
Así es como llamé a lo anterior.
var result = await SignInManager.PasswordSignInAsync(username, password, isPersistent: false, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
return RedirectToAction("Index", "Home");
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
return View();
}
De acuerdo con las respuestas que obtuve, no debería llamar al método de Validate
Membresía dentro de PasswordSignInAsync
. Estoy de acuerdo con eso. De hecho, creo que anular el método también es incorrecto.
También se sugirió que usara UserLogins
donde le daría a mi AD una identificación de proveedor. Pero la única forma en que puedo pensar en usar esto es la siguiente:
IList<UserLoginInfo> loginInfos = await SignInManager.UserManager.GetLoginsAsync(username);
var valid = false;
foreach(var info in loginInfos)
{
valid = Membership.Providers[info.ProviderKey].ValidateUser(username, password);
if (valid) break;
}
Por lo tanto, si quiero autenticar a un usuario contra varios proveedores, puedo crear una clave de proveedor para cada uno de ellos y asignar esas claves de proveedor a los usuarios. Y este código validará al usuario contra ellos. ¿Pero dónde debo poner este código? ¿Qué convención debo seguir?
No estoy interesado en codificar la validación de AD porque creo que ActiveDirectoryMembershipProvider
puede hacer un mejor trabajo que mi propio código. También para ambos casos tengo que agregar referencias a System.DirectoryServices
todos modos.
No desea mezclar MembershipProviders con identidad. Lo que más probablemente querrá hacer es tratar el inicio de sesión en ActiveDirectory de manera similar a como la identidad trata a otros inicios de sesión externos (como google / facebook).
Básicamente, esto se reduce a almacenar el nombre de usuario de AD como un inicio de sesión:
userManager.AddLogin(<userId>, new UserLoginInfo("ActiveDirectory", "<ADUserName>")
Si solo inicia sesión a través de AD, entonces podría anular PasswordSignIn para validar explícitamente contra AD
De lo contrario, querrá esto solo en el flujo de inicio de sesión específico para AD, conservando la contraseña local existente y la funcionalidad de inicio de sesión social.
Pruébalo una vez siguiendo el paso, tal vez te sea de utilidad.