如何使用 ASP.NET Identity 在 ASP.NET MVC 5 应用程序中设置当前用户?

How do you set the current user in an ASP.NET MVC 5 application using ASP.NET Identity?

我很难弄清楚如何在使用 ASP.NET Identity 的 ASP.NET MVC 5 应用程序中设置当前用户。

我们使用封装身份验证的 Web 服务。一个函数调用该服务并取回一个 JWT 令牌,该令牌可以是 "unwrapped" 以检索 ClaimsIdentity。据我了解,此时您需要做的就是调用 HttpContext.GetOwinContext().Authentication.SignIn() 并传递 ClaimsIdentity 以建立当前用户并让该用户在请求中保持不变。

然而,情况似乎并非如此。如果我在控制器或视图中查询 this.User 之后,它是一个匿名用户(this.User.Identity.IsAuthenticated 评估为 false)。此外,刷新页面或重定向会明显表明没有当前用户(同样,this.User.Identity.IsAuthenticated 计算为 false)。

当我检查从 AccountHelper 检索到的身份时,所有数据都在那里。它完全填充了一个名称、一个 ID 和一整套声明。

那么建立当前用户并让它在请求中持续存在的正确方法是什么?

// This call authenticates a user with the provided credentials against our user store
// and returns a bearer token and a ClaimsIdentity.
var response = new AccountHelper().AuthenticateUser(credentials);

if (response.IsAuthenticated) // This is true
{
    // This comes back with a fully populated identity, as expected.
    var claimsIdentity = response.ClaimsIdentity; 

    // This call has no effect, whatsoever. It doesn't set the current user.
    HttpContext.GetOwinContext()
               .Authentication
               .SignIn(new AuthenticationProperties { IsPersistent = true }, claimsIdentity);

首先,您是否错过了代码示例中的 .Current

应该是

HttpContext.Current.GetOwinContext()
    .Authentication
    .SignIn(...);

其次,我假设您已经在您的应用程序中设置了 cookie 身份验证?

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationType = CookieAuthenticationDefaults.AuthenticationType,
    ...
});

这里设置认证类型很重要!当您生成声明身份并在将其传递给 .SignIn() 方法之前,声明身份需要具有相同的身份验证类型,以便它们可以交谈!

我会使用 UserManager class 中的 .CreateIdentityAsync() 方法来创建身份,因为您可以将身份验证类型作为参数之一传入:

// Create an application user from your claim identity?
var appUser = new AppUser { ... };

// And pass the user into manager to create the identity with the same authentication
// type you used when you setup the cookie authentication
var claimsIdentity = _userManager.CreateIdentityAsync(appUser,
    CookieAuthenticationDefaults.AuthenticationType);

我正在使用这种方式为具有开发人员角色的管理员模拟用户,以便我们可以测试该应用程序。