Microsoft Graph API auth error: "Access token validation failure. Invalid audience"

Microsoft Graph API auth error: "Access token validation failure. Invalid audience"

好吧,过去两天我一直在解决这个错误,并且刚刚找到了解决方案。在我的搜索中,我没有找到解决我遇到的问题的单一答案(而是找到了多个最终将我指向解决方案的答案)。因此,这是我尝试向您解释“访问令牌验证失败。无效受众”错误的解决方案:

TLDR:

/**
 * Retrieve token for backend
 */
export const getToken = async (account): Promise<AuthenticationResult> => {
  return await msalInstance.acquireTokenSilent({
    scopes: [process.env.REACT_APP_API_SCOPE as string],
    redirectUri: current_url,
    account,
  });
};

/**
 * Retrieve token for Microsoft Graph API:
 */
export const getTokenForGraphApi = async (
  account
): Promise<AuthenticationResult> => {
  return await msalInstance.acquireTokenSilent({
    scopes: ["https://graph.microsoft.com/User.Read"],
    redirectUri: current_url,
    account,
  });
};

这是我如何发现的长篇故事:

我希望能够从 React 应用程序中查询 Microsoft Graph API

我已经让我组织的管理员设置了 Azure 门户,因此我们的应用程序注册具有 API 权限:

在 React 中,当我进行身份验证时,我使用了作用域:

scopes: [
    process.env.REACT_APP_API_SCOPE as string,
    "User.Read",
],

身份验证顺利,我获得了访问令牌。

访问令牌适用于我们的后端 API,但是当我尝试将访问令牌与 Microsoft Graph API 一起使用时,出现错误:

“访问令牌验证失败。受众无效”。

我阅读并搜索了论坛,并尝试使用 jwt.ms。

只有我们的 API 被列为“aud”,因此我怀疑我需要一个令牌来放置我们的 API 和“https://graph.microsoft.com”。

然后我尝试在我的 User.Read 范围之前加上“https://graph.microsoft.com”,所以它将是:

scopes: [
    process.env.REACT_APP_API_SCOPE as string,
    "https://graph.microsoft.com/User.Read"
],

但是验证失败,报错信息:

"AADSTS28000: 为输入参数范围提供的值无效,因为它包含多个资源。范围 api://{API-application-id}/a-scope https://graph.microsoft.com/User.Read openid 配置文件无效。"

在这里,我们的后端是一个资源,它有一个范围,“https://graph.microsoft.com”是另一个范围为“User.Read”的资源。

解决方案因此需要两个单独的访问令牌:一个范围为“https://graph.microsoft.com/User.Read”,您可以将其与图表一起使用 api,以及后端的另一个访问令牌:

/**
 * Retrieve token for backend
 */
export const getToken = async (account): Promise<AuthenticationResult> => {
  return await msalInstance.acquireTokenSilent({
    scopes: [process.env.REACT_APP_API_SCOPE as string],
    redirectUri: current_url,
    account,
  });
};

/**
 * Retrieve token for Microsoft Graph API:
 */
export const getTokenForGraphApi = async (
  account
): Promise<AuthenticationResult> => {
  return await msalInstance.acquireTokenSilent({
    scopes: ["https://graph.microsoft.com/User.Read"],
    redirectUri: current_url,
    account,
  });
};

错误消息:“访问令牌验证失败。受众无效”告诉您“AUD”(受众)在您用于 Microsoft Graph 的访问令牌上设置不正确 API。

您可以通过粘贴访问令牌来使用 https://jwt.ms/ 检查您的令牌。 (Microsoft 支持站点 jwt.ms 站点:https://docs.microsoft.com/en-us/azure/active-directory/develop/access-tokens

解决方案因此需要两个单独的访问令牌:一个范围为“https://graph.microsoft.com/User.Read”,您可以将其与 Microsoft 图形一起使用 api,以及后端的另一个访问令牌:

/**
 * Retrieve token for backend
 */
export const getToken = async (account): Promise<AuthenticationResult> => {
  return await msalInstance.acquireTokenSilent({
    scopes: [process.env.REACT_APP_API_SCOPE as string],
    redirectUri: current_url,
    account,
  });
};

/**
 * Retrieve token for Microsoft Graph API:
 */
export const getTokenForGraphApi = async (
  account
): Promise<AuthenticationResult> => {
  return await msalInstance.acquireTokenSilent({
    scopes: ["https://graph.microsoft.com/User.Read"],
    redirectUri: current_url,
    account,
  });
};

然后 AUD(受众)将在两个访问令牌上正确设置。