【问题标题】:Azure AD only generates invalid Access Token to use with Microsoft GraphAzure AD 仅生成用于 Microsoft Graph 的无效访问令牌
【发布时间】:2021-01-22 21:45:39
【问题描述】:

我已在 Azure Active Directory 中设置应用注册,以便我可以通过 Microsoft Graph 访问 Microsoft OneNote 笔记本/部分/页面。

它允许几乎每个 Microsoft 持有帐户登录,所以我使用 https://login.microsoftonline.com/common/oauth2/v2.0/authorize 作为我的授权端点,https://login.microsoftonline.com/common/oauth2/v2.0/token 作为我的令牌端点。 在应用注册中,我将 API 权限设置为:

  • Notes.Read.All
  • offline_access
  • openid
  • User.Read

我在我的重定向 URI 中添加了一个本地主机,它被列为“web”,以便我可以按照流程进行操作。

我遇到的问题是,当我最终收到我的 access_token 时,在将其用作承载令牌时收到错误:graph.microsoft.com/v1.0/me/onenote/notebooks

{
    "error": {
        "code": "40001",
        "message": "The request does not contain a valid authentication token. Detailed error information: {0}",
        "innerError": {
            "date": "2020-10-07T20:37:37",
            "request-id": "c8b0c20e-d096-4fcb-9e97-841b1626537c",
            "client-request-id": "a-uuid"
        }
    }
}

所以按照流程,我有这样的事情:

  1. 通过此网址进行身份验证

https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=99e1fc5a-bl4h-bl4h-bl4h-l0ng3rbl4h&redirect_uri=http://localhost/myapp&response_type=code&scope=https://graph.microsoft.com/User.Readopenid offline_access https://graph.microsoft.com/Notes.Read.All&state=abc&response_mode=query

我有点不确定我是否在这里使用了正确的范围变量。我希望能够访问所有用户的 OneNote 笔记本/分区/页面并阅读他们的个人资料并离线执行操作,

  1. 当我的用户成功通过身份验证时,代码会被重定向到这里:

http://localhost/myapp?code=M.R3_BL2.15c2b73a-486c-c0f6-95c1-8432603aa7a4&state=abc

  1. 我从查询字符串中提取code 并进行如下POST:
curl --location --request POST 'https://login.microsoftonline.com/common/oauth2/v2.0/token' \
--form 'code=M.R3_BL2.15c2b73a-486c-c0f6-95c1-8432603aa7a4' \
--form 'grant_type=authorization_code' \
--form 'client_id=99e1fc5a-bl4h-bl4h-bl4h-l0ng3rbl4h' \
--form 'scope=https://graph.microsoft.com/User.Read openid offline_access https://graph.microsoft.com/Notes.Read.All' \
--form 'client_secret=shhhhASecret'

现在这将返回一个 JSON 格式的 access_token。

{
    "token_type": "Bearer",
    "scope": "https://graph.microsoft.com/User.Read openid https://graph.microsoft.com/Notes.Read.All",
    "expires_in": 3600,
    "ext_expires_in": 3600,
    "access_token": "EwCQA8l6BAAUO9chh8cJscQLmU+longstring",
    "refresh_token": "M.R3_BL2.CecNbvRse*longstring",
    "id_token": "eyJ0eXAiOiJKlongstring"
}

但是,如上所述,此访问令牌似乎无法让我访问 Microsoft Graph。我尝试了不同的范围变体以在我的请求中使用,但似乎都没有生成正确的访问令牌。

我用于从 node.js 调用 Microsoft Graph 的代码

const http = require('https');

class OneNote {
constructor(bearer) {
        this.bearer = bearer;
        this.HTTP_CODES = {
            OK: 200,
            Unauthorized: 401
        };
    }

async getNotebooks() {
        const options = this._getOptions();
        options.path += 'notebooks';
        return this._requestData(options)
            .catch((err) => {
                throw err;
            });
    }

_getOptions() {
        return {
            method: 'GET',
            hostname: 'graph.microsoft.com',
            path: '/v1.0/me/onenote/',
            headers: {
                'Authorization': `Bearer ${this.bearer}`
            }
        }
    }

    async _requestData(options) {
        console.log(options)
        return new Promise((resolve, reject) => {
            const req = http.request(options, (res) => {
                let data = '';
                res.on('data', (d) => {
                    data += d;
                });
                if (res.statusCode === this.HTTP_CODES.Unauthorized) {
                    res.on('end', () => {
                        reject(data);
                    });
                } else {
                    res.on('end', () => {
                        resolve(data);
                    });
                }
            });

            req.on('error', (err) => {
                reject(err);
            });
            req.end();
        });
    }
}

【问题讨论】:

  • 看起来这个访问令牌没问题。请使用您的访问令牌分享您致电https://graph.microsoft.com/v1.0/me/onenote/notebooks 的请求。并在jwt.io 中解码您的访问令牌,看看它是否具有正确的audscope
  • 请问您是否隐藏了真实的code?还是您的code“M.R3_BL2.15c2b73a-486c-c0f6-95c1-8432603aa7a4”?访问令牌看起来与普通令牌不同。您使用的是什么类型的帐户? O365 账户还是微软个人账户?
  • @AllenWu 我正在使用我的个人 Microsoft 帐户。当我使用 Microsoft Graph Explorer 并将访问令牌复制到 jwt.io 时,它会给出错误并且不显示任何数据,更不用说我自己生成的数据了?这是我最新的来自授权的真实代码:M.R3_BL2.db535519-c869-054d-df35-64369bfb86fb.

标签: oauth-2.0 jwt azure-active-directory microsoft-graph-api jwt-auth


【解决方案1】:

您可能使用了错误的权限(范围)。

基于Permissions for listing notebooks,个人微软账户所需权限为Notes.Create, Notes.Read, Notes.ReadWrite

这里不需要Notes.Read.All

所以请在范围内添加Notes.Read委派权限来解决这个问题。

【讨论】:

  • 那行得通...如果我删除 Notes.Read.All 会阻止学校或工作用户阅读他们的笔记?因此,拥有这两种权限并允许个人、学校和工作帐户访问他们所有的笔记本/部分/页面并没有什么坏处,对吧?
  • @Jarede 是的。如果您删除 Notes.Read.All,它不应该适用于工作帐户。但您可以在 Azure AD 应用程序中同时分配 Notes.ReadNotes.Read.All 委派权限,并在范围内使用 https://graph.microsoft.com/.default。它将允许个人、学校和工作帐户。我认为没有坏处。这是它的工作方式之一。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-31
  • 2021-01-21
相关资源
最近更新 更多