Skip to content

Think twice about using RoleProvider

May 23, 2012

It’s a common misunderstanding that the RoleProvider in ASP.NET is the only means for populating a user’s roles in ASP.NET. The RoleProvider was introduced in ASP.NET 2.0, so prior to 2005 we did without.

In essence what’s needed to populate roles in ASP.NET is to have some code in the HTTP pipeline handle the PostAuthenticateRequest event and then load the roles for a user and populate the HttpContext.User and Thread.CurrentPrincipal properties in global.asax, as such:

void Application_PostAuthenticateRequest(object sender, EventArgs e)
{
    var ctx = HttpContext.Current;
    if (ctx.Request.IsAuthenticated)
    {
        string[] roles = LookupRolesForUser(ctx.User.Identity.Name);
        var newUser = new GenericPrincipal(ctx.User.Identity, roles);
        ctx.User = Thread.CurrentPrincipal = newUser;
    }
}

That wasn’t so bad.

So often people get pigeonholed into thinking they must use a RoleProvider because it’s some magical part of the infrastructure. In fact the RoleProvider is simply abstracting a database lookup. It has other APIs to manage roles (create roles, add/remove users to/from roles, etc.), but if all you need in your application is to load roles for the current user the RoleProvider might be too heavy weight for your needs.

17 Comments leave one →
  1. August 29, 2012 1:09 pm

    Thanks man, it helped me a lot!

  2. August 30, 2012 5:46 pm

    So, from the global.asax, how do you call a method? (LookupRolesForUser)

    • August 30, 2012 5:57 pm

      “LookupRolesForUser” is just some method you’d implement to accept the username and return an array of strings for the roles. Presumably it’s check whatever custom database you’ve developed to store the roles.

  3. August 31, 2012 8:45 am

    What I mean is where do I put the code? there is no .vb file for the global.asax – I see no ‘view code’ in the context menu

  4. August 31, 2012 8:46 am

    doah! – never mind

  5. August 31, 2012 10:10 am

    Works great – – wish I’d known this years ago

  6. November 27, 2012 6:43 am

    this is cool.

  7. arnaud permalink
    December 19, 2012 10:42 am

    why do you not use one personel provider ? (herits providerrole ?)

  8. leo permalink
    January 9, 2013 1:45 pm

    how can I access the roles I set up afterwards? When using Roles.GetRolesForUser() I keep getting an error with the RoleProviders on the roleManager (gotta have it set to “True” right?) on the webconfig. I’m going crazy over this

  9. iqadbak permalink
    June 17, 2013 2:39 pm

    Isn’t enough to set ctx.User? Why you setting Thread.CurrentPrincipal as well?

    • June 17, 2013 3:16 pm

      You also have to set the thread’s principal because that’s where the rest of .NET looks for the user’s identity.

  10. matin sayed permalink
    June 24, 2013 6:06 am

    Worked For me !
    Thanks :)

  11. November 5, 2013 3:04 pm

    would this not be called on every request… ?

    • November 5, 2013 4:51 pm

      Yep, but this is the way it’s always been (as the same for the role manager/provider). So it’s a good idea to cache those roles somewhere.

  12. James permalink
    December 13, 2013 5:20 pm

    Thanks for the tip. Saved me a lot of grief in implementing an entire RoleProvider.

  13. Muhammed permalink
    September 26, 2014 3:47 pm

    See how i modified your wonderful method.. thanks a lot..

    void Application_PostAuthenticateRequest()
    {
    HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
    FormsAuthenticationTicket authTicket;
    if (authCookie == null || authCookie.Value == “”)
    {
    string[] roles = GetRolesStringArrayForUser(User.Identity.Name);
    authTicket = new FormsAuthenticationTicket(
    1, // version
    User.Identity.Name, // user name
    DateTime.Now, // created
    DateTime.Now.AddMinutes(20), // expires
    true, // persistent?
    roles // can be used to store roles
    );

    string encryptedTicket = FormsAuthentication.Encrypt(authTicket);

    authCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket);
    HttpContext.Current.Response.Cookies.Add(authCookie);
    }
    try
    {
    authTicket = FormsAuthentication.Decrypt(authCookie.Value);
    }
    catch
    {
    return;
    }
    string[] roles = authTicket.UserData.Split(‘;’);
    if (Context.User != null)
    Context.User = new System.Security.Principal.GenericPrincipal(Context.User.Identity, roles);

    }

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: