Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the overhead on PostAuthenticateRequest?

I am implementing a custom ticket system using the Application_PostAuthenticateRequest method in my global.asax file (ASP.NET MVC). I'm wondering what the overhead for this kind of thing is - since it will deserialize some information on every request. It generates a cookie of around 1.8 kb, which is a ton - but is that a better alternative than frequent database trips?

Information being deserialized

  • User Id (int)
  • Roles (string[])
  • Email (string)
  • Associated Ids (int[]) // (hard to describe what these are, but each user will have around 3 of them)

It seemed smarter to implement a custom FormsAuthenticationTicket system than to continuously do round-trips to the database based on User.Identity.Name. But I'm just worried that this constant deserialization is very inhibitive. But it looks something like this...

    protected void Application_PostAuthenticateRequest(object sender, EventArgs e)
    {
        HttpCookie authCookie = HttpContext.Current.Request.Cookies[FormsAuthentication.FormsCookieName];

        if (authCookie != null)
        {
            string encTicket = authCookie.Value;

            if (!String.IsNullOrEmpty(encTicket))
            {
                // decrypt the ticket if possible.
                FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(encTicket);

                var userData = Deserializer.Deserialize(ticket);
                UserPrincipal principal = new UserPrincipal(userData);

                HttpContext.Current.User = principal;
            }
        }
    }

Here is the class being serialized as UserData in the FormsAuthenticationTicket.

[Serializable]
public class MembershipData
{
    public string Email
    {
        get;
        set;
    }

    public int Id
    {
        get;
        set;
    }

    public string[] Roles
    {
        get;
        set;
    }

    public int[] Ancillary
    {
        get;
        set;
    }
}
like image 996
Ciel Avatar asked Feb 09 '11 18:02

Ciel


2 Answers

I know this question is a bit old at this point and already has an accepted answer, but I'd like to throw in my thoughts and how we currently do things with a similar setup.

Originally, we were going through the same process you were and included a fair bit of user data in the cookie. This process did cut down on our database trips, but eventually we hit a bug wherein some users couldn't log in at all while others could. Turns out that the cookie was silently being dropped when it went over a certain size due to our serialized data.

Our current process is a two-tiered caching system instead. We store the user's database ID in the cookie as the User.Identity.Name and then on PostAuthenticateRequest, we try to retrieve the user info from a local ASP.net cache, falling back to a distributed Redis cache. The local cache is in-proc and stored for 15 seconds (so repeated requests don't require going across the wire to Redis). Redis cache is stored for a day, and invalidated on update. If both of those are misses, we then load the information from SQL Server.

We then drop that user information into a custom IPrincipal and everything works like a charm. This seems to work pretty well for us in a reasonably high-usage website.

like image 109
MattGWagner Avatar answered Oct 22 '22 02:10

MattGWagner


I would recommend you measuring the performance but I would expect that the cookie approach will be faster than doing roundtrips to the database. You could also simplify the serialization and make it as fast as possible by using a comma delimited or some special character delimited string. Here is how I would rank different operations in terms of performance:

  1. in-process communication
  2. inter-process communication
  3. inter-network communication
like image 44
Darin Dimitrov Avatar answered Oct 22 '22 03:10

Darin Dimitrov