I needed a way to change the authentication's username in a website. This basically applies the change, and then signs the user out, change session info and cookie info, and then back in -- so that username change is displayed right away.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> ChangeUserName(ManageUsernameViewModel model)
{
bool hasPassword = HasPassword();
if (hasPassword)
{
if (ModelState.IsValid)
{
//Get UserID
var userID = User.Identity.GetUserId();
var currentUserName = User.Identity.GetUserName();
var newUserName = model.NewUserName;
//Check if new username already exisits
if (UserManager.FindByName(model.NewUserName) != null)
{
ModelState.AddModelError(string.Empty, "That username already exist.");
return RedirectToAction("Manage", new { Message = ManageMessageId.DuplicateUserName });
}
var user = UserManager.Find(model.OldUserName, model.Password);
if (user != null)
{
//Change username
if (DataAccess.userDataAccess.updateUserName(model.NewUserName, userID))
{
AuthenticationManager.SignOut();
await SignInAsync(user, false);
var identity = new ClaimsIdentity(User.Identity);
identity.RemoveClaim(identity.FindFirst(identity.NameClaimType));
identity.AddClaim(new Claim(identity.NameClaimType, model.NewUserName));
AuthenticationManager.AuthenticationResponseGrant = new AuthenticationResponseGrant(new ClaimsPrincipal(identity), new AuthenticationProperties { IsPersistent = false });
return RedirectToAction("Manage", new { message = ManageMessageId.ChangeUserNameSuccess });
}
else
{
AddErrors(new IdentityResult("Failed updating your username."));
}
}
else
{
ModelState.AddModelError("", "Invalid username and password.");
}
}
}
// If we got this far, something failed, redisplay form
return View();
}