在没有用户的情况下访问 Microsoft Graph - 正文中缺少 'grant_type'

access Microsoft Graph without user - missing 'grant_type' in body

我想进入 Microsoft Azure 和 Graph 并创建一个简单的应用程序,该应用程序应该将 Graph API 作为后台工作程序使用。 我现在只有一个模拟账户,但我认为这应该无关紧要

我正在学习本教程

https://docs.microsoft.com/en-us/graph/auth-v2-service#4-get-an-access-token

因为我不需要用户帐户。首先,我想使用 Axios. I use NestJs so Axios gets wrapped into a HTTP module.

获取访问令牌

到目前为止我所做的是请求设置

async getToken(): Promise<any> {
    const requestURL: string = 'https://login.microsoftonline.com/2c1714e1-1030-4da9-af5e-59630d7fe05f/oauth2/v2.0/token';

    const requestBody: object = {
        tenant: '2c1714e1-1030-4da9-af5e-59630d7fe05f',
        client_id: 'bec52b71-dc94-4577-9f8d-b8536ed0e73d',
        scope: 'https://graph.microsoft.com/.default',
        client_secret: 'OV/NkBIWH7d3G/BGyJQN3vxQA]fT6qK@',
        grant_type: 'client_credentials',
    };

    const requestConfiguration: object = {
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
        },
    };

    const observableResult: Observable<AxiosResponse<any>> = this.httpService.post(requestURL, requestBody, requestConfiguration);
    return observableResult.toPromise();
}

我收到 400 HTTP 错误,并显示以下消息:

"AADSTS900144: The request body must contain the following parameter: 'grant_type'.\r\nTrace ID: 038a3bf5-9396-4a4c-9dd6-b4608f265800\r\nCorrelation ID: a1871bfc-af0d-470e-b604-f94ea4f10325\r\nTimestamp: 2019-12-21 23:10:11Z"

我是不是误解了文档?有什么问题或缺失?提前致谢

您的数据完全正确(邮递员使用您的数据获取令牌)。但是您在发出 POST 请求时似乎出错了。

正如你所说的docContent-Type: application/x-www-form-urlencoded。所以你首先需要将 requestBody 转换为 URL 编码形式(key=value&key2=value2),而不是将其添加到 url 而是作为正文传递。这不是很明显的部分...

const requestURL: string = 'https://login.microsoftonline.com/2c1714e1-1030-4da9-af5e-59630d7fe05f/oauth2/v2.0/token';

const requestBody: object = {
    tenant: '2c1714e1-1030-4da9-af5e-59630d7fe05f',
    client_id: 'bec52b71-dc94-4577-9f8d-b8536ed0e73d',
    scope: 'https://graph.microsoft.com/.default',
    client_secret: 'OV/NkBIWH7d3G/BGyJQN3vxQA]fT6qK@',
    grant_type: 'client_credentials',
};

let request = Object.keys(requestBody).map(k => `${encodeURIComponent(k)}=${encodeURIComponent(requestBody[k])}`).join('&')
this.httpService.post(requestURL, request, { headers: { 'content-type': 'application/x-www-form-urlencoded' } })

获取访问令牌:

'use strict';

const axios = require('axios');
const qs = require('qs');

const accessTokenWithCredentials = (tenantId, clientId, clientSecret, resource) => {
    const data = {
        resource: resource,
        grant_type: 'client_credentials',

    };
    
    return axios({
        url: `https://login.windows.net/${tenantId}/oauth2/token`,
        method: "post",
        headers: { 'content-type': 'application/x-www-form-urlencoded' },
        auth: {
        username: clientId,
        password: clientSecret,
        },
        data:  qs.stringify(data)
    }).catch(error => {
        throw error;
    })
};

调用函数:

accessTokenWithCredentials(<tenantId>, <clientId>, <clientSecret>, 'https://graph.microsoft.com').then(response => {
    console.log(`Got access token`);
    const token = JSON.stringify(response.data.access_token);

    // do what you need to do

}).catch(err => {
     console.log("err " + err);
     throw err;
});