如何强制更新自定义用户声明?

Met*_*ian 5 asp.net asp.net-mvc claims-based-identity asp.net-identity

我在 ApplicationUser 类中添加了一个自定义声明,如下所示:

public class ApplicationUser : IdentityUser
{
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        if(Theme != null)
            userIdentity.AddClaim(new Claim("ThemeBundle", Theme.Bundle));

        return userIdentity;
    }

    public int? ThemeId { get; set; }
    [ForeignKey("ThemeId")]
    public virtual Theme Theme { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

我像这样扩展了 Identity:

public static class IdentityExtensions
{
    public static string GetThemeBundle(this IIdentity identity)
    {
        var claim = ((ClaimsIdentity) identity).FindFirst("ThemeBundle");
        // Test for null to avoid issues during testing
        return (claim != null) ? claim.Value : string.Empty;
    }
}
Run Code Online (Sandbox Code Playgroud)

我从以下操作方法更新了声明背后的模型:

    public ActionResult ChangeTheme(int id)
    {
        var theme = _db.Themes.Find(id);
        if (theme == null)
            return HttpNotFound();

        var userId = User.Identity.GetUserId();
        var user = _db.Users.Find(userId);
        user.Theme = theme;
        _db.SaveChanges();

        return RedirectToAction("Index", "Home");
    }
Run Code Online (Sandbox Code Playgroud)

我在这样的视图(或其他地方)中访问它:

User.Identity.GetThemeBundle()
Run Code Online (Sandbox Code Playgroud)

当用户使用“ChangeTheme”操作更新他们的“Theme”属性时,在他们注销并重新登录之前什么都不会发生。

我花了一整天的时间仔细考虑以下 QA,但没有取得好的结果:

更新用户声明未生效。为什么?

MVC 5 AddToRole 需要注销才能工作?

并感谢@Brendan Green:ASP.NET Identity - 使用安全图章强制重新登录

到目前为止,我得到的最好的是页面将刷新并且声明返回一个空字符串而不是所需的结果,或者我将用户重定向到登录屏幕。至少那些比什么都不发生要更明确。

一旦用户更改了他们的“主题”属性,我究竟如何才能获得全局更新的声明?如果需要,我会选择一种完全注销用户并重新登录的好方法。使用 AuthenticationManager.Signout 和 .Signin 方法并不能完全解决问题。

eri*_*red 5

Asp.Net MVC 6Asp.Identity 3.0.0-rc1-final 开始,您可以使用 Task SignInManager<TUser>.RefreshSignInAsync(TUser user);它来做到这一点。

  • 这是有效的,[但似乎仅适用于当前登录的用户](/sf/ask/3610029671/),从而提出了为什么用户可以通过的问题。如果我传递不同的用户,当前登录的用户将改为以该用户身份登录。 (2认同)