3
votes

Using a modified version of the Microsoft MSAL quickstart for node.js (original here), I successfully received an access token for the Azure Storage API using the implicit flow. The token included a groups claim, but one of the GUIDs in the claim does not seem to correlate with any group in the tenant. After removing the user from every group, the claim still contains that GUID (and as expected no others anymore):

  "groups": [
    "2cb3a5e8-4606-4407-9a97-616246393b5d"
  ],

A Google search for that GUID didn't result in any hits, so I'm assuming it is not a well-known GUID of some sort.

Why do I get this "unknown" GUID in a group claim?

The AAD tenant involved is a very small tenant, exclusively used by me for learning AAD and authentication. As such, it only contains a single group. The user involved is not a member of this single group.

I've looked at user page in the Azure Portal, which indeed shows that the user is "not a member of any groups". Azure CLI also show that the user isn't a member of any group:

$ az ad user get-member-groups --upn [email protected]
[]
$

The full list of groups in this tenant contains just a single group, and as you can see its ObjectID does not match the GUID I get in the claim:

$ az ad group list --query [].objectId --output tsv
b1cc46de-8ce9-4395-9c7c-e4e90b3c0036
$

I've also created another application registration and have it expose a dummy API. When using that dummy API as scope I again successfully receive an access token, but this one again includes the same unknown GUID as the single group claim.

Here are the hopefully relevant bits of the code.

As mentioned above, first I retrieved an access token for Azure Storage:

        var requestObj = {
            scopes: ["https://storage.azure.com/user_impersonation"]
        };

... but I get the exact same result with a dummy API:

        var requestObj = {
            scopes: ["api://7c7f72e9-d63e-44b6-badb-dd0e43df4cb1/user_impersonation"]
        };

This bit logs the user in:

        function signIn() {
            myMSALObj.loginPopup(requestObj).then(function (loginResponse) {
                //Successful login
                showWelcomeMessage();
                acquireTokenPopup();
            }).catch(function (error) {
                //Please check the console for errors
                console.log(error);
            });
        }

The token is acquired here. I'm aware that callMSGraph won't work here given the scope of the token. I get the token from the browser console log and decode it using jwt.ms.

        function acquireTokenPopup() {
            //Always start with acquireTokenSilent to obtain a token in the signed in user from cache
            myMSALObj.acquireTokenSilent(requestObj).then(function (tokenResponse) {
                console.log("Access Token from cache: " + JSON.stringify(tokenResponse.accessToken));
                callMSGraph(graphConfig.graphMeEndpoint, tokenResponse.accessToken, graphAPICallback);
            }).catch(function (error) {
                console.log(error);
                // Upon acquireTokenSilent failure (due to consent or interaction or login required ONLY)
                // Call acquireTokenPopup(popup window) 
                if (requiresInteraction(error.errorCode)) {
                    myMSALObj.acquireTokenPopup(requestObj).then(function (tokenResponse) {
                        console.log("Access Token after interaction: " + JSON.stringify(tokenResponse.accessToken));
                        callMSGraph(graphConfig.graphMeEndpoint, tokenResponse.accessToken, graphAPICallback);
                    }).catch(function (error) {
                        console.log(error);
                    });
                }
            });
        }
1

1 Answers

2
votes

You will also get directoryRole ids in the groups(got from the access token). You can request https://graph.microsoft.com/v1.0/me/memberOf to check the details. Here is the graph explorer.

enter image description here