8

I have a small Web API application that uses Identity to manage users using Owin Bearer Tokens. The basics of this implementation work fine: I can register a user, login a user and access Web API end points that are marked with [Authorize].

My next step is to limit Web API endpoints using roles. For example, a controller that only users in the Admin role can access. I've created the Admin user as below and I add them to the Admin role. However when I update my existing controllers from [Authorize] to [Authorize(Roles = "Admin")] and try to access it using the Adim account, I get a 401 Unauthorized.

    //Seed  on Startup
    public static void Seed()
    {
        var user = await userManager.FindAsync("Admin", "123456");
        if (user == null)
        {
            IdentityUser user = new IdentityUser { UserName = "Admin" };
            var createResult = await userManager.CreateAsync(user, "123456");

            if (!roleManager.RoleExists("Admin"))
                var createRoleResult = roleManager.Create(new IdentityRole("Admin"));

            user = await userManager.FindAsync("Admin", "123456");
            var addRoleResult = await userManager.AddToRoleAsync(user.Id, "Admin");
        }
    }


   //Works
   [Authorize]
    public class TestController : ApiController
    {
        // GET api/<controller>
        public bool Get()
        {
            return true;
        }
    }

   //Doesn't work
   [Authorize(Roles = "Admin")]
    public class TestController : ApiController
    {
        // GET api/<controller>
        public bool Get()
        {
            return true;
        }
    }

Q: What is the correct way to set up and use roles?


user-8564775
  • 483
  • 2
  • 5
  • 15
  • Have you checked the Role table for newly created role 'Admin' and UserRole table for correct user with Admin role? Are you using identity framework 2.0 or later? – DSR Oct 27 '14 at 10:59

1 Answers1

10

How do you set the claims for the users when they login I believe you are missing this line of code in method GrantResourceOwnerCredentials

 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"));

And if you want to create the identity from DB 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);
Taiseer Joudeh
  • 8,953
  • 1
  • 41
  • 45
  • This works, but I'm not sure I understand why. Do I need to combine this with `userManager.AddToRoleAsync`? In the Grant, should I only assign claims to an Identity if the user belongs to that Role? if you could point me to some documentation, I would appreciate it a lot. Thanks! – user-8564775 Oct 28 '14 at 07:36
  • 1
    Updated the answer, please check it – Taiseer Joudeh Oct 28 '14 at 08:55
  • 2
    I'm new to the Claims tokens, but to me it looks like all tokens received from server will have the Admin and supervisor role assigned. Should'nt the roles for the identity be dynamically fetched by the roles that this user has? – Mohag519 Jan 28 '15 at 09:54
  • @Mohag519 you are missing a point: the idea is to add a Claim of type ClaimTypes.Role to the Identity. That's it. It is totally up to you to add extra logic/validation/check/etc. – Pavel Kovalev Jan 04 '17 at 19:48