Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Authorize a client to browse Office365 Graph API

I am trying to develop a webapp to let a user browse his Active Directory contacts.
I have two accounts: one to register the application (developer account) and the other that would be the general user who have access to Office365 (user account).
I have set up a Javascript client following the Azure AD Graph API documentation.
By now, I am able to prompt the user to login and retrieve an access token, but when I try to make a request, I always get a 401 error.
I am pretty new to Azure, so I don't really understand if the problem is in my application configuration or in my code.
I am able to browse the Graph API explorer with my user account, so I don't think he's missing the authorization to access it.
I am really confused.

I try to add all the steps I am doing, hoping someone could point out the error.

Request 1:

Url: https://login.windows.net/{my tenant id or common (both are working) }/oauth2/authorize

Method: GET

Params:
redirect_uri   // my redirect url, the same I registered in my application. It is just a page that returns the content of the URL
client_id      // my client id
response_type  // code
state          // a random generated string, not required, but reccomanded
resource       // https://graph.windows.net

Response 1:

code           // A long string
state          // The string I sent in the request
session_state  // Another string

Request 2:

Url: https://login.windows.net/{my tenant id or common (both are working) }/oauth2/token

Method: POST

Params:
redirect_uri   // it won't be necessary, but in some post they reccomand to add it
client_id      // my client id
client_secret  // my client secret
code           // the code retrieved from Request 1
grant_type     // authorization_code
state          // a random generated string
resource       // https://graph.windows.net

Response 2:

token_type     // Bearer
access_token   // a long token
id_token       // exploring it with the JWT tool, shows it has the correct app id
refresh_token  // a long code
resource       // the same I sent in the request
scope          // Directory.Read UserProfile.Read
expires_in
expires_on
a couple of other irrelevant keys

Request 3:

Url: https://graph.windows.net/{the domain the logged account belong to}/contacts

Method: GET

Headers:
Authorization: Bearer {the access token retrieved from request 2}

Params:
api-version = 1.5 // The value suggested in the documentation.

Response 3:

{
    "odata.error": {
        "code": "Authentication_MissingOrMalformed",
        "message": {
            "lang": "en",
            "value": "Access Token missing or malformed."
        },
        "values": null
    }
}

This is the content of my Access Token:

{
 typ: "JWT",
 alg: "RS256",
 x5t: "foofoofoofoo"
}.
{
 aud: "https://graph.windows.net",
 iss: "https://sts.windows.net/<SOMEGUID>/",
 iat: 1418224761,
 nbf: 1418224761,
 exp: 1418228661,
 ver: "1.0",
 tid: "<SOMEGUID>",
 amr: [
  "pwd"
 ],
 idp: "https://sts.windows.net/<SOMEGUID>/",
 email: "[email protected]",
 unique_name: "[email protected]",
 sub: "barbarbarbar",
 altsecid: "<an-id>",
 family_name: "Last Name",
 given_name: "First Name",
 appid: "<MY APP ID>",
 appidacr: "1",
 scp: "Directory.Read UserProfile.Read",
 acr: "1"
}

Answer

So, it looks like user must have the "can consent" authorization to authenticate to his own active directory, and this can be provided just by the administrator.
I posted the same request on the MSDN forum and I got the same answer.
I want sincerely thank @Jason Johnston and @Dan Kershaw since this problem was driving me nut and I would never be able to sort it out without their help.
Unfortunately I can award the bounty to just one of them, so I decided to give it @Jason Johnston for the great patience he had in supporting me in this and another discussion.

like image 510
pasine Avatar asked Dec 08 '14 00:12

pasine


People also ask

How do I grant access to Microsoft Graph Explorer?

You can consent to permissions in Graph Explorer by choosing either the Modify permissions tab or the Select permissions option in the settings gear next to your profile when you're signed in. The Modify permissions tab lists all the permissions that you need to run the query in the address bar.

What is delegated permission in graph API?

Delegated permissions are used by apps that have a signed-in user present. For these apps, either the user or an administrator consents to the permissions that the app requests and the app can act as the signed-in user when making calls to Microsoft Graph.


1 Answers

I believe if you actually want to browse the Active Directory, and not just read the authenticated user's profile, you need administrator consent for a web app. See http://msdn.microsoft.com/en-us/library/azure/b08d91fa-6a64-4deb-92f4-f5857add9ed8#BKMK_Graph

If you already knew that, then maybe it's a problem with how you've registered your app or the token itself. Make sure you've selected the appropriate permissions per that link in your app registration. If those look right, then you can check the token. There's a handy little token parser here: http://jwt.calebb.net/. Just paste in the value of your token and it will show you the decoded JSON. Look at the scope or scp parameters.

{
  "typ": "JWT",
  "alg": "RS256",
  "x5t": "asdfsadfasdfsa"
}

{
  "aud": "https://graph.windows.net/",
  "iss": "https://sts.windows.net/<SOMEGUID>",
  "iat": 1418158549,
  "nbf": 1418158549,
  "exp": 1418162449,
  "ver": "1.0",
  "tid": "<SOMEGUID>",
  "amr": [
    "pwd"
  ],
  "oid": "<SOMEGUID>",
  "upn": "[email protected]",
  "unique_name": "[email protected]",
  "sub": "askdljalsdfs",
  "puid": "1003BFFD88937280",
  "family_name": "Administrator",
  "given_name": "MOD",
  "appid": "<YOUR APP ID>",
  "appidacr": "0",
  "scp": "Directory.Read user_impersonation UserProfile.Read",
  "acr": "1"
}
like image 183
Jason Johnston Avatar answered Oct 28 '22 21:10

Jason Johnston