如何使用AspNet.Identity使用Asp.Net MVC5 RTM位登录/验证用户?

时间:2013-09-30 09:48:34

标签: c# visual-studio-2013 asp.net-mvc-5 asp.net-identity owin

道歉并提前感谢您提出这个问题!我还是SO的新手。

我一直在使用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后未经过身份验证。用户和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);
}

(旁注:此时我不需要登录外部用户。)

有什么建议吗? -要么- 我应该回滚所有更改并等到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: ""

然后是“claimIdentity”:

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”不会改变任何内容:

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

1 个答案:

答案 0 :(得分:39)

所以这里的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")
        });