如何修复“访问令牌来自错误的受众或资源。”尝试使用 MSAL 令牌访问 Azure 的 REST api 时

Posted

技术标签:

【中文标题】如何修复“访问令牌来自错误的受众或资源。”尝试使用 MSAL 令牌访问 Azure 的 REST api 时【英文标题】:How do I fix 'The access token is from wrong audience or resource.' when trying to access Azure's REST api using an MSAL token 【发布时间】:2019-11-07 20:43:30 【问题描述】:

我正在创建一个需要使用 Azure REST API 与一些 azure 服务集成的节点 Web 应用。我正在使用节点 MSAL 库进行用户登录并检索访问令牌以向 Azure REST api 发出请求。我能够成功登录用户并检索访问令牌。但是,当我尝试向 Azure 的 REST api 发出请求时,我收到一个 401 错误,上面写着 error="invalid_token", error_description="The access token is from wrong audience or resource."

网络应用程序本身是使用Node LTSReact v16.8.6 构建的。它已部署在 Azure 中并在活动目录中注册。 我正在使用MSAL v1.0.1 登录用户并在用户登陆登录页面时检索令牌。

login.js

import React,  Component  from 'react';
import * as Msal from 'msal';

let msalConfig = 
  auth: 
    clientId: process.env.REACT_APP_CLIENT_ID,
    authority: `https://login.microsoftonline.com/process.env.REACT_APP_TENANT_ID'`,
    navigateToLoginRequestUrl: false,
    redirect_uri: 'http://localhost:3000/newEntry',
    resource: 'https://management.azure.com/'
  ,
  cache: 
    cacheLocation: "localStorage",
    storeAuthStateInCookie: true
  
;

var msalInstance = new Msal.UserAgentApplication(msalConfig);

var tokenRequest = 
  scopes: ['https://management.azure.com/']


class Login extends Component 
  constructor(props) 
    super(props);
    this.state = 
      response: null,
    ;
  

  componentWillMount() 
    // prevent login loop by checking for logged in user and then acquire a token if logged in
    if (!msalInstance.getAccount() && !msalInstance.isCallback(window.location.hash)) 
      this.login();
     else 
      msalInstance.acquireTokenSilent(tokenRequest)
        .then(res => localStorage.setItem('access_token', res.accessToken))
        .catch(err => console.error(err))
    
  

  login = () =>   
    msalInstance.handleRedirectCallback((error, response) => 
      if (error) console.error(error);
      console.log(response);
    )
    msalInstance.loginRedirect(tokenRequest);
  

  render() 
    return (
      <div>
        <h2>Login</h2>
      </div>
    )
  


export default Login;

我已成功返回访问令牌并将其放入本地存储中。

在一个单独的页面上,我正在从本地存储中检索 MSAL 访问令牌,并使用它来发出请求以检索与我的 Azure 订阅关联的所有资源。

  componentWillMount() 
    let token = localStorage.getItem('access_token');
    let url = 'https://management.azure.com/subscriptions/process.env.REACT_APP_SUBSCRIPTION_ID/resource?api-version=2018-02-14'

    fetch(url, 
      method: 'GET',
      headers: 
        'Authorization': `Bearer $token`
      
    )
    .then(response => console.log(response))
    .catch(err => console.error(err));
  

我怀疑我收到了错误,因为登录请求发送的资源值与令牌请求发送的范围值之间存在一些差异。

我已尝试根据Azure: The access token has been obtained from wrong audience or resource 将资源值更改为'resource': 'https://management.core.windows.net/',但这并没有改变任何东西。

我还尝试了各种范围,包括 https://management.azure.com/user_impersonationhttps://management.azure.com//user_impersonation 按照这个示例 Access Token do not include access for API with MSAL

【问题讨论】:

【参考方案1】:

get 方法是默认的,问题可能出在'Authorization': `Bearer $token`。 有时人们使用不同的规则,例如'Authorization': token'Token': `Bearer $token`。 我看到一些使用'S-token': token 的API。试试看。我认为这是因为令牌确实到达了那里。

【讨论】:

从请求中删除 Bearer 会导致 unsupported authentication scheme 并将 Authorization 更改为 TokenS-token 导致 Authorization header is missing 错误,因此它看起来像授权标头格式是正确的。 ssl 怎么样,可能需要一些代理设置为 unrejectedAutheriazed = false?【参考方案2】:

您正在使用 msal,因此您的 msalConfig 中不需要 resource 参数。你可以删除它。

将范围更改为scopes: ['https://management.azure.com/.default']

【讨论】:

【参考方案3】:

所以我最终切换到 ADAL 库,看看是否会遇到同样的错误,我确实遇到了。然而,我确实意识到资源请求 URL 不正确。 api-version 不是公认的版本。一旦我将其切换到2018-02-01,请求就会返回 200。

【讨论】:

以上是关于如何修复“访问令牌来自错误的受众或资源。”尝试使用 MSAL 令牌访问 Azure 的 REST api 时的主要内容,如果未能解决你的问题,请参考以下文章

如何修复错误“错误:命令错误退出状态 1:python。”尝试使用 pip 安装 fitz 模块时?

尝试在 Next.js 10 项目中使用它时,如何修复模块联合错误? [复制]

尝试执行 POST 方法时如何修复此 Sequelize Database 错误?

尝试使用 websockets 从 FastAPI 获取实时数据流时如何修复错误(不支持的升级请求。)?

SwiftUI:如何使用边距 10 修复前导和尾随

尝试运行 Grunt 但出现错误并且不知道如何修复它们