c# - framework - ¿Cómo inicia sesión/autentica a un usuario con Asp.Net MVC5 RTM usando AspNet.Identity?
mvc 5 login example in c# (1)
¡Disculpas y gracias de antemano por esta pregunta! Todavía soy nuevo en SO.
He estado trabajando en una aplicación web usando MVC5, EF6 y VS 2013.
Pasé algún tiempo actualizando a los bits RC una vez lanzado. Gracias a todos los mensajes grandiosos que hay: p. Ej. Desacoplando Microsoft.AspNet.Identity. * Y Actualizando asp.net MVC de 5.0.0-beta2 a 5.0.0-rc1 !
En mi sabiduría infinita, decidí pasar a los bits de RTM que @Hao Kung publicó aquí: ¿Cómo puedo obtener acceso anticipado a los próximos cambios de Identidad de Asp.Net? . Pensé que me ahorraría el problema y que no me quedaría atrás cuando finalmente recibiéramos la compilación de RTM.
Esto ha sido una pesadilla o simplemente me falta algo por completo (o ambos) ya que no puedo descifrar las tareas básicas que han estado trabajando con RC1.
Si bien parece que estoy registrando al usuario a través del controlador ( ¿Dónde está Microsoft.AspNet.Identity.Owin.AuthenticationManager en la versión Asp.Net Identity RTM? ) ... mi WindowsIdentity siempre está vacía y no se autentica después de que llamo a SignIn. El usuario y el objeto claimsIdentity están correctamente poblados.
Aquí está el método de acción que estoy llamando (propiedades movidas a variables locales para completar):
[HttpPost, AllowAnonymous, ValidateAntiForgeryToken]
public virtual async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (ModelState.IsValid) {
var userManager = new UserManager<EtdsUser>(new UserStore<EtdsUser>(new EtdsContext()));
var user = userManager.Find(model.UserName, model.Password);
if (user != null) {
var authenticationManager = HttpContext.GetOwinContext().Authentication;
authenticationManager.SignOut(new[] {DefaultAuthenticationTypes.ApplicationCookie, DefaultAuthenticationTypes.ExternalCookie, DefaultAuthenticationTypes.ExternalBearer});
var claimsIdentity = await userManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
authenticationManager.SignIn(new AuthenticationProperties { IsPersistent = model.RememberMe}, claimsIdentity);
return RedirectToLocal(returnUrl);
}
}
ModelState.AddModelError("", "The user name or password provided is incorrect.");
return View(model);
}
(En una nota al margen: no necesito iniciar sesión con usuarios externos en este momento).
¿Alguna sugerencia? -o-- ¿Debo deshacer todos mis cambios y esperar hasta que VS 2013 sea RTMd?
Actualiza, refactoriza el código para que esté más cerca de la respuesta original de @Hao Kung. Sin embargo, todavía no termino con una identidad de usuario válida. Creo que mi AuthenticationManager no está asignado correctamente?
AuthenticationManger ahora se define como:
public IAuthenticationManager AuthenticationManager { get { return HttpContext.GetOwinContext().Authentication; } }
SignInAsync es ahora un método separado:
private async Task SignInAsync(EtdsUser user, bool isPersistent)
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
var claimsIdentity = await _userManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
AuthenticationManager.SignIn(new AuthenticationProperties { IsPersistent = isPersistent}, claimsIdentity);
}
Después de "SignOut", el depurador muestra:
AuthenticationManager.User.Identity
{System.Security.Principal.WindowsIdentity}
[System.Security.Principal.WindowsIdentity]: {System.Security.Principal.WindowsIdentity}
AuthenticationType: ""
IsAuthenticated: false
Name: ""
El "claimIdentity" es entonces:
claimsIdentity
{System.Security.Claims.ClaimsIdentity}
Actor: null
AuthenticationType: "ApplicationCookie"
BootstrapContext: null
Claims: {System.Security.Claims.ClaimsIdentity.get_Claims}
IsAuthenticated: true
Label: null
Name: "alon"
NameClaimType: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"
RoleClaimType: "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"
"Iniciar sesión" no cambia nada:
AuthenticationManager.User.Identity
{System.Security.Principal.WindowsIdentity}
[System.Security.Principal.WindowsIdentity]: {System.Security.Principal.WindowsIdentity}
AuthenticationType: ""
IsAuthenticated: false
Name: ""
Todavía no hay Autenticación, pero parece que no se lanzaron errores.
Como respondió @Hao Kung, cambió StartUp.Auth.cs desde:
var authOptions = new CookieAuthenticationOptions { ExpireTimeSpan = TimeSpan.FromHours(4.0)};
app.UseCookieAuthentication(authOptions);
A:
var authOptions = new CookieAuthenticationOptions {
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login"),
ExpireTimeSpan = TimeSpan.FromHours(4.0)
}; ...
Así que esto es lo que básicamente será el inicio de sesión en RTM (código copiado del código de muestra de ASPNET Identity ):
//
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (ModelState.IsValid)
{
var user = await UserManager.FindAsync(model.UserName, model.Password);
if (user != null)
{
await SignInAsync(user, model.RememberMe);
return RedirectToLocal(returnUrl);
}
else
{
ModelState.AddModelError("", "Invalid username or password.");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
private async Task SignInAsync(ApplicationUser user, bool isPersistent)
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
}
EDITAR: Y necesita los siguientes cambios en su Startup.Auth.cs:
app.UseCookieAuthentication(new CookieAuthenticationOptions {
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/Account/Login")
});