Devang Vaishnav
Devang Vaishnav

Reputation: 91

Azure AD - missing roles claim in app-only tokens

When I try to get app only token from nodejs backend server as described here, sometimes roles claim is missing in token, which leads to Authorization_IdentityNotFound or Authorization_RequestDenied error.

I created a function to get app only token, which will call /token endpoint until roles claim available in the retrieved token.

Here is the function:

async getApplicationTokenByTenant(
tenantId: string
): Promise<any> {
// post param
const params = {
    client_id: process.env.APP_ID,
    client_secret: process.env.APP_SECRET,
    grant_type: "client_credentials",
    scope: "https://graph.microsoft.com/.default"
};

let expectedRes = null;
let retryCount = 0;
// try to get token for max 4 times
while (!expectedRes && retryCount < 4) {
    console.log(`Try:${retryCount + 1}`);
    // call api
    const res = await fetch(
    `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`,
    {
        method: "POST",
        body: form(params),
        headers: {
        Accept: "application/json",
        "Content-Type":
            "application/x-www-form-urlencoded"
        }
    }
    );

    if (res.status !== 200) {
    const exception = await res.json();
    throw exception;
    }

    const response = await res.json();

    // Decode token
    const decodedToken = jws.decode(
    response.access_token
    ) as any;
    console.log("decodedToken");
    console.log(decodedToken);

    // check if "roles" exist in token
    if (!decodedToken.roles) {
    // if not wait for 3 seconds before retry
    await asyncWait(3000);
    retryCount++;
    } else {
    // got token having roles claim
    expectedRes = response;
    }
}
if (!expectedRes) {
    // did not get expected response after max retry
    throw new Error("Unable to get app token with roles");
}
return expectedRes;
}

And here is the response:

Try:1

{
  "aud": "https://graph.microsoft.com",
  "iss": "https://sts.windows.net/8xxxxxxx-6xxx-4xxx-8xxx-exxxxxxxxxxx/",
  "iat": 1544945058,
  "nbf": 1544945058,
  "exp": 1544948958,
  "aio": "42RgYAhLEHI9n/8xtk896Mfyc2cWAwA=",
  "app_displayname": "Dev Bot",
  "appid": "axxxxxxx-1xxx-4xxx-8bc6-bxxxxxxxxxxx",
  "appidacr": "1",
  "idp": "https://sts.windows.net/8xxxxxxx-6xxx-4xxx-8xxx-exxxxxxxxxxx/",
  "oid": "7xxxxxxx-6xxxx-4xxxx-a94f-cxxxxxxxxxxx",
  "sub": "7xxxxxxx-6xxxx-4xxxx-a94f-cxxxxxxxxxxx",
  "tid": "8xxxxxxx-6xxx-4xxx-8xxx-exxxxxxxxxxx",
  "uti": "qrPy3iOYp0emoAWhGI6oAA",
  "ver": "1.0",
  "xms_tcdt": 1540903121
}

Try:2

{
  "aud": "https://graph.microsoft.com",
  "iss": "https://sts.windows.net/8xxxxxxx-6xxx-4xxx-8xxx-exxxxxxxxxxx/",
  "iat": 1544945062,
  "nbf": 1544945062,
  "exp": 1544948962,
  "aio": "42RgYGBJfLUkMmfnZgFrhl8lThs0AQ==",
  "app_displayname": "Dev Bot",
  "appid": "axxxxxxx-1xxx-4xxx-8bc6-bxxxxxxxxxxx",
  "appidacr": "1",
  "idp": "https://sts.windows.net/8xxxxxxx-6xxx-4xxx-8xxx-exxxxxxxxxxx/",
  "oid": "7xxxxxxx-6xxxx-4xxxx-a94f-cxxxxxxxxxxx",
  "sub": "7xxxxxxx-6xxxx-4xxxx-a94f-cxxxxxxxxxxx",
  "tid": "8xxxxxxx-6xxx-4xxx-8xxx-exxxxxxxxxxx",
  "uti": "cGcY4Mdbyk6BkZlOjVSfAA",
  "ver": "1.0",
  "xms_tcdt": 1540903121
}

Try:3

{
  "aud": "https://graph.microsoft.com",
  "iss": "https://sts.windows.net/8xxxxxxx-6xxx-4xxx-8xxx-exxxxxxxxxxx/",
  "iat": 1544945070,
  "nbf": 1544945070,
  "exp": 1544948970,
  "aio": "42RgYFgQlXKE/SWHGP+115sO7D/yAwA=",
  "app_displayname": "Dev Bot",
  "appid": "axxxxxxx-1xxx-4xxx-8bc6-bxxxxxxxxxxx",
  "appidacr": "1",
  "idp": "https://sts.windows.net/8xxxxxxx-6xxx-4xxx-8xxx-exxxxxxxxxxx/",
  "oid": "7xxxxxxx-6xxxx-4xxxx-a94f-cxxxxxxxxxxx",
  "roles": [
    "Mail.ReadWrite",
    "Group.ReadWrite.All",
    "Files.ReadWrite.All",
    "Directory.Read.All",
    "Mail.Read"
  ],
  "sub": "7xxxxxxx-6xxxx-4xxxx-a94f-cxxxxxxxxxxx",
  "tid": "8xxxxxxx-6xxx-4xxx-8xxx-exxxxxxxxxxx",
  "uti": "CMiI-hcLlUCpqO6z70ukAA",
  "ver": "1.0",
  "xms_tcdt": 1540903121
}

As shown in response, I am getting expected token(having roles claim) on the third try. Any reason why this not working on the first try?

Upvotes: 3

Views: 1449

Answers (1)

SunnySun
SunnySun

Reputation: 1935

On my side, I tried the admin consent in the portal and the url request for admin consent, and then got app-only token immediately, the roles included in the token. As I know, update the permission may need time to work.

enter image description here

Upvotes: 1

Related Questions