Using Token Configuration to include arbitrary claims in id_token or access_token or samlToken

Sahil Malik
Winsmarts.com
Published in
4 min readApr 22, 2020

--

Wow that is a long title, isn’t it? Here is what I am trying to do. There is a new feature in AAD that lets you add optional claims,

But if you click on it, it shows you a whitelisted value of tokens to pick from. I have covered this nicely in my Pluralsight course, specifically here, where I talk about custom claims driven authorization. In that course, I show you how to include claims from a whitelisted set of checkboxes (ip_addr, ctry, more..), but did you know, that the Token configuration whitelisted token list also includes custom directory extension claims also? That is the focus of this blogpost.

The challenge is, sometimes organizations have a whole bunch of custom information they wish to drive this logic from. So, you can use AAD connect and synch directory extensions, and use those to include claims.

The purpose of this blogpost is to dive a bit deeper. I want to using MS Graph, create directory extensions, set it’s value, and then include it in my claim. Cool?

Here are some important points to remember, yes please read these.

  1. Extension Attributes and Directory extensions are different things. As of now, you need directory extensions. In MS Graph terms, this means not /extensions, but /extensionProperties.
  2. You create a directory extension on an application, and you then add it’s value on the user object.
  3. If you wish to include it in the samlToken, you simply create it on the application and you are all set.
  4. If you wish to include it in the id_token, you add a value on the user object, on the app that is authenticating, i.e. the client app.
  5. If you wish to include it in the access_token, you add it in the called API application.

Cool? Okay lets get started. By the end of this blogpost, you’ll know how to get this working for id_token, but you can easily extend it for access_token.

Step 1: Create the directory extension

This is a POST request as follows,

https://graph.microsoft.com/v1.0/applications/<app's ObjectId>/extensionProperties

The BODY is the extension property you are creating,

{
"name": "someExtension",
"dataType": "string",
"targetObjects": [
"User"
]
}

This produces an output as below,

Note the name for the extension property, extension_guid_extensionname. That guid is the appID. The appID, not ObjectID

Step 2: Create value for a user

You issue a PATCH request to,

https://graph.microsoft.com/v1.0/users/<userid | username>

With a BODY as follows,

{
"extension_4ae2b98d392444a4a8dc4bc01d6b94e2_someExtension": "someValue"
}

Step 3: Include it in your manifest.xml

You can hand edit manifest.xml, but you can also use the Token Configuration page. Honestly just use the Token Configuration page, because if you mess up in typing, the Token Configuration page will show you the error, which is kind of nice. Here is how you select this extension property

This is the change it made to manifest.xml

Step 4, Authenticate and look for the id_token

I am using an iOS app, you can use whatever, anything that gives you an id_token.

func acquireTokenInteractively() {guard let applicationContext = self.applicationContext else { return }guard let webViewParameters = self.webViewParamaters else { return }let parameters = MSALInteractiveTokenParameters(scopes: kScopes, webviewParameters: webViewParameters)parameters.promptType = .selectAccountapplicationContext.acquireToken(with: parameters) { (result, error) inif let error = error {self.updateLogging(text: "Could not acquire token: \(error)")return}guard let result = result else {self.updateLogging(text: "Could not acquire token: No result returned")return}// result.idToken is what you need hereself.accessToken = result.accessTokenself.updateLogging(text: "Access token is \(self.accessToken)")self.updateCurrentAccount(account: result.account)self.getContentWithToken()}}

Once you get the id_token, go to https://jwt.ms and decrypt it,

BOOM! You have your extension property now included in the claim.

--

--