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

时间:2019-06-26 00:44:30

标签: reactjs azure access-token msal azure-rest-api

我正在创建一个节点Web应用程序,该应用程序需要使用Azure REST API与某些Azure服务集成。我正在使用节点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/',但没有任何改变。

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

3 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

因此,我最终切换到ADAL库,看看是否会遇到相同的错误,但确实如此。但是我确实意识到资源请求URL不正确。 api-version不是可接受的版本。将其切换为2018-02-01后,请求返回200。