Where to create custom IPrincipal object

asp.netforms-authentication

I am using Application_PostAuthenticateRequest event in global.asax to create custom IPrincipal object

void Application_PostAuthenticateRequest(object sender, EventArgs args)
{
    if (Context.User.Identity.IsAuthenticated == true)
        if (Context.User.Identity.AuthenticationType == "Forms")
        {                 
              Context.User = new CustomPrincipal(Context.User);
              Thread.CurrentPrincipal = Context.User;
        }                
}

to use in my application where I want get some more information about logged user. I thought it would be called one time when user authenticates but I noticed that it is called on every page request couple times for the same logged user. I found that even requesting image from AppThemes calls this method!

Where should I create that object instead to avoid calling this method multiple times for each user?

Best Solution

I found an answer to my question.

In loggin_in event I should save authentication cookie (I can store all information that I later need in my customPrincipal in UserData property) and in Application_PostAuthenticateRequest I should create CustomPrincipal from that cookie. That way this event fires every request but I don't hit database - I read data from cookie.

I followed http://www.ondotnet.com/pub/a/dotnet/2004/02/02/effectiveformsauth.html

In my case code is:

void Application_PostAuthenticateRequest(object sender, EventArgs args)
    {
        HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
        if (authCookie == null)
            return;
        FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
        string[] customData = authTicket.UserData.Split(new Char[] { '|' });

        if (Context.User.Identity.IsAuthenticated == true)
        {
            if (Context.User.Identity.AuthenticationType == "Forms")
            {
                Context.User = new CustomPrincipal(customData, Context.User);
                Thread.CurrentPrincipal = Context.User;
            }
        }
}
Related Question