当使用oauth2 - garethp - php-ews连接到交换帐户时出现异常

3htmauhk  于 2022-12-21  发布在  PHP
关注(0)|答案(2)|浏览(141)

我使用garethp php-ews连接EWS使用oauth2.我正在接收访问令牌,但当它传递给邮件函数(getMailItems,getMailbox,getFolder ...等)以下致命错误"UnauthorizedException"显示.尝试了许多方法,但仍然相同.
致命错误:错误代码:453堆栈跟踪:\xampp\htdocs\exchange\vendor\garethp\php-ews\src\API\ExchangeWebServices中出现异常。浏览器:\xampp\htdocs\exchange\vendor\garethp\php-ews\src\API\交换网络服务. php(368):(301)返回上一页(301):服务器响应(空)#2 C:\xampp\htdocs\exchange\vendor\garethp\php-ews\src\API. php(362):调用('获取文件夹',数组)#3 C:\xampp\htdocs\exchange\vendor\garethp\php-ews\src\API. php(378):获取文件夹(数组)#4 C:\xampp\htdocs\exchange\vendor\garethp\php-ews\src\Mail\MailAPI. php(22):邮箱地址:C:\xampp\htdocs\exchange\vendor\garethp\php-ews\src\Mail\MailAPI. php(81):C:\xampp\htdocs\exchange\testSync. php(50)返回上一页第453行上的C:\xampp\htdocs\exchange\供应商\电子邮件\邮件API
下面是我传递的参数:

$tokenEndpoint = 'https://login.microsoftonline.com/common/oauth2/v2.0/token';
 $authorizationEndpoint = 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize';
 $clientId = '********';
 $clientSecret = '********';
 $redirectUri = 'http://localhost/testredirect.php';
 $scope = 'https://outlook.office.com/Mail.Read';

还尝试使用图形API:电子邮件地址='https://graph.microsoft.com/Mail.Read';
这是我拥有的API权限:

cqoc49vn

cqoc49vn1#

只有两个作用域可用于EWS的委派访问,即

  • EWS.AccessAsUser.All

仅适用于应用程序(客户端凭据流)

  • 完全访问作为应用程序

参见https://learn.microsoft.com/en-us/exchange/client-developer/exchange-web-services/how-to-authenticate-an-ews-application-by-using-oauth
EWS不支持Microsoft Graph支持的更严格的范围,这些范围是您引用的权限,从安全Angular 来看,这是您通常选择Graph而不是EWS的原因。

oo7oh9g9

oo7oh9g92#

我在使用帐户令牌连接到交换帐户时遇到了类似的问题。结果是,如果您使用令牌,请求后面的CURL需要具有以下附加参数:

$headers[] = sprintf("Authorization: Bearer %s", $this->token);
curl_setopt($this->ch, CURLOPT_HTTPAUTH, CURLAUTH_BEARER);

用于访问令牌的作用域和主机:

private const API_SCOPE = 'offline_access EWS.AccessAsUser.All EAS.AccessAsUser.All'; // Scope for Exchange Access
private const HOST_MICROSOFT_365 = 'outlook.office365.com'; // Host for Microsoft Connection

请求方法的完整示例如下所示:

public function __doRequest($request, $location, $action, $version, $one_way = 0){
    $headers = array(
        'Method: POST',
        'Connection: Keep-Alive',
        'User-Agent: PHP-SOAP-CURL',
        'Content-Type: text/xml; charset=utf-8',
        'SOAPAction: "'.$action.'"',
    );
    // Use Token for Authorization if set
    if(!empty($this->token)){
        $headers[] = sprintf("Authorization: Bearer %s", $this->token);
        curl_setopt($this->ch, CURLOPT_HTTPAUTH, CURLAUTH_BEARER);
    }else{ // User/Password Login
        curl_setopt($this->ch, CURLOPT_USERPWD, $this->user.':'.$this->password);
    }
    
    $this->ch = curl_init($location);

    curl_setopt($this->ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($this->ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($this->ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($this->ch, CURLOPT_POST, true );
    curl_setopt($this->ch, CURLOPT_POSTFIELDS, $request);
    curl_setopt($this->ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);

    curl_setopt($this->ch, CURLOPT_TIMEOUT, 60); //timeout in seconds
    curl_setopt($this->ch, CURLOPT_CONNECTTIMEOUT, 60);

    $response = curl_exec($this->ch);

    return $response;
}

我发现的大多数类都不包含承载授权,包括CURLAUTH_BEARER。我从jamesiarmes php-ews library中找到了一个fork,但它对我不起作用,所以我决定自己实现它。

相关问题