php – 使用来自office365 oauth api的oauth令牌检索用户信息

我目前正在尝试使用Office365 REST API,为此,我需要使用OAuth2机制进行身份验证.到现在为止还挺好.

经过长时间的战斗,我终于设法获取了所述令牌,但我需要获取与令牌一起使用的用户信息(例如他的标识符,电子邮件,名称等).

使用沙盒,我需要这样的东西:

我已经尝试通过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"

但我所拥有的只有以下几点:

{"error":{"code":"-2147024891, System.UnauthorizedAccessException","message":"Access denied. You do not have permission to perform this action or access this resource."}}

获取所述OAuth令牌的请求基于这些参数(通过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']);

所以任何想法我怎么能得到用户信息(甚至是基本信息)?

谢谢

– 编辑

我想我明白了.似乎在https://outlook.office365.com/api/v1.0/me上的curl请求给出了一个带有MailboxGuid,Id,Alias和GivenName的简单数组:

curl https://outlook.office365.com/api/v1.0/me -X GET -H "Authorization: Bearer <my oauth token>"

给出以下内容(有时会暂停,有时不会……我想我必须努力,如果有人可以提出建议,请随意插入)

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

它不像沙盒返回的东西那么完整,但它应该给我我需要的东西……

但是……它有时会给我一个暂停,有时它会很好……大概是3/5的比例.任何的想法 ?谢谢

P.S:如果您需要知道我如何在azure上配置应用程序,请询问

最佳答案 您是否查看过令牌请求中返回的身份令牌?这可能包含您想要的所有信息,并且您已经拥有它,因此无需再发出第二个请求.

这是一个sample(除其他外)解析身份令牌以获取用户的显示名称.检查Office365Service.php中的getUserName函数:

// 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'];
}
点赞