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

时间:2014-02-22 21:02:27

标签: asp.net-mvc asp.net-identity

我正在使用带有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”的值,所以当我再次签名时,我会有相同的值?

谢谢,

米格尔

3 个答案:

答案 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);