簡體   English   中英

Microsoft 圖返回“訪問令牌為空”

[英]Microsoft graph return "access token is empty"

我發布了這個請求:


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

這將返回:


{
  "token_type": "Bearer",
  "expires_in": 3599,
  "ext_expires_in": 0,
  "access_token": "eyJ0eX......
}

我已經使用 jwt.io 解碼了令牌,它絕對不是空的。 它包含 14 個聲明。 aud, iss, tid 等...

然后我在此請求中使用訪問令牌


GET https://graph.microsoft.com/v1.0/users
Athorization: Bearer eyJ0eX...

然后我得到一個 401 Unauthorized 這個機構:


{
  "error": {
    "code": "InvalidAuthenticationToken",
    "message": "Access token is empty.",
    "innerError": {
      "request-id": "",
      "date": "2018-08-14T15:41:44"
    }
  }
}

預期結果是 200 Ok,正文包含用戶列表

這是否僅僅意味着我的應用程序未經授權,並且錯誤消息只是具有誤導性(訪問令牌為空)? 還是我做錯了什么?

更新:我注意到雖然令牌確實包含聲明,但它沒有范圍聲明,這對我來說似乎有點奇怪。 我認為它具有 User.Read.All 范圍。 應用程序(客戶端 ID/客戶端機密)應該具有此權限。 我收到的令牌中的聲明具有以下聲明:


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 

授權標頭拼寫錯誤。

所以“訪問令牌為空”可能實際上意味着不存在甚至“請求中沒有授權標頭”。

一個 URL 有效,而另一個無效。

這有效:

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)

但這個沒有:

endpoint = "https://graph.microsoft.com/v1.0//users/myuserid/calendars"
headers = {"Authorization": 'Bearer ' + access_token_gmc}
response = requests.get(endpoint, headers=headers)  

請確保拼寫正確。

對於 User.Read.All 范圍,您不能獲得用戶同意。 它必須是管理員同意。 看起來您可能錯過了使用管理員帳戶同意您的應用程序。

要做到這一點:

GET https://login.microsoftonline.com/{tenant}/adminconsent
?client_id=6731de76-14a6-49ae-97bc-6eba6914391e
&state=12345
&redirect_uri=http://localhost/myapp/permissions

然后獲取訪問令牌,您應該獲取管理員已同意用戶的范圍。

對我來說,我的問題是我在請求 url 和 Authorization 標頭之間放置了一個換行符,而是將其作為正文。

錯誤的:

GET https://graph.microsoft.com/v1.0/users

Authorization: Bearer {{token}}

正確的:

GET https://graph.microsoft.com/v1.0/users
Authorization: Bearer {{token}}

一個愚蠢的錯誤,但很容易被忽視——如果你看到這篇文章,你可能犯了一個愚蠢的錯誤,比如 OP(錯字)或這個。 再次查看您的請求語法!

我在使用MSAL angular應用程序中遇到了同樣的錯誤。

在此處輸入圖片說明

這完全是因為MSALAngularConfigFactory提供了錯誤的API scope 我的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'
};

如您所見,我在protectedResourceMap給出了https://graph.microsoft.com/beta ,這是錯誤的。 相反,我們應該提供https://graph.microsoft.com/v1.0/ 所以這里是正確的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'
};

我在app.module.ts使用它,如下所示。

function MSALAngularConfigFactory(): MsalAngularConfiguration {
  return {
    popUp: false,
    protectedResourceMap: environment.protectedResourceMap,
  };
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM