2013-09-30 9 views
45

Przepraszam iz góry dziękuję za to pytanie! Wciąż jestem nowy w SO.Jak zalogować/uwierzytelnić użytkownika za pomocą bitów RTM Asp.Net MVC5 przy użyciu AspNet.Identity?

pracuję nad aplikacji internetowych z wykorzystaniem MVC5, EF6 i VS 2013

Spędziłem trochę czasu na aktualizację do bitów RC raz uwolnione. Dzięki wszystkim świetnym postom tam: np. Decoupling Microsoft.AspNet.Identity.* i Updating asp.net MVC from 5.0.0-beta2 to 5.0.0-rc1!

W mojej nieskończonej mądrości zdecydowałem się przenieść na bity RTM, które @Hao Kung zamieścił tutaj: How can I get early access to upcoming Asp.Net Identity changes?. Pomyślałem, że zaoszczędzę kłopotów i nie będę za daleko, kiedy wreszcie otrzymamy kompilację RTM.

To był albo koszmar, albo po prostu kompletnie czegoś brakuje (albo jedno i drugie), ponieważ nie mogę wymyślić podstawowych zadań, które pracowały z materiałami RC1.

Chociaż wygląda na to, że loguję użytkownika za pomocą kontrolera (Where is Microsoft.AspNet.Identity.Owin.AuthenticationManager in Asp.Net Identity RTM version?) ... mój WindowsIdentity jest zawsze pusty i nie jest uwierzytelniany po tym, jak zadzwonię do SignIn. Obiekt user i claimIdentity są poprawnie wypełnione.

Oto metoda działania Wołam (przeniesiony właściwości do zmiennych lokalnych dla kompletności):

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

(Na marginesie:. I nie trzeba logować się użytkownikom zewnętrznym w tym czasie)

Wszelkie sugestie? -lub- Czy powinienem wycofać wszystkie moje zmiany i po prostu poczekać, aż VS 2013 to RTMd?


Zaktualizuj, poprawiaj kod, aby był bliżej oryginalnej odpowiedzi @Hao Kung. Jednak wciąż nie otrzymuję prawidłowej tożsamości użytkownika. Myślę, że mój Menedżer uwierzytelniania nie jest przypisany poprawnie?

AuthenticationManger jest obecnie definiowany jako:

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

SignInAsync jest oddzielny sposób:

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

po "SignOut" debugera pokazuje:

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

przycisków „claimsIdentity "jest następnie:

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" niczego nie zmienia:

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

Nadal brak uwierzytelniania, ale wydaje się, że nie ma błędów są wyrzucane.


Jak odpowiedział @Hao Kung, zmieniono StartUp.Auth.cs od:

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

Do:

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

Istnieje interfejs ... Microsoft.Owin.Security.IAuthenticationManager – user2315985

+0

Nie HttpContext.GetOwinContext(). Uwierzytelnianie zwraca implementację IAuthenticationManager? Przynajmniej tak myślałem, ale może czegoś brakuje. – ACG

Odpowiedz

36

Więc oto co logowania będzie w zasadzie wyglądają jak w RTM (kod skopiowany z ASPNET Identity sample code):

// 
    // 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: i trzeba śledź zmiany w swoim Starcie.Auth.cs:

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

Niesamowite dzięki ... ciekawe, czy moje wystąpienia "userManager" i "authenticationManager" wyglądają poprawnie? Zmodyfikowałem metodę logowania na podstawie poprzedniego postu, więc mam nadzieję, że podążałem właściwą drogą. – ACG

+0

Przebudowałem moją metodę logowania i utworzyłem SignInAsync zgodnie z sugestią. Mój kod wygląda teraz podobnie do twojego (i oryginalnego wpisu). Metoda _userManager.FindAsync zwraca mój prawidłowy niestandardowy użytkownik (EtdsUser). Jednak po wywołaniu AuthenticationManager.SignIn ... User.Identity jest nadal pusta. W poprzedniej odpowiedzi na podobne pytanie napisałeś "To najprawdopodobniej oznacza, że ​​coś poszło nie tak podczas rejestracji, a nie ma żadnych roszczeń". _userManager.CreateIdentityAsync zwraca poprawną tożsamość, po prostu nie mogę jej "podpisać". – ACG

+0

Zobacz moje edytowane pytanie powyżej z dodatkowymi szczegółami. – ACG

Powiązane problemy