Azure AD - 应用程序令牌中缺少角色声明

3
当我尝试从Node.js后端服务器获取仅应用程序令牌(如此处所述)时,有时令牌中会缺少roles声明,这会导致Authorization_IdentityNotFoundAuthorization_RequestDenied错误。
我创建了一个函数来获取仅应用程序令牌,该函数将调用/token端点,直到检索到roles声明为止。
以下是该函数:
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;
}

这里是响应结果: 尝试: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
}

尝试: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
}

尝试: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
}

如响应所示,在第三次尝试中,我得到了预期的令牌(具有角色声明)。有没有任何原因导致第一次尝试不起作用?


嗨,Devang。这种情况是偶然发生的吗?还是在角色更新后出现的? - Jay Gong
嗨Jay,我还没有更新任何角色。我认为只有在管理员同意后应用程序立即尝试获取应用程序令牌时才会发生这种情况。看起来需要一些时间来在使用者的租户上创建服务主体对象。因此,在等待1-2分钟后,它才能按预期工作,但这并不是解决方案。 - Devang Vaishnav
这种情况也经常发生在我身上,第一次尝试通常会失败,第二次有时也会失败,但第三次总是能成功...哇... - Rixhers Ajazi
1个回答

1
在我的这一端,我尝试了管理同意和URL请求以获取管理员同意,并立即获得了仅应用程序的令牌,该令牌包含的角色。据我所知,更新权限可能需要时间才能生效。

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接