2013-09-30 49 views
45

道歉和預先感謝這個問題!我還是新來的。如何使用AspNet.Identity以Asp.Net MVC5 RTM位登錄/驗證用戶?

我一直在使用MVC5,EF6和VS 2013

一個Web應用程序我花了一些時間升級到一次發佈的RC位。感謝所有偉大的職位:例如。 Decoupling Microsoft.AspNet.Identity.*Updating asp.net MVC from 5.0.0-beta2 to 5.0.0-rc1

以我無窮的智慧,我決定轉移到@Hao Kung在這裏發佈的RTM位:How can I get early access to upcoming Asp.Net Identity changes?。我想我會省下麻煩,並且在我們最終獲得RTM版本時不會太落後。

這可能是一場噩夢,或者我完全錯過了一些(或者兩者兼有),因爲我無法弄清楚一直使用RC1的東西的基本任務。

雖然好像我通過控制器(Where is Microsoft.AspNet.Identity.Owin.AuthenticationManager in Asp.Net Identity RTM version?)登錄用戶...我的WindowsIdentity總是空的,我沒有通過SignIn進行身份驗證。用戶和claimsIdentity對象正確填充。

下面是操作方法我打電話(移動性局部變量的完整性):

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

(在一個側面說明:我不需要登錄,此時外部用戶)

有什麼建議嗎? - 或 - 我是否應該回滾所有更改並等待VS 2013爲RTMd?


更新,重構代碼,使其更接近@Hao Kung的原始答覆。但是,我仍然沒有得到有效的用戶身份。我認爲我的AuthenticationManager分配不正確?

AuthenticationManger現在定義爲:

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

SignInAsync現在是一個單獨的方法:

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

「SignOut」 後,調試器顯示:

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

的「claimsIdentity 「然後是:

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" 

「簽到」並沒有改變任何東西:

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

仍然沒有驗證,但似乎沒有錯誤拋出。


由@Hao Kung回答,更改了StartUp.Auth。CS來自:

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

要:

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

有一個接口... Microsoft.Owin.Security.IAuthenticationManager – user2315985

+0

不HttpContext.GetOwinContext()。身份驗證返回IAuthenticationManager的實現?至少我認爲它確實如此,但我可能會錯過一些東西。 – ACG

回答

36

那麼這裏就是登錄將基本上看起來像在RTM(從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); 
    } 

編輯:你所需要的請遵循Startup.Auth.cs中的更改:

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

真棒謝謝...只是好奇,做我的「用戶管理器」和「身份驗證管理器」的實例化看起來是正確的?我根據你以前的帖子修改了我的登錄方法,所以我希望我能夠走上正確的道路。 – ACG

+0

我重構了我的登錄方法,並按照您的建議創建了SignInAsync。我的代碼現在看起來與您的相似(以及您製作的原始帖子)。 _userManager.FindAsync方法返回我正確的自定義用戶(EtdsUser)。然而,在調用AuthenticationManager.SignIn之後,User.Identity仍然是空的。在您之前對類似問題的回覆中,您表示「最有可能意味着登錄出現問題,並且沒有索賠負責人。」 _userManager.CreateIdentityAsync確實會返回一個有效的標識,我實際上不能將其「簽名」。 – ACG

+0

請參閱上面我編輯的問題並提供其他詳細信息。 – ACG

相關問題