[英]Microsoft graph return "access token is empty"
I post this request:我发布了这个请求:
POST https://login.microsoftonline.com:443/{my-tennant-here}/oauth2/v2.0/token HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded
client_id={client id here}
&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default
&client_secret={client secret here}
&grant_type=client_credentials
This returns:这将返回:
{
"token_type": "Bearer",
"expires_in": 3599,
"ext_expires_in": 0,
"access_token": "eyJ0eX......
}
I have decoded the token using jwt.io and it definitely is not empty.我已经使用 jwt.io 解码了令牌,它绝对不是空的。 It contains 14 claims.
它包含 14 个声明。 aud, iss, tid etc...
aud, iss, tid 等...
I then use the access token in this request然后我在此请求中使用访问令牌
GET https://graph.microsoft.com/v1.0/users
Athorization: Bearer eyJ0eX...
I then get a 401 Unauthorized with this body:然后我得到一个 401 Unauthorized 这个机构:
{
"error": {
"code": "InvalidAuthenticationToken",
"message": "Access token is empty.",
"innerError": {
"request-id": "",
"date": "2018-08-14T15:41:44"
}
}
}
Expected result was a 200 Ok with a body containing a list of users预期结果是 200 Ok,正文包含用户列表
Does this simply mean that my app is Unauthorized, and the error message is just misleading (access token is empty)?这是否仅仅意味着我的应用程序未经授权,并且错误消息只是具有误导性(访问令牌为空)? Or have I done something wrong?
还是我做错了什么?
Update: I have noted that the although the token does contain claims it does not have a scope claim which seems a bit weird to me.更新:我注意到虽然令牌确实包含声明,但它没有范围声明,这对我来说似乎有点奇怪。 I would assume that it had the User.Read.All scope.
我认为它具有 User.Read.All 范围。 The application (client id/client secret) should have this permission.
应用程序(客户端 ID/客户端机密)应该具有此权限。 The claims in the token I receive have the following claims:
我收到的令牌中的声明具有以下声明:
aud: "https://graph.microsoft.com",
iss: "https://sts.windows.net/my tennant id",
iat: timestamp
nbf: timestamp
exp: timestamp
aio: looks like some kind of signature
app_displayname: "the expected app name"
appid: "the expected appid"
appidacr: "1"
idp: "https://sts.windows.net/...."
oid: "GUID"
sub: "GUID"
tid: "my tennant id"
uti: "value"
ver: 1.0
The Authorization header was misspelled.授权标头拼写错误。
So "Access token is empty" probably actually meant not present or even "No authorization header in request".所以“访问令牌为空”可能实际上意味着不存在甚至“请求中没有授权标头”。
One URL works while the other doesn't.一个 URL 有效,而另一个无效。
This works:这有效:
endpoint = "https://graph.microsoft.com/v1.0/reports/getOffice365ActiveUserDetail%28period%3D%27D7%27%29"
headers = {"Authorization": 'Bearer ' + access_token_gmc}
response = requests.get(endpoint, headers=headers)
But this one doesn't:但这个没有:
endpoint = "https://graph.microsoft.com/v1.0//users/myuserid/calendars"
headers = {"Authorization": 'Bearer ' + access_token_gmc}
response = requests.get(endpoint, headers=headers)
Please make sure the spellings are correct.请确保拼写正确。
For User.Read.All scope you can't have a user consent.对于 User.Read.All 范围,您不能获得用户同意。 It must be admin consent.
它必须是管理员同意。 It looks like you may have missed consenting your app using an admin account.
看起来您可能错过了使用管理员帐户同意您的应用程序。
To do this hit:要做到这一点:
GET https://login.microsoftonline.com/{tenant}/adminconsent
?client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&state=12345
&redirect_uri=http://localhost/myapp/permissions
Then get an access token and you should get the scopes the admin has consented users for.然后获取访问令牌,您应该获取管理员已同意用户的范围。
For me, my issue was that I had put a linebreak between the request url and the Authorization header, making it the body instead.对我来说,我的问题是我在请求 url 和 Authorization 标头之间放置了一个换行符,而是将其作为正文。
Wrong:错误的:
GET https://graph.microsoft.com/v1.0/users
Authorization: Bearer {{token}}
Correct:正确的:
GET https://graph.microsoft.com/v1.0/users
Authorization: Bearer {{token}}
A stupid mistake, but easy to overlook - if you get to this post you have probably done a silly mistake like OP (typo) or this.一个愚蠢的错误,但很容易被忽视——如果你看到这篇文章,你可能犯了一个愚蠢的错误,比如 OP(错字)或这个。 Look through your request syntax again!
再次查看您的请求语法!
I was getting the same error in my angular
application where I use MSAL
.我在使用
MSAL
angular
应用程序中遇到了同样的错误。
And it was all because of the wrong API scope
provided in the MSALAngularConfigFactory
.这完全是因为
MSALAngularConfigFactory
提供了错误的API scope
。 I was having the environment
as preceding.我的
environment
和前面一样。
export const environment = {
production: false,
clientId: 'clientid',
redirectUrl: 'http://localhost:4200',
graphApiUrl: 'https://graph.microsoft.com/v1.0',
graphGetUserImage: '/me/photo/$value',
protectedResourceMap: [
['http://localhost:65498/api', ['api.access']],
['https://graph.microsoft.com/beta', ['user.read']]
] as [string, string[]][],
authority: 'https://login.microsoftonline.com/organizations'
};
As you can see that I have given https://graph.microsoft.com/beta
in the protectedResourceMap
, which is wrong.如您所见,我在
protectedResourceMap
给出了https://graph.microsoft.com/beta
,这是错误的。 Instead, we should give https://graph.microsoft.com/v1.0/
.相反,我们应该提供
https://graph.microsoft.com/v1.0/
。 So here is the correct environment
.所以这里是正确的
environment
。
export const environment = {
production: false,
clientId: 'clientid',
redirectUrl: 'http://localhost:4200',
graphApiUrl: 'https://graph.microsoft.com/v1.0',
graphGetUserImage: '/me/photo/$value',
protectedResourceMap: [
['http://localhost:65498/api', ['api.access']],
['https://graph.microsoft.com/v1.0/', ['user.read']]
] as [string, string[]][],
authority: 'https://login.microsoftonline.com/organizations'
};
And I use it in the app.module.ts
as below.我在
app.module.ts
使用它,如下所示。
function MSALAngularConfigFactory(): MsalAngularConfiguration {
return {
popUp: false,
protectedResourceMap: environment.protectedResourceMap,
};
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.