2013-09-30 2 views
45

Извинения и благодарности за этот вопрос! Я все еще новичок в SO.Как вы входите в систему/аутентифицируете пользователя с битами Asp.Net MVC5 RTM с использованием AspNet.Identity?

Я работаю на веб-приложений с использованием MVC5, Ef6 и VS 2013.

я провел некоторое время обновления до бита RC после освобождения. Благодаря всем замечательным сообщениям: например. Decoupling Microsoft.AspNet.Identity.* и Updating asp.net MVC from 5.0.0-beta2 to 5.0.0-rc1!

В моей бесконечной мудрости я решил перейти к битвам RTM, которые @Hao Kung опубликовали здесь: 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. Объект user и ClaimIdentity правильно заполнен.

Вот метод действия я называю (перемещаемых свойства локальных переменных для полноты):

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

(На стороне записки:. Я не нужно войти в систему внешних пользователей в это время)

Любые предложения? -or- Должен ли я откатывать все мои изменения и ждать, пока 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); 

To:

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

EDIT: А вам нужен следуйте за изменениями в вашем Startup.Auth.cs:

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

Удивительная благодарность ... просто любопытно, выполняются ли мои экземпляры «userManager» и «authenticationManager»? Я изменил свой метод входа на основе вашего предыдущего сообщения, поэтому я надеюсь, что я как бы пошел по правильному пути. – ACG

+0

Я реорганизовал мой метод входа и создал SignInAsync, как вы предложили. Мой код теперь похож на ваш (и исходный пост, который вы сделали). Метод _userManager.FindAsync возвращает мой правильный пользовательский пользователь (EtdsUser). Однако после вызова AuthenticationManager.SignIn ... User.Identity все еще пуст. В своем предыдущем ответе на аналогичный вопрос вы заявили: «Это, скорее всего, означает, что что-то пошло не так со знаком, и нет принципа претензий». _userManager.CreateIdentityAsync действительно возвращает действительный идентификатор, я просто не могу получить его «подписанный». – ACG

+0

См. мой отредактированный вопрос выше с дополнительной информацией. – ACG

Смежные вопросы