I have created an app Registration and want to add some custom claims into my JWT access token.
I have follow the instructions from https://learn.microsoft.com/en-us/entra/identity-platform/optional-claims but somehow I must have done a mistake as I cannot get any additional claim into my JWT access token (I request it via Postman and check the data with https://jwt.io).
I tried to add the custom claims via the azure portal but my JWT does not add these values
I played with the scopes and used: User.Read openid profile but changing these value did not change anything too.
Her the example of my manifest:
{
"id": "cfdb05a2-357b-4e52-8f68-7a4a48a45256",
"acceptMappedClaims": null,
"accessTokenAcceptedVersion": 2,
"addIns": [],
"allowPublicClient": true,
"appId": "19eccd56-b192-450d-820c-77a353d1fd7c",
"appRoles": [],
"oauth2AllowUrlPathMatching": false,
"createdDateTime": "2024-04-22T14:31:19Z",
"description": null,
"certification": null,
"disabledByMicrosoftStatus": null,
"groupMembershipClaims": "None",
"identifierUris": [
"api://19eccd56-b192-450d-820c-77a353d1fd7c"
],
"informationalUrls": {
"termsOfService": null,
"support": null,
"privacy": null,
"marketing": null
},
"keyCredentials": [],
"knownClientApplications": [],
"logoUrl": null,
"logoutUrl": null,
"name": "TEST_APP_SAML",
"notes": null,
"oauth2AllowIdTokenImplicitFlow": true,
"oauth2AllowImplicitFlow": true,
"oauth2Permissions": [],
"oauth2RequirePostResponse": false,
"optionalClaims": {
"idToken": [
{
"name": "tenant_region_scope",
"source": null,
"essential": false,
"additionalProperties": []
},
{
"name": "verified_primary_email",
"source": null,
"essential": false,
"additionalProperties": []
},
{
"name": "verified_secondary_email",
"source": null,
"essential": false,
"additionalProperties": []
},
{
"name": "vnet",
"source": null,
"essential": false,
"additionalProperties": []
},
{
"name": "ctry",
"source": null,
"essential": false,
"additionalProperties": []
},
{
"name": "tenant_ctry",
"source": null,
"essential": false,
"additionalProperties": []
},
{
"name": "xms_pdl",
"source": null,
"essential": false,
"additionalProperties": []
},
{
"name": "xms_pl",
"source": null,
"essential": false,
"additionalProperties": []
},
{
"name": "xms_tpl",
"source": null,
"essential": false,
"additionalProperties": []
},
{
"name": "ztdid",
"source": null,
"essential": false,
"additionalProperties": []
},
{
"name": "upn",
"source": null,
"essential": false,
"additionalProperties": [
"include_externally_authenticated_upn"
]
},
{
"name": "xms_cc",
"source": null,
"essential": false,
"additionalProperties": []
}
],
"accessToken": [
{
"name": "ctry",
"source": null,
"essential": false,
"additionalProperties": []
},
{
"name": "tenant_ctry",
"source": null,
"essential": false,
"additionalProperties": []
},
{
"name": "ztdid",
"source": null,
"essential": false,
"additionalProperties": []
},
{
"name": "upn",
"source": null,
"essential": false,
"additionalProperties": [
"include_externally_authenticated_upn"
]
},
{
"name": "login_hint",
"source": null,
"essential": false,
"additionalProperties": []
}
],
"saml2Token": []
},
"orgRestrictions": [],
"parentalControlSettings": {
"countriesBlockedForMinors": [],
"legalAgeGroupRule": "Allow"
},
"passwordCredentials": [],
"preAuthorizedApplications": [],
"publisherDomain": "andreasweier85gmail.onmicrosoft.com",
"replyUrlsWithType": [
{
"url": "https://jwt.ms",
"type": "InstalledClient"
},
{
"url": "https://login.microsoftonline.com/common/oauth2/nativeclient",
"type": "InstalledClient"
}
],
"requiredResourceAccess": [
{
"resourceAppId": "00000003-0000-0000-c000-000000000000",
"resourceAccess": [
{
"id": "14dad69e-099b-42c9-810b-d002981feec1",
"type": "Scope"
},
{
"id": "e1fe6dd8-ba31-4d61-89e7-88639da4683d",
"type": "Scope"
}
]
},
{
"resourceAppId": "00eda80b-051a-46ab-940f-2bbdc3dabeec",
"resourceAccess": [
{
"id": "4d2e19f0-3525-4517-9e7d-48f0411b4395",
"type": "Scope"
}
]
}
],
"samlMetadataUrl": null,
"signInUrl": null,
"signInAudience": "AzureADMultipleOrgs",
"tags": [
"apiConsumer",
"singlePageApp"
],
"tokenEncryptionKeyId": null
}
2
Answers
Thanks for the answer. Somehow I do still not manage to get the values in my token even with your proposed solution.
I did some investigations/tries and found out, that if I add in my scope openid (in order to use openid eg. get Id token) then I get all my needed values (groups, custom claims, standard claims ) in the id token but not in the access token. Any further hints?
Here once again my config and an example ID-TOKen and Access-Token I get
Manifest:
}
The ID-Token:
and finaly the access token (decoded payload):
In your optional claims you have not specified a source. When source is
null
the Microsoft Identity Platform doesn’t know where to get the information from. Thus, the claim is completely omitted from the token.name
: The name of the claim as it will apear in the token returned by the Identity Platform.source
: The Entra ID User Profile Attribute, or Directory Extension, which should be read for the authenticating user. You can use OOB attributes, such as userPrincipalName. Or, you can use an extended (custom) attribute. For custom attributes, such as your use of vnet, you should have already extended the directory schema and assigned a value to the user.essential
: Tells the server to fail authentication if it is not possible to obtain the value of source for the user. You’ve set to false, which is fine.additionalProperties
: Allows you to validate, filter and transform the claim value according to criteria, conditions, and parameters you specify. include_externally_authenticated_upn does not appear to me to be a valid additional property field.So, let’s look at an example where you want to return the user principal name as a claim with the name upn.
Here we use name "upn" to specify the return claim name, and source userPrincipalName, because that is the name of the attribute in Entra.
If you are using custom attributes from a directory extension, make sure the extension has been applied.
https://learn.microsoft.com/en-us/entra/identity/domain-services/concepts-custom-attributes