top of page

Configure App attributes in Entra ID Access Token – App Claims Mapping Policy

  • Nick Tillack
  • Mar 16
  • 5 min read

Updated: Mar 17


Customise Application Access Token for Service to Service Entra ID claims token.

There are many instances where a custom claim in the client credentials flow is required. One such example is when you have a scenario where Application A is calling Application B's API, and Application B needs to see the displayname of Application A in the access token provided in the api call. The (client) application displayname is not part of the basic claim set that is included by default for tokens in addition to the core claim set. Additionally, it is not included as an optional claim that can be configured in the Entra portal and therefore must be included as a custom claim in a claims mapping policy. We can see in the claims customization reference that the displayname sourced from the client application can be included in the JWT or SAML token. A common scenario is to configure Access Tokens to include app attributes such that the API can verify information of the app from the directory without making additional calls to Microsoft Graph API.


To demonstrate this, we'll setup two new app registrations, "Application A - Client App" and "Application B - Web API", and firstly see what the default access token looks like without applying a claims mapping policy.


Service to Service OAuth Demo Setup

  • Create 2 app registrations, "Application A - Client App" and "Application B - Web API".

  • Create an app role called 'api_access' and add an application ID uri (Expose an API blade) on "Application B - Web API".

  • Grant "Application A - Client App" access to App B's api_access app role (you will need to set yourself as the owner of B to be able to do this).


What the client credential access token looks like before we add a Claims Mapping Policy

Throughout this demo we'll use Postman to make the request to Entra and obtain the access token via the client credential authentication flow. We'll then paste the access token in https://jwt.ms to view the claims for verification purposes.


Firstly, we'll setup our request in Postman, setting the grant type to Client Credentials, using the clientid and client secret for our Application A - Client App registration. Also, ensure the scope is set to the default scope of the Application B - Web API registration. In my case, that's api://695621b9-6edf-4fa2-b27d-d01e152cce52/.default.


Client Credential flow using Postman:


OAuth 2 Client Credential Flow Postman Entra Id


Once we click 'Get New Access Token' and copy paste the token into https://jwt.ms, we can see that the Web API would receive the following claims:


View Client Credential App Access Token Claims via Jwt.ms

We can see that by default, the access token that is retrieved via a client credential flow includes several claims that provide information about the calling application, however the app displayname and Application's URI are not included by default.


How to Include Application Display Name From an OAuth Access Token Using a Claims Mapping Policy

Before we create a claims mapping policy, we need to make two modifications to the manifest of the Application B - Web API app.

  1. The 'acceptmappedclaims' flag must be set to 'true'. This should only be set for single tenant applications - see the app manifest reference

  2. 'requestedAccessTokenVersion' needs to be set to '2'


These changes enable the application us to configure the claims inside the token.


OAuth2 return app_displayname in token claims Entra ID App Manifest changes

We then need to update the Application ID uri of Application B - Web API. Firstly, go to the 'Expose an API blade' and change the Application ID uri that we created earlier to https://yourtenantdomainname/webapi. In my case, this is https://modern443.com/webapi.


Retrieve application display name from an oauth access token

Now that our that our Web API app registration is updated, we can create the Claims Mapping Policy. There is no interface in the Azure/Entra portal to create or interact with claims mapping policies, so for this we'll use the Invoke-MgGraphRequest cmdlet as part of the Microsoft Graph PowerShell SDK.

Firstly, run Connect-MgGraph -Scopes "Policy.ReadWrite.ApplicationConfiguration", "Policy.Read.All" to sign into Entra using an account with at least Cloud Application Administrator.

Next, we'll make a POST request to the /policies/claimsMappingPolicies endpoint to create the policy. We will provide the definition parameter which specifies if the basic claimset will be included and the claim schema for any new claims we are adding. We will also specify the displayname of the policy which we will call 'IncludeAppDisplayname' (ensure this is unique within your tenant).

We can refer to the claim set reference to see what other claims we are able to map using this method.


Configure App Attributes in Access Token

Firstly defining the parameters we will supply in our POST request and assigning to the 'params' variable:


$params = @{
	definition = @(
	'{"ClaimsMappingPolicy":{"Version":1,"IncludeBasicClaimSet":"true", "ClaimsSchema": [{"Source":"application","ID":"displayname","SamlClaimType":"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/clientapp_displayname","JwtClaimType":"clientapp_displayname"}]}}'
) 
displayName = "IncludeAppDisplayName"
}

In the claims schema specified above, the 'Source' and 'ID' fields must be a valid combination sourced from the claim schema entry elements. The 'SamlClaimType' and 'JwtClaimType' fields can be set to determine what the name of our claim will be in the respective tokens. In this case, we've set this to "clientapp_displayname".

Next, we'll use the Invoke-MgGraphRequest cmdlet to make the POST request to the claimsMappingPolicies endpoint.



Invoke-MgGraphRequest -Method POST https://graph.microsoft.com/v1.0/policies/claimsMappingPolicies -Body $params

Once the claims mapping policy has been created, we need to assign it to the service principal of our application that is receiving the api call (Application B - Web API). This ensures that any application requesting a token to be scoped to our Web API app will have the claims mapping policy take effect for the access token. To do this, we first need to find the id of our newly created claims mapping policy. This was provided to us in the output of the previous command, however we can also do this by getting all claims mapping policies with the following command.


Invoke-MgGraphRequest -Method GET https://graph.microsoft.com/v1.0/policies/claimsMappingPolicies/ | Select-Object -ExpandProperty Values

Entra Id Claims Mapping Policies via PowerShell

In our example, we can see that we have only one, with an id of 679ce342-4e5e-4891-bd5d-cb35caef43c1. If there are more in your tenant, you will have to match the relevant policy displayname to the claims mapping policy id.


We then set the parameters of the request to the reference of our claims mapping policy, ensuring that you replace the below id with the id of your own claims mapping policy.


$params = @{
	"@odata.id" = "https://graph.microsoft.com/v1.0/policies/claimsMappingPolicies/679ce342-4e5e-4891-bd5d-cb35caef43c1"
}

And finally make the request to assign the the claims mapping policy to the Application B - Web API service principal, ensuring that you replace the id specified in the below uri to your own service principal object id.


Invoke-MgGraphRequest -Method POST 'https://graph.microsoft.com/v1.0/servicePrincipals/f542bbbd-2960-4c6e-8830-ba75bc77d277/claimsMappingPolicies/$ref' -Body $params

We can confirm that this has assigned properly by running the following graph request to get assigned claims mapping policies for the service principal.


(Invoke-MgGraphRequest -Method GET 'https://graph.microsoft.com/v1.0/servicePrincipals/ead54af3-e611-495d-a849-78f848f8d9c6/claimsMappingPolicies').value

The returned id should match the id of our claims mapping policy.


Finally, we'll head back to postman to get a new access token. We will need to change the requested scope of our request to include our new Application ID URI, in my case the scope is now 'https://modern443.com/webapi/.default'


view custom claims in Entra Id Access Token from Client Credential Flow using Jwt.ms


We can see that the last claim in the list is our new app displayname claim. Claims mapping policies support several other claim types that can be added to the access token. Additionally, claims mapping policies can include claims transformations to modify the values displayed in the tokens, see claims customization.


References

Abstract Lines _edited.jpg

Having an Identity Crisis?

Connect with our experts to enhance your organization's security and efficiency. Our team will reach out to understand your needs and create a tailored solution.

bottom of page