2013-09-30 2 views
45

Entschuldigung und Danke im Voraus für diese Frage! Ich bin noch neu in SO.Wie meldet/authentifiziert man einen Benutzer mit Asp.Net MVC5 RTM Bits mit AspNet.Identity?

ich auf einer Web-Anwendung arbeiten wurden mit MVC5, EF6 und VS 2013

verbrachte ich den RC Bits einige Zeit Upgrade einmal freigegeben. Danke an all die tollen Posts da draußen: zB. Decoupling Microsoft.AspNet.Identity.* und Updating asp.net MVC from 5.0.0-beta2 to 5.0.0-rc1!

In meiner unendlichen Weisheit, beschloss ich, zu den RTM-Bits zu gehen, die @Hao Kung hier gepostet: How can I get early access to upcoming Asp.Net Identity changes?. Ich dachte, ich würde mir die Mühe sparen und nicht zu weit zurückbleiben, wenn wir endlich den RTM-Build erhalten.

Das war entweder ein Albtraum, oder ich vermisse einfach etwas (oder beides), da ich grundlegende Aufgaben, die mit dem RC1-Zeug gearbeitet hatten, nicht verstehen kann.

Während es so aussieht, als würde ich den Benutzer über den Controller anmelden (Where is Microsoft.AspNet.Identity.Owin.AuthenticationManager in Asp.Net Identity RTM version?) ... ist meine WindowsIdentity immer leer und nicht authentifiziert, nachdem ich SignIn aufgerufen habe. Das Benutzer- und das claimsIdentity-Objekt sind korrekt ausgefüllt. Hier

ist die Aktionsmethode I (bewegte Objekte auf lokale Variablen auf Vollständigkeit) nenne:

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

(Auf einer seitlichen Anmerkung:. Ich brauche zu diesem Zeitpunkt nicht in externe Benutzer anmelden)

Irgendwelche Vorschläge? -oder- Sollte ich alle meine Änderungen zurücksetzen und nur warten, bis VS 2013 RTMd ist?


Update, Refaktor Code, um es näher an @ Hao Kungs ursprüngliche Antwort zu machen. Ich habe jedoch immer noch keine gültige Benutzeridentität. Ich denke mein AuthenticationManager ist nicht korrekt zugewiesen?

AuthenticationManger nun definiert als:

public IAuthenticationManager AuthenticationManager { get { return HttpContext.GetOwinContext().Authentication; } } 

SignInAsync nun eine separate Methode ist:

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

After "SignOut", der Debugger zeigt:

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

Die „claimsIdentity "ist dann:

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" ändert nichts:

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

Noch keine Authentifizierung, scheint aber, dass keine Fehler ausgelöst werden.


Wie von @Hao Kung beantwortet, geändert StartUp.Auth.cs aus:

var authOptions = new CookieAuthenticationOptions { ExpireTimeSpan = TimeSpan.FromHours(4.0)}; 
app.UseCookieAuthentication(authOptions); 

An:

var authOptions = new CookieAuthenticationOptions { 
    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 
    LoginPath = new PathString("/Account/Login"), 
    ExpireTimeSpan = TimeSpan.FromHours(4.0) 
}; ... 
+0

Es gibt eine Schnittstelle ... Microsoft.Owin.Security.IAuthenticationManager – user2315985

+0

Gibt es keine HttpContext.GetOwinContext(). Authentifizierung gibt eine Implementierung von IAuthenticationManager zurück? Zumindest dachte ich das, aber ich vermisse etwas. – ACG

Antwort

36

Also hier ist was Login wird in RTM (Code aus dem ASPNET Identity sample code kopiert) sehen aus wie im Grunde:

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

EDIT: Und Sie müssen die folgen Sie den Änderungen in Ihrem Startup.Auth.cs:

 app.UseCookieAuthentication(new CookieAuthenticationOptions { 
      AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 
      LoginPath = new PathString("/Account/Login") 
     }); 
+0

Awesome thanks ... nur neugierig, meine Instanziierungen von "UserManager" und "AuthenticationManager" richtig aussehen? Ich habe meine Login-Methode basierend auf deinem vorherigen Post geändert, also hoffe ich, dass ich den richtigen Weg eingeschlagen habe. – ACG

+0

Ich habe meine Login-Methode überarbeitet und SignInAsync erstellt, wie Sie es vorgeschlagen haben. Mein Code sieht jetzt ähnlich wie Ihres aus (und dem ursprünglichen Post, den Sie gemacht haben). Die _userManager.FindAsync-Methode gibt meinen korrekten benutzerdefinierten Benutzer (EtdsUser) zurück. Nach dem Aufruf von AuthenticationManager.SignIn ... ist die User.Identity jedoch immer noch leer. In Ihrer vorherigen Antwort auf eine ähnliche Frage haben Sie gesagt: "Das bedeutet höchstwahrscheinlich, dass etwas mit der Anmeldung schief gelaufen ist und keine Reklamation vorhanden ist". _userManager.CreateIdentityAsync gibt eine gültige Identität zurück, ich kann es nicht wirklich "signiert" bekommen. – ACG

+0

Siehe meine editierte Frage oben mit zusätzlichen Details. – ACG