I have a working setup in Azure where a Function App is protected by OAuth using an app registration in AAD.
In this app registration, I have defined two roles; Administrator and Developer. I have assigned both of these roles to myself, and now I want to retrieve the role to determine what kind of actions a user is allowed to take.
To try to understand what is going in, I've added the following to a protected endpoint:
[FunctionName("Test")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req, CancellationToken ct)
{
bool isDeveloper = req.HttpContext.User.HasClaim("roles", "Developer");
bool isAdministrator = req.HttpContext.User.HasClaim("roles", "Administrator");
_logger.LogInformation($"Has role developer? {isDeveloper}"); // true
_logger.LogInformation($"Has role administrator? {isAdministrator}"); // true
bool isDeveloperBuiltin = req.HttpContext.User.IsInRole("Developer");
bool isAdministratorBuiltin = req.HttpContext.User.IsInRole("Administrator");
_logger.LogInformation($"Has role developer using built in? {isDeveloperBuiltin}"); // false
_logger.LogInformation($"Has role administrator using built in? {isAdministratorBuiltin}"); // false
foreach (Claim claim in req.HttpContext.User.Claims)
{
_logger.LogInformation(claim.Type " : " claim.Value "\n");
}
}
The name of the role claim in my token is roles
but under the hood the IsInRole
function checks the claim ClaimsType.Role
which I do not have in my token. Pasting my token at jwt.ms shows:
"roles": [
"Developer",
"Administrator"
]
How come the role claim is different for a token issued by Microsoft themselves? Am I misunderstanding something here?
If possible I would like to use the utility method IsInRole
, but I have worked around this for the moment and wrote a small utility which basically does the same:
public bool IsUserInRole(ClaimsPrincipal principal, Role role)
{
return principal.HasClaim("roles", role.ToString());
}
However, I would like to understand what is going on here and what steps I could take to use the IsInRole
method instead. Am I doing something wrong by instead using my own utility method?
CodePudding user response:
This is a known limitation of Azure function. You can read about discussion at this github issue. So your current approach is way to go. However,
I would suggest to write an extension method (may be I like as it is more cleaner).
public static class ClaimsPrincipalExtensions
{
public static bool IsUserInRole(this ClaimsPrincipal principal, Role role)
{
return principal.HasClaim("roles", role.ToString());
}
}