Even though this is an old question, I was challenged with the same issue and I want to share my solution which I find a lot more practical and easier to understand.
Introduce these two helper methods into your code:
using Newtonsoft.Json;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
/// <summary>
/// Decodes a JWT token to a decoded string.
/// </summary>
/// <param name="jwtToken">The JWT token to decode.</param>
/// <returns>The decoded string representation of the JWT token.</returns>
public static string DecodeJwtToken(string jwtToken)
{
var tokenHandler = new JwtSecurityTokenHandler();
if (tokenHandler.CanReadToken(jwtToken))
{
var decodedToken = tokenHandler.ReadJwtToken(jwtToken);
return decodedToken.ToString();
}
else
{
throw new ArgumentException("Invalid JWT token.");
}
}
/// <summary>
/// Extracts the "roles" array from a JWT security token.
/// </summary>
/// <param name="jwtToken">The JWT security token from which to extract the roles array.</param>
/// <returns>A list of strings representing the roles extracted from the JWT security token.</returns>
public static List<string> ExtractRolesFromJwtSecurityToken(string jwtToken)
{
var tokenHandler = new JwtSecurityTokenHandler();
var securityToken = tokenHandler.ReadToken(jwtToken) as JwtSecurityToken;
if (securityToken != null)
{
var rolesClaims = securityToken.Claims.Where(claim => claim.Type == "roles");
if (rolesClaims != null)
{
var roleStrings = rolesClaims.Select(claim => claim.Value.Replace("roles:", "").Trim()).ToList();
return roleStrings;
}
}
// If roles claim is not found or cannot be extracted, return an empty list or handle the error accordingly.
return new List<string>();
}
These two can be used like this:
var app = ConfidentialClientApplicationBuilder.Create(clientId)
.WithAuthority(AzureCloudInstance.AzurePublic, tenantId)
.WithClientSecret(clientSecret)
.Build();
var authResult = await app.AcquireTokenForClient(scopes).ExecuteAsync();
var jwtToken = authResult.AccessToken;
// use this if you want to inspect the entire token
var decodedToken = DecodeJwtToken(jwtToken);
// and if you're lazy, this. The result will be like {"Mail.Read", "Mail.Write", ... }
var permissions = ExtractRolesFromJwtSecurityToken(jwtToken);