Using Microsoft Entra groups to authorize resources access in Blazor web assembly

Recently, as a part of one of my pet projects, I was trying to implement authentication and authorization with Microsoft Entra identities and groups in a Blazor WebAssembly application. The part related to authentication was quite a simple one. The tricky part started when I tried to provide access to the specific page only for members of a specific Microsoft Entra group.
The first thing I did was configuring Token for my App Registration in Microsoft Entra to contain information about groups membership. I won’t be describing this process here, you are able to find this information inside many internet articles (for example: here). After that, I’ve added the following line of code inside Program.cs file in my WebAssembly project:
{
config.AddPolicy("GroupPolicy", policy =>
policy.RequireClaim("groups", "e39713a4-3701-5fa2-b407-17221baf91bc"));
});
Don’t worry, the all the GUID identifiers you can see in this article are the fake ones, used only for the purpose of this text ;).
I’ve also added the following attribute into the page I’ve tried to restrict access to:
@attribute [Authorize(Policy = "GroupPolicy")]
Unfortunately, when I tried to access the page, after successful login with the group member account, I was still getting the following information: “You are not authorized to access this resource.”. I the browser console, the following information was available:
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2] Authorization failed. These requirements were not met: ClaimsAuthorizationRequirement:Claim.Type=groups and Claim.Value is one of the following values: (e39713a4-3701-5fa2-b407-17221baf91bc)
That was really strange. I’ve quickly decoded my token retrieved with browser tools using https://jwt.ms site. This is what I’ve found inside:
"groups": [ "a9e91909-1ed9-467d-9d08-37379a10c8f4", "5e558337-34f1-4efc-9433-bbb7b74b67d9", "cced8cf7-26c6-4abc-bc32-7824848f521c", "e39713a4-3701-5fa2-b407-17221baf91bc" ]
That makes sense cause my account is a member of the multiple Entra groups. However due to some reasons Microsoft Identity frameworks treat this value as a single string and try to compare its content with my claim policy value.
What was needed was implementing custom Authorization Requirement and its handler. I’ve achieved this goal with the 2 following classes:
public class GroupRequirement : IAuthorizationRequirement
{
public string RequiredGroupId { get; }
public GroupRequirement(string groupId)
{
RequiredGroupId = groupId;
}
}
public class GroupRequirementHandler : AuthorizationHandler<GroupRequirement>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, GroupRequirement requirement)
{
var groupClaims = context.User.Claims.Where(c => c.Type == "groups").Select(c => c.Value).FirstOrDefault();
if(groupClaims != null)
{
var deserializedClaims = JsonSerializer.Deserialize<List<string>>(groupClaims);
if(deserializedClaims != null)
{
if (deserializedClaims.Contains(requirement.RequiredGroupId))
{
context.Succeed(requirement);
}
}
}
return Task.CompletedTask;
}
}
Finally I’ve modified the Program.cs file in my project to use my custom Group Requirement class.
builder.Services.AddAuthorizationCore(config =>
{
config.AddPolicy("GroupPolicy", policy =>
policy.Requirements.Add(new GroupRequirement("e39713a4-3701-5fa2-b407-17221baf91bc ")));
});
After all the above described operations I was finally able to access the secured page.




