如何解决对 https://login.microsoftonline.com/{{TenantID}}/oauth2/token 进行 HTTP POST 调用时,访问令牌中缺少声明类型角色
伙计们!
我是 MS REST API 的新手,我正在尝试通过 Microsoft Graph API 访问 OneDrive。我有一个企业办公室 365 帐户,这是我迄今为止所做的:
-
完全按照此处提到的步骤创建了 Azure 应用:https://docs.microsoft.com/en-us/graph/toolkit/get-started/add-aad-app-registration。
-
添加了以下内容:https://docs.microsoft.com/en-us/onedrive/developer/rest-api/concepts/permissions_reference?view=odsp-graph-online 委托 API 权限。
附上截图如下:
首先,执行下面的 REST API 来获取访问令牌:
curl --location --request POST 'https://login.microsoftonline.com/<TenantId>/oauth2/token' \
--form 'grant_type=client_credentials' \
--form 'client_id=<ClientId>' \
--form 'client_secret=<ClientSecret>' \
--form 'resource=https://graph.microsoft.com/'
这将返回所需的访问令牌,HTTP响应如下所示:
{
"token_type": "Bearer","expires_in": "3599","ext_expires_in": "3599","expires_on": "1611896111","not_before": "1611893123","resource": "https://graph.microsoft.com/","access_token": "eyJ..."
}
现在,我正在尝试向以下端点 https://graph.microsoft.com/v1.0/users/<idOrUserPrincipalName>/drive
curl --location --request GET 'https://graph.microsoft.com/v1.0/users/<UserPrincipalName>/drive' \
--header 'Authorization: Bearer eyJ...'
我从服务器收到一个 HTTP 403 (Forbidden) 错误消息:
{
"error": {
"code": "AccessDenied","message": "Either scp or roles claim need to be present in the token.","innerError": {
"date": "2021-01-29T06:17:10","request-id": "c1a6a642-5cf6-40ed-bf55-75c1e3845357","client-request-id": "c1a6a642-5cf6-40ed-bf55-75c1e3845357"
}
}
}
仔细检查 JWT 令牌并对其进行解码后,我发现其中缺少角色声明。
{
"typ": "JWT","nonce": "HKO...","alg": "RS256","x5t": "nOo...","kid": "nOo..."
}.{
"aud": "https://graph.microsoft.com/","iss": "https://sts.windows.net/.../","iat": 1611893058,"nbf": 1611893058,"exp": 1611896958,"aio": "E2Z...","app_displayname": "OneDrive_API_Test","appid": "085...","appidacr": "1","idp": "https://sts.windows.net/.../","idtyp": "app","oid": "a5c...","rh": "0.AAA...","sub": "a5c...","tenant_region_scope": "NA","tid": "...","uti": "Bf...","ver": "1.0","xms_tcdt": 1394468532
}.[Signature]
理想情况下它应该是这样的:
{
"typ": "JWT","nonce": "toS...","kid": "nOo..."
}.{
"aud": "https://graph.microsoft.com","iat": 1611766631,"nbf": 1611766631,"exp": 1611770531,"aio": "E2J...","app_displayname": "myapp","appid": "a5c...","oid": "215...","rh": "0.AAAA...","roles": [
"User.ReadWrite.All","Files.ReadWrite.All","User.Read.All",],"sub": "215...","tid": "b39...","uti": "aKV...","xms_tcdt": 1394468532
}.[Signature]
如果我在应用程序中错误配置了某些内容,从而错过了导致 403 错误的角色声明,有人可以让我吗?任何指针都会非常有帮助
解决方法
如果您使用客户端凭据流,您将获得一个 APP 令牌,并且带有负载的请求看起来像这样。
POST https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token
请求正文:
client_id=535fb089-9ff3-47b6-9bfb-4f1264799865 &scope=https%3A%2F%2Fgraph.microsoft.com%2F.default &client_secret=qWgdYAmab0YSkuL1qKv5bPX &grant_type=client_credentials
在 Azure AD 应用注册中,您需要添加应用程序权限。在这里,当您调用 /users/userid/drive 时,您需要至少拥有 Files.Read.All
应用程序权限。
现在像使用此访问令牌一样使用 curl 调用 Graph API。你会得到数据
,@Shiva Keshav Varma 回答得很好。我来解释你的疑惑:
- 为什么您的令牌没有角色声明?
roles
声明仅显示应用程序权限,因为您已向应用程序授予委托权限,因此您的令牌中没有此类声明。
-
/me
端点和/users
端点有什么区别?
/me
端点通常需要用户交互。此时,应用代表以登录用户的身份执行请求。它要求您向应用程序授予委托权限,然后使用 auth code flow 获取访问令牌,并且该流程支持联合身份验证和 MFA。解析令牌时,您将看到 scp
声明。
/users
端点通常用于不需要用户交互的守护进程。它要求您向应用程序授予应用程序权限,然后使用 client credential flow 获取访问令牌。解析令牌时,您将看到 roles
声明。
最后总结一下:根据你的需求,如果只能授予委托权限,那么你应该使用auth code flow获取访问令牌,然后调用/me端点: https://graph.microsoft.com/v1.0/me/drive
。
使用身份验证代码流程获取令牌有两个步骤:
-
在浏览器中获取授权码,需要登录用户。
在浏览器中输入这个url获取授权码:
https://login.microsoftonline.com/xxxxxxx-bd27-40d5-8459-230ba2a757fb/oauth2/v2.0/authorize?
client_id=f212af58-f976-4bc5-be9d-7aexxxxxxxx
&response_type=code
&redirect_uri=https://localhost:4500/web/completeoauth/ms
&response_mode=fragment
&scope=Files.Read.All
&state=12345
- 使用授权码在 postman 中兑换访问令牌。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。