Introduction:
Azure AD B2C is a robust solution for managing customer identities, but it has certain limitations compared to Microsoft Entra ID (formerly Azure Active Directory). A key limitation is the absence of native support for app roles and group claims—features that are readily available in Microsoft Entra ID. Specifically, Azure AD B2C does not include group memberships or app role assignments in the issued ID token.
However, Azure AD B2C is built on the Microsoft Entra ID platform, so we can overcome this limitation by integrating with the Microsoft Graph API. In this blog, I’ll walk you through how I developed a custom solution that enables this functionality
Overview
Here’s what we’ll cover:
- Creating a secure .NET 8 MVC application to manage app roles and group memberships using Microsoft Graph API.
- Enriching Azure AD B2C ID tokens with app role and group information using an Azure Function.
- Integrating the Azure Function with a custom B2C policy.
- Deploying infrastructure, including Azure Web App, Key Vault, and Function App.
- Automating infrastructure deployment using GitHub Actions.

This workaround solution to manage the app role and groups is only for the users who are using Azure AD B2C, not for Entra External ID.
Recommendation
- If you’re starting a new project, use Microsoft Entra External ID.
- If using Azure AD B2C today, evaluate a migration strategy as Microsoft aligns future innovation with Entra External ID.
Building the .NET 8 MVC Application with Microsoft Graph API
The first part of the project was developing a .NET 8 MVC application that allows an application owner to manage app roles and a group owner to manage group members. The application is protected using Azure AD B2C and is accessible only to authenticated users.
Register two applications in Azure AD B2C: one to implement the client credential flow and another for application authentication using the Authorization flow.
Why Client Credential flow to implement Graph Client?
Azure AD B2C has no delegated permission for the following MS Graph API scopes. So, we used the application permission with the client credentials flow.
- Application.Read.All
- AppRoleAssignment.ReadWrite.All
- GroupMember.ReadWrite.All
- User.Read.All

Get the Secret and save it in Azure Key Vault and use the Secret. JSON service for local development.
Authorization Flow for the user login
Register a B2C application in the Azure portal with the default open ID permission for the application user login.
Make sure you have selected ID tokens for Implicit grant and hybrid flows.

This application has different abilities to manage application roles and Group membership
Application Page
This application page will list all the app roles and allow you to manage or assign users or groups to the app roles.
The user should log in as an application owner to manage the members for App roles.

Groups I Own Page
This page will list all your own groups and allow you to manage their members.

I used Materio template for the UI design
Azure Function to Enrich B2C Claims
To dynamically include app role and group membership data in user tokens, I created an Azure Function that integrates with Azure AD B2C custom policies.
Function Capabilities:
- Accepts the user’s object ID.
- Calls Microsoft Graph using client credentials to:
- Fetch assigned app roles.
- Fetch group memberships.
- Returns a JSON structure with this data to be included in the token.
This function provides real-time identity enrichment and supports fine-grained access control in downstream applications.
Learn more about this Azure Function implementation from my last article
Azure AD B2C Custom Policy to Call Azure Function
To invoke the Azure Function during the token issuance process, I extended my Azure AD B2C custom policy.
Custom Policy Integration Steps:
- Defined a ClaimsExchange to call the RESTful technical profile pointing to the Azure Function.
- Passed the objectId as an input claim.
- Mapped the response to custom claims like appRoles and groups.
This step ensures that the enriched identity information is included in the token at runtime without storing it directly in the B2C directory.
Learn more about this Custom policy implementation from my last article
Infrastructure Setup in Azure
To host and manage all components, I provisioned the following resources:
- Azure Web App: Hosts the .NET 8 MVC application.
- Azure Function App: Hosts the claim enrichment logic.
- Azure Key Vault: Securely stores client ID, client secret, and tenant ID.
- Azure Application Registration: This is for Graph API access and authentication.
- Azure Resource Group: Logical grouping of all resources.
All secrets were referenced using Managed Identity where applicable.
GitHub Actions for Infrastructure Deployment
To automate infrastructure deployment and streamline CI/CD, I implemented GitHub Actions workflows that:
- Use az login via service principal for secure access.
- Deploy ARM/Bicep templates or Terraform scripts for:
- App Service
- Function App
- Key Vault
- Upload secrets to Key Vault.
- Assign necessary permissions (e.g., Managed Identity to read secrets).
Check the Bicep template for the deployment from my GitHub repository
Summary
While Azure AD B2C doesn’t natively support app roles and group claims like Microsoft Entra ID, its foundation on the same underlying framework allows for these capabilities to be extended through the Microsoft Graph API and custom policies. To address this limitation, I created a custom solution that includes a web application for managing app roles and group memberships, an Azure Function to dynamically retrieve this data at runtime, and custom B2C policies to inject the role and group claims into the token. This setup enables fine-grained access control and enterprise-grade authorization for applications using Azure AD B2C, bringing it much closer to the feature set offered by Microsoft Entra ID. The complete implementation is available on GitHub for easy customization and reuse.