Question

I am creating a basic authentication system with MVC 4 that uses custom logic. I have a UserModel class (which inherits from IPrincipal) that stores data I need to be persistent. To do this I am using the following code in my Controller:

if (ModelState.IsValid)
{
   if (userModel.IsValidUser())
   {
      FormsAuthentication.SetAuthCookie(userModel.Username, false);
      HttpContext.User = userModel;
      // User is now logged in; send them to Index method to load MyeMan data
      return RedirectToAction("Index", "Login");
   }
}

Then, in the Index action:

if (IsUserLoggedIn())
{
   UserModel userModel = (UserModel) HttpContext.User; // This line throws error
}

The error I get is:

Unable to cast object of type 'System.Web.Security.RolePrincipal' to type 'MyProj.UserModel'.

When I look in debug, the HttpContext.User accepts the UserModel without complaint. Only when it redirects to the different action does its datatype change.

Am I doing something wrong or is this the complete wrong way to go about storing UserModel persisently without Sessions? Sessions will expire independently of the AuthCookie; I was told HttpContext.User is the way to go.

Was it helpful?

Solution

Assigning the user will work, but this assignment will not persist between requests. You have to make sure to set up the user at the beginning of each request, perhaps in a custom AuthorizeAttribute or IHttpModule. For example, you might have logic like:

  • Retrieve the relevant cookie from the request
  • Verify that the cookie corresponds to a valid session (e. g. by querying a database containing this information)
  • Retrieve the session information based on the cookie and store it in the User property

Also, when you assign HttpContext.Current.User consider assigning Thread.CurrentPrincipal as well.

OTHER TIPS

Read Passing Data in an ASP.NET MVC Application

You can use TempData to pass the data between the action. It will be available for only subsequent requests

  TempData["User"] = userModel;
  // User is now logged in; send them to Index method to load MyeMan data
  return RedirectToAction("Index", "Login");

In Index

 UserModel user= (UserModel)TempData["User"];
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top