How can I get a users role inside a WebAPI method without a lookup to the AspNetUserRoles table? How can I get a users role inside a WebAPI method without a lookup to the AspNetUserRoles table? asp.net asp.net

How can I get a users role inside a WebAPI method without a lookup to the AspNetUserRoles table?


As you stated you are using bearer tokens to protect your end points. I believe that there is little misunderstanding with what those bearer tokens magical string contains inside it.Well those tokens contains all the roles for the user you issued the token for, as well if you are using the default data protection DPAPI in Web API not (JWT Tokens) then those tokens are signed and encrypted so no one can tamper with the data inside the token unless he has the mashineKey for the web server issued this token, so do not worry about data protection.

My recommendation is to read the roles/claims for the user from the database, there is no need for this workarounds and hacks you are trying to do, all you need to do is to set the claims for the users when they login in method GrantResourceOwnerCredentials You can set it like this way by getting the user then reading the roles from DB and setting them as claim of type "Role"

 var identity = new ClaimsIdentity(context.Options.AuthenticationType); identity.AddClaim(new Claim(ClaimTypes.Name, context.UserName)); identity.AddClaim(new Claim(ClaimTypes.Role, "Admin")); identity.AddClaim(new Claim(ClaimTypes.Role, "Supervisor"));

Remember this only happens once when the user login, then you will receive a bearer signed and ecrypted token which contains all the claims for this user, no need to any DB access to verify it.

Or if you want to create the identity from Database you can use the below:

 public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager, string authenticationType)    {        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType        var userIdentity = await manager.CreateIdentityAsync(this, authenticationType);        // Add custom user claims here        return userIdentity;    }

Then in GrantResourceOwnerCredentials do the below:

ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(userManager, OAuthDefaults.AuthenticationType);

Now once you send the bearer token to an protected end point with Authorize attribute such as [Authorize(Roles = "Teacher")] I can assure you that your code will not go to the DB to do any query open SQL profiler and check it will read the claims from the encrypted token along with the Roles claim and check if this user belongs to Teacher role and allow or deny the request.

I've blogged a detailed series of 5 posts about Token Based Authentication along with Authorization server, and JWT tokens. I recommend you to read those posts to get better understanding of bearer tokens.


Rather than having 3 separate methods, You can simply check the User.IsInRole("RoleName") available in your controller class. It's using the same logic that is in the [Authorise] attribute.e.g.

public class DataApiController : ApiController{    [HttpPut]    [Route("UpdateStatus/{userTestId:int}/{userTestStatusId:int}")]    public async Task<IHttpActionResult> UpdateStatus(int userTestId, int userTestStatusId)    {        if(User.IsInRole("Admin"))        {            //Update method etc....        }        //else if(....) else etc    {}


The role claims by default are stored in the user's login cookie, so the [Authorize(Roles = "Teacher")] should be fast. The only database hit will be when you first sign in (or whenever the sign in cookie is refreshed. The authorize checks are done against IClaimsPrincipal created from the sign in cookie.

You might need to also update some other code for this to work, see this question which is similar to what you are doing: Authorize with Roles