I have developed an authentication mechanism in Asp.Net Web Api 2 with the feature for granting refresh tokens, based on the tutorial on Taiseer's blog.
Here is my question. Assume the following scenario: A user logs in using password and get a refresh token and an access token. The access token in fact includes what roles he is in (hence his authorities within the app). In the mean time the system admin will change this person's roles, so once his access token expires and he wants to use the refresh token to obtain a new access token, his new access token must include the newly updated roles for him.
In my "RefreshTokenProvider" class, I am using the following code in "GrantResourceOwnerCredentials" method to get the user roles from the database and add them to the claims:
var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(new ApplicationDbContext()));
var y = roleManager.Roles.ToList();
var id = new ClaimsIdentity(context.Options.AuthenticationType);
id.AddClaim(new Claim(ClaimTypes.Name, context.UserName));
id.AddClaim(new Claim("sub", context.UserName));
var roles2 = UserRoleManagerProvider.RoleManager().Roles.ToList();
foreach (IdentityRole i in roles2)
{
if (roleIds.Contains(i.Id))
id.AddClaim(new Claim(ClaimTypes.Role, i.Name));
}
This piece works fine (even though I believe there should be a nicer way to do it?!)
But the part that is not working properly is in the "GrantRefreshToken" method, where we need to update roles in order to reflect them in the new access token:
var newId = new ClaimsIdentity(context.Ticket.Identity);
// *** Add shit here....
var userId = context.Ticket.Properties.Dictionary["userId"];
IdentityUser user = UserRoleManagerProvider.UserManager().FindById(userId);
foreach (Claim c in newId.Claims)
{
if (c.Type == ClaimTypes.Role) newId.RemoveClaim(c);
}
if (user.Roles.Count > 0)
{
var roleIds = new List<string>();
var roles2 = UserRoleManagerProvider.RoleManager().Roles.ToList();
foreach (IdentityUserRole ir in user.Roles)
{
roleIds.Add(ir.RoleId);
}
foreach (IdentityRole r in roles2)
{
if (roleIds.Contains(r.Id))
newId.AddClaim(new Claim(ClaimTypes.Role, r.Name));
}
}
Again, if there is a nicer way to do it I'd appreciate you guy's help! But mainly, my problem is that the part for removing the Roles that are not in effect anymore, does not work. Do you by any chance know what is wrong with that piece?!
FYI, in the above code the "UserRoleManagerProvider" is a simple static class I have created which is like this:
public static class UserRoleManagerProvider
{
public static RoleManager<IdentityRole> RoleManager()
{
var roleManager = new RoleManager<IdentityRole>(new RoleStore<IdentityRole>(new ApplicationDbContext()));
return roleManager;
}
public static UserManager<IdentityUser> UserManager()
{
var userManager = new UserManager<IdentityUser>(new UserStore<IdentityUser>(new ApplicationDbContext()));
return userManager;
}
}