Reputation: 7547
I have stored authentication info inside the User.Identity.Name
once the user log in to the system. using this method
FormsAuthentication.SetAuthCookie(Id + " | " + Name + " | " + Language + " | " + Culture + " | " + Email + " | " + Role+ " | " + TimeOffset+ " | " + Rights, RememberMe);
Now I want to change the some value inside User.Identity.Name
when user change some configutation setting, eg Language
But after calling the FormsAuthentication.SetAuthCookie()
, the value inside the User.Identity.Name
does not change anymore
string identity = HttpContext.Current.User.Identity.Name; // modify current value
FormsAuthentication.SetAuthCookie(identity, false); // assign new value
How can I change this value?
Upvotes: 1
Views: 539
Reputation: 42497
SetAuthCookie
updates the cookie containing the FormsAuth ticket with the updated value, but it does not set the User
of the current context. You can change the user of the current context by creating a new IPrincipal
and IIdentity
. It's as simple as getting the current HttpContext
and setting the User
property.
You'd normally do this in an IHttpModule
or Global.asax.cs in the PostAuthenticateRequest
event, because at this point FormsAuth will already have authenticated the user's ticket and set the identity. After this event, the new IPrincipal
you created will be available to the application for the remainder of the request.
protected void Application_PostAuthenticateRequest(object sender, EventArgs args)
{
var application = (HttpApplication)sender;
var context = application.Context;
if (context.User != null || !context.User.Identity.IsAuthenticated) return; // user not authenticated, so you don't need to do anything else
// Here, you'd process the existing context.User.Identity.Name and split out the values you need. that part is up to you. in my example here, I'll just show you creating a new principal
var oldUserName = context.User.Identity.Name;
context.User = new GenericPrincipal(new GenericIdentity(oldUserName, "Forms"), new string[0]);
}
As an aside, I don't recommend packing values in the identity name, but rather the ticket's UserData
property. In that case, you can check if the context.User.Identity
is FormsIdentity
and access Ticket.UserData
:
protected void Application_PostAuthenticateRequest(object sender, EventArgs args)
{
var application = (HttpApplication)sender;
var context = application.Context;
if (context.User != null || !context.User.Identity.IsAuthenticated) return; // user not authenticated, so you don't need to do anything else
var formsIdentity = context.User.Identity as FormsIdentity;
if (formsIdentity == null) return; // not a forms identity, so we can't do any further processing
var ticket = formsIdentity.Ticket;
// now you can access ticket.UserData
// to add your own values to UserData, you'll have to create the ticket manually when you first log the user in
var values = ticket.UserData.Split('|');
// etc.
// I'll pretend the second element values is a comma-delimited list of roles for the user, just to illustrate my point
var roles = values[1].Split(',');
context.User = new GenericPrincipal(new GenericIdentity(ticket.Name, "Forms"), roles);
}
Here is some more info on creating FormsAuth tickets with custom values in UserData.
Upvotes: 1