Microsoft Graph API 身份验证错误:“访问令牌验证失败。无效的受众”

Posted

技术标签:

【中文标题】Microsoft Graph API 身份验证错误:“访问令牌验证失败。无效的受众”【英文标题】:Microsoft Graph API auth error: "Access token validation failure. Invalid audience" 【发布时间】:2021-03-21 02:21:53 【问题描述】:

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

TLDR:

检查在https://jwt.ms/ 上使用 MSAL 进行身份验证时收到的访问令牌中是否将“https://graph.microsoft.com”列为 AUD(受众)(Microsoft 位于网站 jwt.ms 的背后来源:@987654322 @)。就我而言,列出了后端 API 范围,而不是“https://graph.microsoft.com”。这就是为什么 Microsoft graph api 检查访问令牌时“观众”无效的原因。 解决方案是请求两个不同的访问令牌,一个用于后端范围,一个用于https://graph.microsoft.com/User.Read 范围:
/**
 * 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 权限:

后端 API 权限 微软图形 “User.Read” “User.ReadBasic.All”。

在 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,
  );
;

【问题讨论】:

【参考方案1】:

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

您可以通过粘贴访问令牌使用https://jwt.ms/ 检查您的令牌。 (微软后台jwt.ms网站:https://docs.microsoft.com/en-us/azure/active-directory/develop/access-tokens)

因此,解决方案是需要两个单独的访问令牌:一个范围为“https://graph.microsoft.com/User.Read”,您可以与 Microsoft graph 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 身份验证错误:“访问令牌验证失败。无效的受众”的主要内容,如果未能解决你的问题,请参考以下文章

获取 Microsoft Graph API 的有效访问令牌

Microsoft Graph 和自定义 API 的访问令牌

Microsoft Graph Toolkit 新版发布 - 新的 Microsoft Teams 身份验证提供程序和文件上传功能

Microsoft Graph Toolkit 新版发布 - 新的 Microsoft Teams 身份验证提供程序和文件上传功能

具有 Azure AD 身份验证的 Azure 函数 - 允许的令牌受众不适用于 Microsoft Graph

Microsoft Graph PowerShell v2 发布公开预览版 - 新的身份验证方法,支持解除阻塞场景,脚本迁移工具