我目前正在尝试将用户的电子邮件/用户名从移动应用更新为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没有太多关于此的文档。任何帮助是极大的赞赏。
答案 0 :(得分: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();
}