【发布时间】:2016-01-25 23:07:26
【问题描述】:
我在 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()
当用户使用“ChangeTheme”操作更新他们的“Theme”属性时,在他们注销并重新登录之前什么都不会发生。
我花了一整天的时间考虑以下质量检查,但没有好的结果:
Update User Claim not Taking Effect. Why?
MVC 5 AddToRole requires logout before it works?
感谢@Brendan Green:ASP.NET Identity - Forcing a re-login with security stamp
到目前为止,我得到的最好的结果是页面将刷新并且声明返回一个空字符串而不是所需的结果,或者我将用户重定向到登录屏幕。至少那些比什么都没有发生更不那么模棱两可。
一旦用户更改其“主题”属性,我到底如何才能获得全球更新的声明?如果需要,我会选择一种完全注销用户并重新登录的好方法。使用 AuthenticationManager.Signout 和 .Signin 方法并不能完全解决问题。
【问题讨论】:
-
如果您更改用户表中的安全标记,这将使 cookie / 令牌无效并导致下一页请求强制重新验证。见stackoverflow.com/questions/24570872/…
-
嗯...不确定降低 ValidateInterval 的权衡是否值得,看起来将其设置为零甚至不是一个选项,因为它会破坏其他功能(比如用户不能够注销)...现在我只是使用 RedirectToAction 将用户立即发送到登录屏幕。不是最优雅的,但它现在可以解决问题。
标签: asp.net asp.net-mvc asp.net-identity claims-based-identity