Simple Fellow
Simple Fellow

Reputation: 4622

FromsAuthenticationTicket.UserData is always empty and authentication cookie does not retain value

I have the following code in the Login(username, password)

if (hasher.Compare(password, person.Hash))
                {
                    FormsAuthentication.SetAuthCookie(userId, true);
                    OpenAccount(person);

                    var principle = new GenericPrincipal( new GenericIdentity($"{person.FirstName} {person.LastName}"), new string[] {"All"});
                    var data = Konstants.Serialize(principle);
                    var ticket = new FormsAuthenticationTicket(1, principle.Identity.Name, DateTime.Now, DateTime.Now.AddMinutes(30), true, data);
                    var encryptedTicket = FormsAuthentication.Encrypt(ticket);


                    FormsAuthentication.SetAuthCookie(principle.Identity.Name, false);
                    var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
                    Response.SetCookie(cookie);
                    Response.RedirectToRoute("Default");
                }

Then in the Global.asax I have the following code:

protected void Application_AuthenticateRequest(Object sender, EventArgs e)
{
    var  authCookie = Request.Cookies[FormsAuthentication.FormsCookieName];
    try
    {
        if (authCookie != null)
        {
            FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(authCookie.Value);
            if (!string.IsNullOrEmpty(ticket.UserData))
            {
                var principle = Konstants.Deserialize<GenericPrincipal>(ticket.UserData);
                HttpContext.Current.User = principle;
            }
        }
    }
    catch 
    {


    }
}

But in the AutheticateRequest the ticket.UserData is always empty. In fact the cookie value I get is the one that was before authentication not the one that I stored. What am I doing wrong here.

Update: The Serialize and Deserialize code is as follows:

   public static string Serialize<T>(T obj)
    {
        var ret = string.Empty;
        using(var ms = new MemoryStream())
        {
            var bf = new BinaryFormatter();
            bf.Serialize(ms, obj);
            ret= Convert.ToBase64String(ms.GetBuffer());
        }
        return ret;
    }

public static T Deserialize<T>(string text)
{
    var obj = default(T);
    var data = Convert.FromBase64String(text);
    using(var ms = new MemoryStream(data, false))
    {
        var bf = new BinaryFormatter();
        obj = (T)bf.Deserialize(ms);
    }
    return obj;
}

Upvotes: 2

Views: 957

Answers (1)

tattarrattat
tattarrattat

Reputation: 371

You've got two calls to SetAuthCookie in that first code block, but you don't need either if you're creating a custom ticket. I think this should do the trick:

OpenAccount(person);

var principle = new GenericPrincipal( new GenericIdentity($"{person.FirstName} {person.LastName}"), new string[] {"All"});
var data = Konstants.Serialize(principle);
var ticket = new FormsAuthenticationTicket(1, principle.Identity.Name, DateTime.Now, DateTime.Now.AddMinutes(30), true, data);
var encryptedTicket = FormsAuthentication.Encrypt(ticket);

var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
Response.SetCookie(cookie);
Response.RedirectToRoute("Default");

Edit: I also just noticed that you're not passing your serialized data into the userData field of the new ticket, is that the intention?

Upvotes: 3

Related Questions