1

We are using ASP.NET Identity 2.0, and want to allow username change. When it is changed, the following happens:

  1. user is signed out => no error
  2. username is changed in database => works, the change is visible
  3. user is signed in with new username => works but still shows old username

The problem is step 3, after signin the user is still returned with the old username, even though in the db it's the new one, and login with the new one worked.

I tried the following to clear existing references:

Context.GetOwinContext().Authentication.SignOut(); // also tried it with DefaultAuthenticationTypes.ExternalCookie
Session.Clear();
Session.Abandon();

// sign in with the new username => no problem
IdentityHelper.SignIn(manager, user, false);

// added this later, when the rest didn't work, but didn't help either
Context.User = new System.Security.Principal.GenericPrincipal(new System.Security.Principal.GenericIdentity(user.UserName), roles);

// tried this too, but didn't help either
System.Web.Security.FormsAuthentication.SetAuthCookie(user.UserName, true);

// after executing the following statement, user always has the old username
var user = Context.User.Identity.GetUserName();

All statements execute without error. Any ideas what else needs doing?

EDIT

Also tried clearing the cache via loop

foreach (System.Collections.DictionaryEntry entry in HttpContext.Current.Cache)
    HttpContext.Current.Cache.Remove(entry.Key as string);

and also Context.Application.Clear();

Also tried wiping the user, i.e 'Context.User = null' but this resulted in an exception on signIn. When I execute 'user = manager.Find("newUserName", password)' to sign in with, it returns the user but even though it was retrieved with the new username, it still actually contains the old username. Not sure what else I should clear.

devlock
  • 959
  • 1
  • 9
  • 14
  • 5
    You are essentially getting the details from the HTTPContext... refreshing the page once you have 'wiped' the session / user details should do it. – Paul Zahra Nov 10 '14 at 10:06
  • Have you taken care of the cache? – Tushar Gupta Nov 10 '14 at 10:29
  • thanks for both your suggestions but neither helped; I had tried redirecting after signIn with the new userName but it didn't make a difference; regarding the cache, please see my edit above – devlock Nov 10 '14 at 13:02
  • I think the issue is with the Entity Framework and not session per say. Have a look at this: http://stackoverflow.com/questions/22839881/asp-net-identity-2-0-update-user – NP3 Nov 10 '14 at 13:07
  • Have you tried setting the page to not cache? I've seen this with some browsers and need to set both server-side and client-side caching off in order to get it to reliably work. It doesn't throw any errors, but the HTML doesn't update, and when it happens it drives me nuts. See my answer to this other question: http://stackoverflow.com/questions/26807706/odd-session-behavior-in-asp-net/26807768#26807768 – Tim Nov 10 '14 at 13:09
  • @NP3: I don't think it's the same thing - we can see in the db that the update has taken place (and also you can get the user with the new credentials without error) – devlock Nov 10 '14 at 13:21
  • Seems like your old cookie is still available. Tye this - var myCookie = new HttpCookie("YOUR COOKIE NAME") {Expires = DateTime.Now.AddDays(-1)}; Response.Cookies.Add(myCookie); – DSR Nov 10 '14 at 14:10
  • @DSR: a good suggestion, and by sheer coincidence I'd meanwhile done something like it based on this post http://stackoverflow.com/questions/412300/formsauthentication-signout-does-not-log-the-user-out; unfortunately, no joy – devlock Nov 10 '14 at 15:13
  • I had the same problem and the only way to get over it was to create a temporary cookie and reply with unauthorized error when it comes again check the cookie and redirect to other page. – Pedro.The.Kid Nov 10 '14 at 16:04
  • @Tim: sorry, didn't work in this case – devlock Nov 10 '14 at 16:21

2 Answers2

1

Also posting this answer because I was tearing my hair out :)

I tried everything even the redirect as listed above. However I came across this article http://benfoster.io/blog/aspnet-identity-stripped-bare-mvc-part-2 and noticed that he was using the signout except he was specifying the type so

_applicationSignInManager.AuthenticationManager.SignOut("ApplicationCookie") 

instead of leaving it blank, I tried it at it worked! without the redirect.

So my code looks like this-

_applicationSignInManager.AuthenticationManager.SignOut("ApplicationCookie");
FormsAuthentication.SignOut(); // doing for good measure (might not need)

// Sign back in (Does the password sign in etc)
var resultSignIn = helper.PasswordSignIn(userName: userName, password: password, isPersistent: false, shouldLockout: true);

// Update the HttpContext with the new user
HttpContext.Current.User = new GenericPrincipal(new GenericIdentity(userName), new string[] { });
shill
  • 11
  • 1
0

Posting this as an answer in case someone else pulls their hair out over this. Turns out a redirect does solve the problem, but it needs to be done in between signOut and signIn.

If the redirect happens after signIn, as I had tried before, the old value is retained. So somehow something seems to be cleared during redirect that I wasn't able to remove manually but which needs clearing before signing in again.

devlock
  • 959
  • 1
  • 9
  • 14