views:

119

answers:

1

I have an custom role provider that gets the roles a user belongs to from a database. I also have a custom authentication module registered in my web.config's httpModules which sniffs incoming HTTP requests and (if it's an OAuth signed request) sets the HttpContext.Current.User property to impersonate the user, and the IPrincipal that it sets includes all the user's roles, plus an extra one called "delegated".

The trouble is, after I set my custom IPrincipal, apparently ASP.NET still calls my custom role provider, and then resets the IPrincipal with one that has only the standard roles for that user.

If I set <roleManager enabled="false" ...> in my web.config file, the authentication module's assigned roles stick. Obviously though, I want the best of both worlds. How can I use the role provider, but "cancel" the role provider's effect when my authentication module decides to?

A: 

It turns out that in the authentication http module's Init method, I can find the RoleManager, and then hook an event that gives me veto power on whether it does its overriding work:

 public void Init(HttpApplication context) {
  var roleManager = (RoleManagerModule)context.Modules["RoleManager"];
  roleManager.GetRoles += this.roleManager_GetRoles;
 }

 private void roleManager_GetRoles(object sender, RoleManagerEventArgs e) {
  if (this.application.User is OAuthPrincipal) {
   e.RolesPopulated = true; // allows roles set in AuthenticationRequest to stick.
  }
 }

 private void context_AuthenticateRequest(object sender, EventArgs e) {
  if (/*oauth request*/) {
   HttpContext.Current.User = CreateOAuthPrincipal();
  }
 }
Andrew Arnott