我正在使用带有Owin和声明身份验证的ASP.NET MVC 5.1。
用户更改其电子邮件后,我需要更新用户声明,因此我尝试使用控制器:
ClaimsIdentity identity = (ClaimsIdentity)User.Identity;
Claim claim = identity.FindFirst(ClaimTypes.Email);
identity.RemoveClaim(claim);
identity.AddClaim(new Claim(ClaimTypes.Email, newEmail));
IOwinContext context = new OwinContext();
context.Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
context.Authentication.SignIn(identity);
声明已更改,但当我刷新页面时,电子邮件声明又是原始声明......
似乎cookie没有更新。知道我做错了吗?
是否有可能从身份中获取“IsPersistent”的值,所以当我再次签名时,我会有相同的值?
谢谢,
米格尔
答案 0 :(得分:23)
我遇到了同样的问题,所以我想在这里总结一下我的发现。正如克里斯所说,答案的基础确实在这里:How to change authentication cookies after changing UserName of current user with asp.net identity但我发现这个话题有点难以理解,而且这个问题并不是真正的直接重复。
首先,从当前的OWIN上下文中获取AuthenticationManager。完成后,您可以通过调用SignIn
方法获取“isPersistent”(以及原始AuthenticateAsync
调用中的其他属性)的值。然后,要更新当前用户身份的声明,您只需要替换AuthenticationResponseGrant
属性的值,如下所示:
var identity = (ClaimsIdentity)User.Identity;
// Call AddClaim, AddClaims or RemoveClaim on the user identity.
IOwinContext context = Request.GetOwinContext();
var authenticationContext =
await context.Authentication.AuthenticateAsync(DefaultAuthenticationTypes.ExternalCookie);
if (authenticationContext != null)
{
authenticationManager.AuthenticationResponseGrant = new AuthenticationResponseGrant(
identity,
authenticationContext.Properties);
}
实际更新cookie的AuthenticationResponseGrant
属性的最终设置。
希望这有助于其他读者。
答案 1 :(得分:6)
SORRY,这是一个ASP.NET核心解决方案 我也对索赔提出质疑,但答案很容易找到。
要刷新cookie,您可以依赖SignInManager的RefreshSignInAsync()函数;
private readonly UserManager<ApplicationUser> _userManager;
private readonly ApplicationDbContext _context;
private readonly SignInManager<ApplicationUser> _signInManager;
public ApiClubController(UserManager<ApplicationUser> userManager, SignInManager<ApplicationUser> signInManager, ApplicationDbContext context)
{
_userManager = userManager;
_context = context;
_signInManager = signInManager;
}
在你的功能中:
//GET CURRENT USER
var usr = await GetCurrentUserAsync();
//OLD CLAIM
var myClaims = await _userManager.GetClaimsAsync(usr);
var oldClaim = myClaims.Where(o => o.Type.Equals("Club")).FirstOrDefault();
if (oldClaim != null)
{
await _userManager.RemoveClaimAsync(usr, oldClaim);
}
//CREATE CLUB CLAIM
var clubClaim = new Claim("Club", "" + id);
await _userManager.AddClaimAsync(usr, clubClaim);
//RESET USER COOKIE
await _signInManager.RefreshSignInAsync(usr);
//RETURN
return Ok(company);;
注意:强> 我在这里使用了一个API,因为我很多时会混淆角度。 如果您使用API更新自己的身份,则需要刷新页面,以便根据您的声明查看内容
答案 2 :(得分:4)
这对我有用。不确定它是否是最好的方法,但更新的声明是在数据库和后续控制器中。
var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
var c = identity.Claims.FirstOrDefault(r => r.Type == "tId");
await UserManager.RemoveClaimAsync(user.Id, c);
await UserManager.AddClaimAsync(user.Id, new Claim("tId", "9032C945-DC5C-4FC9-BE7C-8EDC83A72E58"));
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
AuthenticationManager.SignIn(new AuthenticationProperties { IsPersistent = isPersistent }, identity);