首页 文章

在Web API中更新标识用户声明

提问于
浏览
14

我目前正在尝试将用户的电子邮件/用户名从移动应用程序更新为Web API项目 . 我目前正在使用oauth和令牌身份验证 . 更新身份用户时,用户将变为未经身份验证,因为用户名和访问令牌不再有效 . 根据我的阅读,我必须更新身份声明 . 这是我到目前为止所尝试的:

var identity = new ClaimsIdentity(User.Identity);

if (result)
{
    var identityUser =  await UserManager.FindByNameAsync(User.Identity.Name);

    identityUser.Email = AntiXssEncoder.HtmlEncode(value.Email, true);
    identityUser.UserName = AntiXssEncoder.HtmlEncode(value.Email, true);

    var identityResult = await UserManager.UpdateAsync(identityUser);

    if(identityResult.Succeeded)
    {
        var authenticationManager = HttpContext.Current.GetOwinContext().Authentication;

        await UserManager.RemoveClaimAsync(identityUser.Id, identity.FindFirst(ClaimTypes.Name));
        await UserManager.AddClaimAsync(identityUser.Id, new Claim(ClaimTypes.Name, value.Email));

        identity.RemoveClaim(identity.FindFirst(ClaimTypes.Name));
        identity.AddClaim(new Claim(ClaimTypes.Name, value.Email));

        authenticationManager.AuthenticationResponseGrant =
                    new AuthenticationResponseGrant(
                    new ClaimsPrincipal(identity),
                    new AuthenticationProperties { IsPersistent = false });
     }
  return Ok();
}

但是,它在使用 User.Identity.Name 时仍显示上一封电子邮件,并且 authenticationManager 内的用户声明也未更新 . 我为Web API提供了很多关于此的文档 . 任何帮助是极大的赞赏 .

1 回答

  • 0

    主要问题是代表用户名称的声明未在最后一步中使用的 ClaimsIdentity 中更新 .

    执行更新的最简单方法是使用SignInManager<TUser, TKey>.SignIn方法

    signInManager.SignIn(identityUser, isPersistent: false, rememberBrowser: false);
    

    这也是一种ASP.NET身份惯用方式,因为它使用关联的 IClaimsIdentityFactory 来创建新身份的声明 .


    完整的例子

    static async Task<IdentityResult> UpdateEmailAsync<TUser>(
        IPrincipal principal,
        UserManager<TUser, string> userManager,
        SignInManager<TUser, string> signInManager,
        string newEmail
    )
        where TUser : class, IUser<string>
    {
        string userId = principal.Identity.GetUserId();
        IdentityResult result = await userManager.SetEmailAsync(userId, newEmail);
        if (result.Succeeded)
        {
            // automatically confirm user's email
            string confirmationToken = await userManager.GenerateEmailConfirmationTokenAsync(userId);
            result = await userManager.ConfirmEmailAsync(userId, confirmationToken);
            if (result.Succeeded)
            {
                TUser user = await userManager.FindByIdAsync(userId);
                if (user != null)
                {
                    // update username
                    user.UserName = newEmail;
                    await userManager.UpdateAsync(user);
    
                    // creates new identity with updated user's name
                    await signInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);
                }
    
                // succeded
                return result;
            }
        }
    
        // failed
        return result;
    }
    

    然后你可以从你的代码中调用它

    string newEmail = AntiXssEncoder.HtmlEncode(value.Email, true);
    IdentityResult result = await UpdateEmailAsync(identityUser, UserManager, SignInManager, newEmail);
    if (result.Succeeded)
    {
        return Ok();
    }
    

相关问题