Retrieving user information with a oauth token from the office365 oauth api

api, azure, oauth-2.0, office365, php

Solution

Have you looked at the identity token that comes back from your token request? This might have all the info you want, and you already have it so no need to make a second request.

Here's a sample that (among other things) parses the identity token to get the user's display name. Check the `getUserName` function in Office365Service.php:

// Parses an ID token returned from Azure to get the user's
// display name.
public static function getUserName($id_token) {
  $token_parts = explode(".", $id_token);

  // First part is header, which we ignore
  // Second part is JWT, which we want to parse
  error_log("getUserName found id token: ".$token_parts[1]);

  // First, in case it is url-encoded, fix the characters to be 
  // valid base64
  $encoded_token = str_replace('-', '+', $token_parts[1]);
  $encoded_token = str_replace('_', '/', $encoded_token);
  error_log("After char replace: ".$encoded_token);

  // Next, add padding if it is needed.
  switch (strlen($encoded_token) % 4){
    case 0:
      // No pad characters needed.
      error_log("No padding needed.");
      break;
    case 2:
      $encoded_token = $encoded_token."==";
      error_log("Added 2: ".$encoded_token);
      break;
    case 3:
      $encoded_token = $encoded_token."=";
      error_log("Added 1: ".$encoded_token);
      break;
    default:
      // Invalid base64 string!
      error_log("Invalid base64 string");
      return null;
  }

  $json_string = base64_decode($encoded_token);
  error_log("Decoded token: ".$json_string);
  $jwt = json_decode($json_string, true);
  error_log("Found user name: ".$jwt['name']);
  return $jwt['name'];
}

Problem

I'm currently trying to use the Office365 REST APIs, and for that, I need to auth using the OAuth2 mechanism. So far, so good. After a long battle, I finally managed to fetch the said tokens, but I need to fetch the user information (such as his identifier, email, name, ...) that goes with the token. Using the sandbox, I need something like that : I already tried to fetch the user information through the `api.office.com` api : ``` curl https://api.office.com/discovery/v1.0/me/services -H "Authorization: Bearer <oauth token>" -H "Accept: application/json;odata=verbose" ``` But all I have is the following : ``` {"error":{"code":"-2147024891, System.UnauthorizedAccessException","message":"Access denied. You do not have permission to perform this action or access this resource."}} ``` the request to get said OAuth token is based on these parameters (through the HWIOAuthBundle) : ``` <?php $config = ['authorization_url' => 'https://login.windows.net/%s/oauth2/authorize', 'infos_url' => 'https://outlook.office365.com/api/%s/me', 'access_token_url' => 'https://login.windows.net/%s/oauth2/token', 'application' => 'common', 'api_version' => 'v1.0', 'csrf' => true]; $config['access_token_url'] = sprintf($config['access_token_url'], $config['application']); $config['authorization_url'] = sprintf($config['authorization_url'], $config['application']); $config['infos_url'] = sprintf($config['infos_url'], $config['api_version']); ``` so any idea how could I get the user information (even the basic ones) ? Thanks -- edit I think I got it. It would seems that with a curl request on `https://outlook.office365.com/api/v1.0/me` gives a simplistic array with the MailboxGuid, Id, Alias and GivenName : ``` curl https://outlook.office365.com/api/v1.0/me -X GET -H "Authorization: Bearer <my oauth token>" ``` Gives the following (with sometimes a timeout, sometimes not... I guess I have to work on that, if anyone can have suggestions, feel free to barge in) ``` {"@odata.context":"https://outlook.office365.com/api/v1.0/$metadata#Me", "@odata.id":"https://outlook.office365.com/api/v1.0/Users('baptiste@wisembly.onmicrosoft.com')", "Id":"baptiste@wisembly.onmicrosoft.com", "DisplayName":"Baptiste Clavi\u00e9", "Alias":"baptiste", "MailboxGuid":"<snip>"} ``` It is not as complete as the thing returned by the sandbox, but it should gives me what I need... But... it sometimes gives me a timeout, sometimes it goes just fine... On a 3/5 ratio approximatively. Any idea ? Thanks P.S : if you need to know how I configured the app on azure, do ask

Original source