Azure AD v2 roles not included in Access Token
Asked Answered
S

3

19

I'm using https://login.microsoftonline.com/.../oauth2/v2.0/token to authenticate (authorization_code grant) to azure Ad using the scopes: offline_access, openid, profile, User.Read

According to the documentation the Access Token I receive should contain the roles of the user: https://learn.microsoft.com/en-us/azure/active-directory/develop/access-tokens

However only the identity token returns the roles:

--Access Token
{
  "typ": "JWT",
  "nonce": "IWTwK2P0vzHoNnv1vvvSsjZSbAYPpSIk8MozY0A4WR0",
  "alg": "RS256",
  "x5t": "nOo3ZDrODXEK1jKWhXslHR_KXEg",
  "kid": "nOo3ZDrODXEK1jKWhXslHR_KXEg"
}.{
...
  "rh": "0.ASgASPp-HouAsUyXCdG05vvfeHAoPPG46TFOoWYsil-LDcsoADw.",
  "scp": "User.Read profile openid email",
...
}.[Signature]

--Identity Token
{
  "typ": "JWT",
  "alg": "RS256",
  "kid": "nOo3ZDrODXEK1jKWhXslHR_KXEg"
}.{
...
  "rh": "0.ASgASPp-HouAsUyXCdG05vvfeHAoPPG46TFOoWYsil-LDcsoADw.",
  "roles": [
    "MyApp.Read",
    "MyApp.Admin",
    "MyApp.Write",
  ],
...
}.[Signature]

Is there a way to make the access token also include the roles?

Sherrisherrie answered 24/2, 2021 at 9:42 Comment(4)
Hi Carl. I'll upvote and accept before the end of the day. I'm just giving others time to respond as well.Sherrisherrie
Okay, nice day :)Sphinx
Hi, does this help you?Sphinx
Murdock, I think you should upvote and accept the answer. I had the same problem and thanks to following @CarlZhao answer I managed to solve the issue.Sherronsherry
S
17

Thanks to @juunas for the tip, @juunas is right. If you are using a custom api, the user token can also contain roles claim.

You need to create two applications in Azure, one representing the client application and the other representing the api application, and then use the client application to call the api application.

First, you need to expose the API of the back-end application protected by Azure and add the client application:

enter image description here

Next you need to set the api application AppRole, which is your customized role, and it will be displayed in the manifest.

enter image description here

Then you can assign the role to the user. Go to enterprise application>your api application>Users and groups.

enter image description here

Next, go to the client application, give your client application access to your backend api:

  • Under 'API permissions' click on 'Add permission', then click on the 'My APIs' tab.
  • Find your backend application and select the appropriate scope.
  • Click 'Add permissions'.
  • Grant admin consent for your APIs.

Next, you need to use the auth code flow to obtain an access token,which requires you to log in to the user and obtain the authorization code, and then use the authorization code to redeem the access token.

enter image description here

Parse the token, it contains both scp claims and roles claims.

enter image description here

Additional step

As mentioned by @Ekkelenkamp in the comments, another step that may be required to show the roles claim in the access_token is to remove "emit_as_roles" from the "optionalClaims.accessToken" configuration in the server's app registration manifest:

enter image description here

Sphinx answered 24/2, 2021 at 10:9 Comment(10)
Thanx Carl. Do you maybe have some documentation or where is this stated?Sherrisherrie
@Sherrisherrie The user token only contains the scp claim, and only the application token has the roles claim. #45957435Sphinx
@Sherrisherrie I have answered similar questions before, you can refer to: #62543368Sphinx
This is not correct. They are not in the token because it's a MS Graph API token. User tokens can also contain a roles claim if users are assigned roles on the app. To get them the OP needs to acquire a token for their API, not MS Graph.Tuberous
Weird thing is the new answer only works if the users are explicitly added to the roles and not via a group. We ended up just using the id token.Sherrisherrie
@CarlZhao the step of authorizing the client application in the "Expose an API" blade of the API registration is not necessary for this to work.Sherronsherry
Yes, this operation is not necessary.Sphinx
Anyone coming to this using NestJs must add the api url to the protectedResouceMap: {'http://api.example', 'api://6765.../test/ }. This will get an access token including roles if set up as described above.Cepeda
Thanks for the great explanation. It is very hard to find documentation on how to actually set this up. I followed the steps described her. All seems fine, the access key can be validated correctly (which is not possible using the default openid scope ). But still no app roles in the access token. I feel I'm missing one little step here. Any suggestions would be appreciated. Maybe there are some requirements on the app registration type of the api or client applications?Stiles
I figured out what what wrong on my side. In the token configuration on the app registration, I added the optional groud claim and enabled the Emit groups as role claims on the access token. This is not needed and prevented the app roles on appearing in the access key. I also found the following explanation quite userfull: dotnetlead.com/net/…Stiles
E
2

Unfortunately there is a bug on AAD that only add the roles to the access_token when an API scope is requested when requesting the token.

In order to get the roles to work, your need the following setup:

  • Create the application
  • Add an scope to the application using the "Expose an API"
  • Use the scope created on step above when requesting a token

The end result will be a token

Example:

https://login.microsoftonline.com/{tenantid}/oauth2/v2.0/authorize?client_id={appid}&response_type=token&scope={appid}/{scopename}&nonce=678910

The scopes openid, email and profile should only be used with id_tokens

Edithe answered 2/11, 2021 at 23:12 Comment(1)
This solution works for me! but the scopes should work with access tokens as well if I am not missing anything...Antemortem
C
2

If you are registering an API app in Azure Active Directory's App Registration and exposing that through an SPA app also registered in Azure Active Directory, then-

  1. The id token contains roles exposed on the SPA app and
  2. The access token contains roles exposed on the API app.

(This was the essential information for me from Carl Zhao's answer)

Christiansen answered 17/12, 2021 at 4:37 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Purgatorial

© 2022 - 2024 — McMap. All rights reserved.