Reputation: 12470
I am rolling with a somewhat homebrew method of authenticating users. After authenticating the user, the authentication ticket is set like so in C#.
FormsAuthenticationTicket authenticationTicket = new FormsAuthenticationTicket(1, viewModel.Email, DateTime.Now, DateTime.Now.AddHours(48), true, String.Join("|", roles));
string encryptedTicket = FormsAuthentication.Encrypt(authenticationTicket);
HttpCookie authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
Response.Cookies.Add(authCookie);
With a small note that roles is a string list built out of the available roles to that user (The roles are not within the same user table - e.g. there is a set of conditions that define a user "role").
Next within the Application_BeginRequest method in Global.asax I have the following :
// Extract the forms authentication cookie
string cookieName = FormsAuthentication.FormsCookieName;
HttpCookie authCookie = Context.Request.Cookies[cookieName];
if (null == authCookie)
{
return;
}
FormsAuthenticationTicket authTicket = null;
try
{
authTicket = FormsAuthentication.Decrypt(authCookie.Value);
}
catch (Exception ex)
{
return;
}
if (null == authTicket)
{
return;
}
string[] roles = authTicket.UserData.Split(new char[] { '|' });
FormsIdentity id = new FormsIdentity(authTicket);
GenericPrincipal principal = new GenericPrincipal(id, roles);
HttpContext.Current.User = principal;
Basically setting the current context with the user from the authticket. However, I first ran into an issue as I was doing a custom Authorize attribute for an MVC class, and I noticed that the User of the HTTPContext was NOT set.
I then noticed that within each action, the User was not set either. I can clearly see however by stepping through my code, that the user IS being found within the authentication ticket and being decrypted OK and stored in the context variable. But by the time I get to an action within any controller, the User has vanished from the context.
EDIT : It should also be noted that other values set on the HTTPContext do carry over to the controller. e.g. this line
HttpContext.Current.AllowAsyncDuringSyncStages = false; // Or true
Will carry whatever I set it to into the controller action. It seems to only be the User that gets blanked.
Upvotes: 2
Views: 2142
Reputation: 2542
Application_BeginRequest is not a valid place to set HttpContext.Current.User, As it will be overwritten during Authorization.
You need to implement the above code in Application_AuthorizeRequest.For example refer to below code. Then it will be available in controller.
public MvcApplication()
{
this.AuthorizeRequest += MvcApplication_AuthorizeRequest;
}
void MvcApplication_AuthorizeRequest(object sender, EventArgs e)
{
FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket("test", true, 30);
FormsIdentity id = new FormsIdentity(authTicket);
GenericPrincipal principal = new GenericPrincipal(id, new string[] { });
HttpContext.Current.User = principal;
}
Upvotes: 1