Search code examples
azureauthenticationazure-active-directorymicrosoft-graph-apiazure-ad-msal

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. It contains 14 claims. aud, iss, tid etc...

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:

 
{
  "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

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. The application (client id/client secret) should have this permission. 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 


Solution

  • The Authorization header was misspelled.

    So "Access token is empty" probably actually meant not present or even "No authorization header in request".