With .NET 2.0 you can use the built-in role management feature, which handles setting roles for you.
For .NET 1.1, or if some reason you can't or don't want to use the built-in role management, then the PostAuthenticateRequest event is a good place to do it.
Session is not used to store roles because (a) the lifetime of the session is completely independent of the lifetime of the forms authenticatio cookie and (b) session may not even be enabled.
The roles do need to be set on each request, but this isn't a problem. You don't need to retrieve them from the database (*) each time - you can cache them somewhere. Caching them in Session is a reasonable solution, but you do need to include code to reread from the database if you don't find them there.
(*) or wherever you have stored them.
EDIT
For example, to cache roles in Session you could do something like:
string[] GetRoles(string userName)
{
string[] roles = Session["Roles"] as string[];
if (roles == null)
{
roles = GetRolesFromDatabase(userName);
Session["Roles"] = roles;
}
return roles;
}
Alternatively you can avoid the dependency on Session by storing the roles in the ASP.NET cache, probably with a sliding expiration. The Cache is shared between all requests, so you'd need to use the username as part of the cache key:
string[] GetRoles(string userName)
{
string cacheKey = "Roles:" + userName;
string[] roles = Cache[cacheKey] as string[];
if (roles == null)
{
roles = GetRolesFromDatabase(userName);
Cache.Insert(cacheKey, roles, ...);
}
return roles;
}