Обновить идентификационные требования пользователей в веб-интерфейсе

В настоящее время я пытаюсь обновить имя пользователя/пользователя пользователя из мобильного приложения в проект веб-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

Основная проблема заключается в том, что требование, представляющее имя пользователя, не обновляется в ClaimsIdentity вы используете на последнем этапе.

Самый простой способ выполнить обновление - использовать SignInManager<TUser, TKey>.SignIn метод

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

Это также идиоматический способ ASP.NET Identity, поскольку он использует связанный 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 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 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();
}