Cómo iniciar sesión/autenticar un usuario con Asp.Net Bits MVC5 RTM usando AspNet.Identidad?


Disculpas y Gracias de antemano por esta pregunta! Todavía soy nuevo en ESO.

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 liberados. Gracias a todos los grandes mensajes por ahí: por ejemplo. Desacoplar Microsoft.AspNet.Identidad.* y Actualización asp.net MVC de 5.0.0-beta2 a 5.0.0-rc1 !

En mi infinita sabiduría, decidí pasar a los bits de RTM que @Hao Kung publicó sobre aquí: ¿Cómo puedo obtener acceso anticipado a próximos Asp.Net ¿Cambios de identidad?. Pensé que me ahorraría el problema y no estaría demasiado atrás cuando finalmente recibiéramos la construcción de RTM.

Esto ha sido una pesadilla, o simplemente me estoy perdiendo algo por completo (o ambos) ya que no puedo entender las tareas básicas que habían estado trabajando con las cosas RC1.

Mientras que parece que estoy registrando al usuario a través del controlador ( Donde está Microsoft.AspNet.Identidad.Owin.AuthenticationManager en Asp.Net Identidad versión RTM?) ... mi WindowsIdentity siempre está vacía y no autenticada después de mi indicativo de llamada. El objeto user y ClaimsIdentity se rellenan correctamente.

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

(Nota al margen: No necesito iniciar sesión en usuarios externos en este momento.)

Alguna sugerencia? -o- Debo revertir todos mis cambios y solo espera hasta VS 2013 es RTMd?


Actualización, refactorizado código para hacerlo más cercano a 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 "Firmar", el depurador muestra:

AuthenticationManager.User.Identity
{System.Security.Principal.WindowsIdentity}
    [System.Security.Principal.WindowsIdentity]: {System.Security.Principal.WindowsIdentity}
    AuthenticationType: ""
    IsAuthenticated: false
    Name: ""

La "ClaimsIdentity" 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"

"SignIn" no cambia cualquier cosa:

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 producen errores.


Como respondió @Hao Kung, se cambió el inicio.Auth.cs de:

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)
}; ...
Author: Community, 2013-09-30

1 answers

Así que así es como se verá básicamente el inicio de sesión en RTM (código copiado del código de ejemplo de identidad de ASPNET ):

    //
    // 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 Inicio.Auth.cs:

        app.UseCookieAuthentication(new CookieAuthenticationOptions {
            AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
            LoginPath = new PathString("/Account/Login")
        });
 39
Author: Hao Kung,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-12 16:17:40