3

We are trying to set up an authentication/authorization-process with the following requirements:

  • Authentication: Done by Azure AD.
  • Authorization: Only members of a specific security groups should be allowed to access the app.

While the authentication part seems to work without problems, we are stuck at the authorization part. We are using Express and Passport.

Azure AD some tokens to req.headers, e.g.

  • x-ms-token-aad-access-token
  • x-ms-token-aad-refresh-token
  • x-ms-token-aad-id-token

We are currently using the id-token together with the passport-azure-ad BearerStrategy to check the security groups of the user against the allowed security groups.

The problem is: As soon as the id-token expires, the application won't let us access the app. Assuming setting {session: true} in passport could solve this issue, we enabled the session, but no luck.

Doing some more research I found this post: How to refresh an ID Token from Azure AD in a Web App?, which states that only access-tokens can be refreshed, but ID tokens cannot and should not.

Examining the x-ms-token-aad-access-token and the x-ms-token-aad-refresh-token, we found that they don't have the JWT-structure, e.g

    eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1THdqcHdBSk9NOW4tQSJ9.eyJhdWQiOiJodHRwczovL3NlcnZpY2UuY29udG9zby5jb20vIiwiaXNzIjoiaHR0cHM6Ly9zdHMud2luZG93cy5uZXQvN2ZlODE0NDctZGE1Ny00Mzg1LWJlY2ItNmRlNTdmMjE0NzdlLyIsImlhdCI6MTM4ODQ0MDg2MywibmJmIjoxMzg4NDQwODYzLCJleHAiOjEzODg0NDQ3NjMsInZlciI6IjEuMCIsInRpZCI6IjdmZTgxNDQ3LWRhNTctNDM4NS1iZWNiLTZkZTU3ZjIxNDc3ZSIsIm9pZCI6IjY4Mzg5YWUyLTYyZmEtNGIxOC05MWZlLTUzZGQxMDlkNzRmNSIsInVwbiI6ImZyYW5rbUBjb250b3NvLmNvbSIsInVuaXF1ZV9uYW1lIjoiZnJhbmttQGNvbnRvc28uY29tIiwic3ViIjoiZGVOcUlqOUlPRTlQV0pXYkhzZnRYdDJFYWJQVmwwQ2o4UUFtZWZSTFY5OCIsImZhbWlseV9uYW1lIjoiTWlsbGVyIiwiZ2l2ZW5fbmFtZSI6IkZyYW5rIiwiYXBwaWQiOiIyZDRkMTFhMi1mODE0LTQ2YTctODkwYS0yNzRhNzJhNzMwOWUiLCJhcHBpZGFjciI6IjAiLCJzY3AiOiJ1c2VyX2ltcGVyc29uYXRpb24iLCJhY3IiOiIxIn0.JZw8jC0gptZxVC-7l5sFkdnJgP3_tRjeQEPgUn28XctVe3QqmheLZw7QVZDPCyGycDWBaqy7FLpSekET_BftDkewRhyHk9FW_KeEz0ch2c3i08NGNDbr6XYGVayNuSesYk5Aw_p3ICRlUV1bqEwk-Jkzs9EEkQg4hbefqJS6yS1HoV_2EsEhpd_wCQpxK89WPs3hLYZETRJtG5kvCCEOvSHXmDE6eTHGTnEgsIk--UlPe275Dvou4gEAwLofhLDQbMSjnlV5VLsjimNBVcSRFShoxmQwBJR_b2011Y5IuD6St5zPnzruBbZYkGNurQK63TJPWmRd3mbJsGM0mf3CUQ

They don't contain any dots and thus don't pass the JWT-verification.

Resulting in the following question:

  • What is the correct way to check security groups of a user against specified allowed security groups?
omg_me
  • 69
  • 1
  • 6

2 Answers2

8

You can do it through passport in one call, you do not need to do extra calls to other api layers, as seams to be suggested in multiple posts online. Using the v2 endpoint and defining a scope you can choose what you have access to and what you receive back in the token. Some options, including security group do require you to modify the manifest, see below.

In your Azure Active Directory go to the App registration you are using the authenticate users. In the manifest for that app registration change the groupMembershipClaims from null to "SecurityGroup" or "All" if want to include office groups etc.

{ "id": "some-id", "accessTokenAcceptedVersion": null, "allowPublicClient": false, "appId": "some-id", "appRoles": [], "oauth2AllowUrlPathMatching": false, "createdDateTime": "2018-11-15T17:49:23Z", "groupMembershipClaims": "SecurityGroup", "identifierUris": [ ...............

It then populates the Groups field with an array of the groups using their Object ID.

So you can get the array at req.user._json.groups

   if (req.user._json.groups.indexOf('some-group-Object-ID') > -1) {
        //In Group
    } else {
        //Not in Group
    }
RickWeb
  • 1,765
  • 2
  • 25
  • 40
  • 1
    This is the answer that helped me with what I needed – Jeff Sep 17 '19 at 16:43
  • This is indeed the best answer but keep in mind that if users are member of [more than 150 groups you can have issues](https://learn.microsoft.com/en-us/azure/active-directory/hybrid/how-to-connect-fed-group-claims) as the token will not contain all groups.. – DarkLite1 Feb 21 '20 at 12:34
2

Apart from checking group claims in ID token , you could also call microsoft graph api to get the groups that the user is a direct member of :

POST https://graph.microsoft.com/beta/me/getMemberGroups
Content-type: application/json
Content-length: 33

{
  "securityEnabledOnly": true
}

Or using Auzre AD Graph api :

POST https://graph.windows.net/myorganization/{resource_collection}/{resource_id}/getMemberGroups?api-version
Content-Type: application/json
{
  "securityEnabledOnly": false
}

For how an App Service Web, Mobile, or API app can be configured to call the Azure Active Directory Graph API on behalf of the logged-in user. You could refer to below document which show detail steps:

https://cgillum.tech/2016/03/25/app-service-auth-aad-graph-api/

After authentication, access token can be fetched directly from a built-in request header (x-ms-token-aad-access-token) and you could make a http request to call graph api to get the group information .

Nan Yu
  • 26,101
  • 9
  • 68
  • 148
  • We'll look into it. Thanks for all the info and the examples! – omg_me Jun 14 '17 at 10:30
  • @omg_me waiting for feedback , if the reply helps, you could mark it as answer which may help others who meet same problem . – Nan Yu Jun 15 '17 at 01:12