Marco Dinatsoli
Marco Dinatsoli

Reputation: 10570

mvc4 add specific data to session

I have a login in form. When the user login in, he has to choose between two types and send user name and password.

I can do that, and I can connect to my model in order to authenticate the user. Then, if he entered the correct name and password, I do this:

FormsAuthentication.SetAuthCookie(login.UserName, login.RememberMe);

But I need a way in order to save his type. I think I have to do that in session, am i right? and if yes, how please? If not, what is the best way?

Upvotes: 0

Views: 1967

Answers (4)

Gary Woodfine
Gary Woodfine

Reputation: 387

What do you mean by "save his type" ? Do you mean his role? So essentially what role the user is in the application? IF it is role then maybe storing it in the Authcookie is the right place. You could add additional values onto the authentication cookie, or even roll your own Authorize Attribute that takes into consideration the additional values, which will then be available on the User Principal object ` public interface ICustomPrincipal : IPrincipal { Guid UserID { get; set; } string FirstName { get; set; } string LastName { get; set; } string EmailAddress { get; set; } Guid CompanyID { get; set; } }

public class CustomPrincipal : ICustomPrincipal
{
    public IIdentity Identity { get; private set; }
    public bool IsInRole(string role)
    {
        return false;
    }

    public CustomPrincipal()
    {

    }

    public CustomPrincipal(IIdentity indentity)
    {
        this.Identity = new GenericIdentity(indentity.Name);
    }
    public CustomPrincipal(string email)
    {
        this.Identity = new GenericIdentity(email);
    }
   public Guid UserID { get; set; }
   public string FirstName { get; set; }
   public string LastName { get; set; }
   public string EmailAddress { get; set; }
   public Guid CompanyID { get; set; }
   public string CompanyName { get; set; }
   public string JobTitle { get; set; }


}`.


 public sealed class CustomAuthoriseAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        bool isAuthorized = base.AuthorizeCore(httpContext);
        if (!isAuthorized) return false;

        CustomPrincipal customPrincipal = null;
        HttpCookie authCookie = httpContext.Request.Cookies[FormsAuthentication.FormsCookieName];

        if (authCookie != null)
        {
            FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
            var serializer = new JavaScriptSerializer();

            if (authTicket != null)
            {
                var serializeModel = serializer.Deserialize<CustomPrincipalSerializeModel>(authTicket.UserData);

                customPrincipal = new CustomPrincipal(authTicket.Name)
                {
                    UserID = serializeModel.UserID,
                    FirstName = serializeModel.FirstName,
                    LastName = serializeModel.LastName,
                    CompanyID = serializeModel.CompanyID,
                    EmailAddress = serializeModel.EmailAddress,
                    CompanyName = serializeModel.CompanyName,
                    JobTitle = serializeModel.JobTitle,

                };
            }
        }


                 HttpContext.Current.User = customPrincipal;

        return isAuthorized;
    }
}

public  class CustomPrincipalSerializeModel
{
  public Guid UserID { get; set; }
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public string EmailAddress { get; set; }
  public Guid CompanyID { get; set; }
  public string CompanyName { get; set; }
  public string JobTitle { get; set; }

}

Then you Login Method could look something like this

 if (!membershipService.IsAccountLockedOut(loginModel.Email) &&
            membershipService.Login(loginModel.Email, loginModel.Password))
        {
            UserDto user = membershipService.GetUserDetail(loginModel.Email);
            var cookieContext = new CookieContext();
            cookieContext.SetAuthenticationToken(user);
            //Need to check if user has reset thier password and needs to change it
            if (!user.PasswordReset)
            {
                return RedirectToLocal(returnUrl);
            }
            else
            {
                return RedirectToAction("ChangePassword", "Account");
            }
        }

The Set Authentication Method looks something like this

public void SetAuthenticationToken(UserDto userDto)
    {
        string userData;
        string encTicket;

        var serializeModel = new CustomPrincipalSerializeModel();
        serializeModel.UserID = userDto.ID;
        serializeModel.FirstName = userDto.FirstName;
        serializeModel.LastName = userDto.LastName;
        serializeModel.EmailAddress = userDto.Email;
        serializeModel.CompanyID = userDto.CompanyID;
        serializeModel.CompanyName = userDto.Company;
        serializeModel.JobTitle = userDto.JobTitle;

        var serializer = new JavaScriptSerializer();
        userData = serializer.Serialize(serializeModel);

        var autTicket = new FormsAuthenticationTicket(1, userDto.Email, DateTime.Now,
                                                      DateTime.Now.AddMinutes(15), false, userData);
        encTicket = FormsAuthentication.Encrypt(autTicket);
        var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
        cookie.HttpOnly = true;
        HttpContext.Current.Response.Cookies.Add(cookie);
    }

All your data you need to travel with your user throughout the application is available on the Authentication Cookie, and is available on the User object whenever you use your CustomAuthorise attribute

 [CustomAuthorise]
    [OutputCache(NoStore = true, VaryByParam = "*", Duration = 0)]
    public ActionResult Index()
    {

        var model = _someService.SomeFunction(User.CompanyID);  //Company ID is from Auth Cookie
        return View(model);
    }

Upvotes: 0

Scottie
Scottie

Reputation: 11308

It depends. Do you need the "type" saved after the user closes down his browser? Because if you save it in the session, the next time he opens it, it will be gone.

If you do need it saved, it would be best to use a cookie instead.

To add a cookie, you would do something like this:

this.Response.Cookies.Add(new HttpCookie("my-cookie-name", myValueToSave));

Upvotes: 1

Patrick Desjardins
Patrick Desjardins

Reputation: 140803

If you want to use a session you can use the Session.

You can store anything into it. So you can store the whole login object if you desire.

Session["user"] = yourUser;

Session is a good place since it will be unique for each user.

If you are using the MemberShip classes in your web application, you can add custom field which I think is the best solution for your problem. See this example or this blog post. Not only this will have your information saved into the session of the user but it will also add this user type inside the database.

Upvotes: 1

Peter Porfy
Peter Porfy

Reputation: 9030

You can simply use the Session object within your controller:

Session["usertype"] = yourType;

However I would use a custom class for this kind of information storing and you should also redesign this solution if you have a lots of users (reconsider session storing location or online user data location at all).

Upvotes: 1

Related Questions