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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19091157/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 14:03:55  来源:igfitidea点击:

How do you login/authenticate a user with Asp.Net MVC5 RTM bits using AspNet.Identity?

c#visual-studio-2013asp.net-mvc-5asp.net-identityowin

提问by ACG

Apologies and Thanks in advance for this question! I am still new to SO.

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

I have been working on a web application using MVC5, EF6, and VS 2013.

我一直在使用 MVC5、EF6 和 VS 2013 开发 Web 应用程序。

I spent some time upgrading to the RC bits once released. Thanks to all the great posts out there: eg. Decoupling Microsoft.AspNet.Identity.*and Updating asp.net MVC from 5.0.0-beta2 to 5.0.0-rc1!

发布后,我花了一些时间升级到 RC 位。感谢那里的所有精彩帖子:例如。解耦 Microsoft.AspNet.Identity.*并将asp.net MVC 从 5.0.0-beta2 更新到 5.0.0-rc1

In my infinite wisdom, I decided to move to the RTM bits that @Hao Kung posted about here: How can I get early access to upcoming Asp.Net Identity changes?. I figured I would save the trouble and not be too far behind when we finally receive the RTM build.

在我无限的智慧中,我决定转向@Hao Kung 在此处发布的 RTM 位:如何尽早访问即将到来的 Asp.Net Identity 更改?. 我想当我们最终收到 RTM 版本时,我会省去麻烦并且不会落后太多。

This has either been a nightmare, or I am just completely missing something (or both) as I can not figure out basic tasks that had been working with the RC1 stuff.

这要么是一场噩梦,要么我完全错过了某些东西(或两者兼有),因为我无法弄清楚使用 RC1 的东西的基本任务。

While it seems like I am logging the user in via the controller (Where is Microsoft.AspNet.Identity.Owin.AuthenticationManager in Asp.Net Identity RTM version?) ... my WindowsIdentity is always empty and not authenticated after I call SignIn. The user and claimsIdentity object are correctly populated.

虽然看起来我是通过控制器登录用户(Asp.Net Identity RTM 版本中的 Microsoft.AspNet.Identity.Owin.AuthenticationManager 在哪里?)...我的 WindowsIdentity 始终为空,并且在我调用 SignIn 后未通过身份验证。user 和 claimIdentity 对象已正确填充。

Here is the action method I am calling (moved properties to local variables for completeness):

这是我正在调用的操作方法(为了完整性将属性移动到局部变量):

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

(On a side note: I do not need to log in external users at this time.)

(附带说明:此时我不需要登录外部用户。)

Any suggestions? -or- Should I roll back all my changes and just wait until VS 2013 is RTMd?

有什么建议?- 或者 - 我应该回滚我的所有更改并等到 VS 2013 成为 RTMd 吗?



Update, refactored code to make it closer to @Hao Kung's original reply. However I still do not end up with a valid user identity. I think my AuthenticationManager is not assigned correctly?

更新、重构代码以使其更接近@Hao Kung 的原始回复。但是,我仍然没有得到有效的用户身份。我认为我的 AuthenticationManager 没有正确分配?

AuthenticationManger is now defined as:

AuthenticationManger 现在定义为:

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

SignInAsync is now a separate method:

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

After "SignOut", the debugger shows:

在“SignOut”之后,调试器显示:

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

The "claimsIdentity" is then:

那么“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"

"SignIn" does not change anything:

“登录”不会改变任何东西:

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

Still no Authentication, but seems that no errors are thrown.

仍然没有身份验证,但似乎没有抛出错误。



As answered by @Hao Kung, changed StartUp.Auth.cs from:

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

采纳答案by Hao Kung

So here's what login will basically look like in RTM (code copied from the ASPNET Identity sample code):

所以这里是登录在 RTM 中的基本样子(从ASPNET Identity 示例代码复制的代码):

    //
    // 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: And you need the follow changes in your Startup.Auth.cs:

编辑:并且您需要在 Startup.Auth.cs 中进行以下更改:

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