我有一个自定义声明添加到我的 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; }
}
我像这样扩展了身份:
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;
}
}
我从以下操作方法更新声明背后的模型:
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");
}
我在这样的视图(或其他地方)访问它:
User.Identity.GetThemeBundle()
当用户使用"更改主题"操作更新其"主题"属性时,在注销并重新登录之前不会发生任何操作。
我花了一整天的时间考虑以下QA以上,但没有好的结果:
更新用户声明未生效。为什么?
MVC 5 AddToRole 需要注销才能工作?
感谢@Brendan格林:ASP.NET 身份 - 使用安全标记强制重新登录
到目前为止,我得到的最好的是页面将刷新并且声明返回一个空字符串而不是所需的结果,或者我将用户重定向到登录屏幕。至少这些比什么都没发生要模棱两可。
我到底如何在用户更改其"主题"属性后立即获得全局更新的声明?如果需要,我会选择一种完全注销用户并重新登录的好方法。使用 AuthenticationManager.Signout 和 。登录方法并不能完全解决问题。
从 Asp.Net MVC 6和Asp.Identity 3.0.0-rc1-final开始,您可以使用Task SignInManager<TUser>.RefreshSignInAsync(TUser user);
来做到这一点。