首页 文章

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

提问于
浏览
16

我正在使用ASP.NET MVC 5.1与Owin和声明身份验证 .

用户更改其电子邮件后,我需要更新用户声明,所以我尝试在控制器中:

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 回答

  • 23

    我有同样的问题,所以我想在这里总结一下我的发现 . 正如克里斯所说,答案的基础确实在这里:How to change authentication cookies after changing UserName of current user with asp.net identity但我发现这个线程有点难以理解,而这个问题实际上并不是直接的重复 .

    首先,从当前的OWIN上下文中获取AuthenticationManager . 一旦你有了,你可以通过调用 AuthenticateAsync 方法获得"isPersistent"(以及原始 SignIn 调用中的其他属性)的值 . 然后要更新当前用户身份的声明,您只需要替换 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 属性的最终设置 .

    希望这有助于其他读者 .

  • 4

    SORRY, this is an ASP.NET CORE solution 我也质疑索赔的问题,但答案很容易找到 .

    要刷新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);;
    

    NOTE: 我'm using an API here, because I' m混合很多角度 . 如果您使用API更新自己的身份,则需要刷新页面,以便根据您的声明查看内容

  • 6

    这适合我 . 不确定它是否是最好的方法,但更新的声明是在数据库和后续控制器中 .

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

相关问题