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

时间:2019-12-21 23:18:51

标签: typescript azure-active-directory microsoft-graph nestjs office365api

我想进入Microsoft Azure和Graph,并创建了一个简单的应用程序,该应用程序应将Graph API作为后台工作人员使用。 我目前只有一个模拟帐户,但我认为这没关系

我正在关注本教程

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

因为我不需要用户帐户。首先,我想使用Axios获取访问令牌。我使用NestJs,因此Axios被包裹在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:请求正文必须包含以下参数:   'grant_type'。\ r \ n跟踪ID:   038a3bf5-9396-4a4c-9dd6-b4608f265800 \ r \ n相关ID:   a1871bfc-af0d-470e-b604-f94ea4f10325 \ r \ n时间戳:2019-12-21   23:10:11Z“

我误解了文档吗?有什么问题或遗漏?预先感谢

2 个答案:

答案 0 :(得分:1)

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

正如您提到的doc所说,Content-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' } })

答案 1 :(得分:0)

获取访问令牌:

'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;
});