Reputation: 91
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
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.
Upvotes: 1