本文介绍了如何在服务/守护程序应用程序中为EWS托管API获取OAuth2访问令牌的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Azure VM上有一个Exchange Online环境和服务/daemin(无交互式用户)应用程序.服务使用EWS托管API处理任何租户用户邮箱中的电子邮件.现在,EWS客户端使用基本身份验证,据Microsoft称,EWS将不再支持EWS客户端访问Exchange Online.

I have an Exchange Online environment and service/daemin (no interactive user) application on the Azure VM. Service uses EWS managed API to work with emails in the mailbox of any tenant user. Now EWS client uses Basic authentication that, according to Microsoft, will become unsupported in EWS to access Exchange Online.

因此,我需要找到一种方法,以获取与EWS托管API一起使用的服务/守护程序应用程序的有效访问令牌.

So, I need to find a way to get valid access token for service/daemon application to use with EWS managed API.

以下文章对EWS应用程序进行身份验证,显示了将OAuth 2.0与EWS托管API结合使用的示例.该示例有效,但是它使用交互式方法来获取同意(登录表单出现,允许用户进行身份验证并授予所请求的应用程序许可),该方法不适用于服务/守护程序应用程序场景,因为没有交互式用户.

The following article shows an example of using OAuth 2.0 with EWS managed API. This example works, but it uses interactive method of getting consent (sign-in form appears allowing user authenticate themselves and grant requested permission to application) that is not suitable for service/daemon app scenario, because there is no interactive user.

对于服务/守护程序应用程序,我需要使用client credential身份验证流程.

For service/daemon application I need to use client credential authentication flow.

https://aad.portal.azure.com 门户上使用管理员帐户我注册了应用程序Azure Active Directory.为注册的应用程序添加了客户端机密.

Using admin account on https://aad.portal.azure.com portal I registered application with Azure Active Directory. Added client secret for registered application.

上述文章对EWS应用程序进行身份验证将https://outlook.office.com/EWS.AccessAsUser.All用作scope.但是我没有在门户网站上找到具有此类URL的许可.我在Office 365 Exchange Online> Application permissions> Mail下仅找到以下权限:

Aforementioned article uses https://outlook.office.com/EWS.AccessAsUser.All as a scope. But I did not find permission with such a URL on the portal. I found only the following permissions under Office 365 Exchange Online > Application permissions > Mail:

  1. https://outlook.office365.com/Mail.Read允许该应用在没有登录用户的情况下读取所有邮箱中的邮件
  2. https://outlook.office365.com/Mail.ReadWrite允许应用程序在没有登录用户的情况下创建,读取,更新和删除所有邮箱中的邮件.
  1. https://outlook.office365.com/Mail.Read Allows the app to read mail in all mailboxes without a signed-in user
  2. https://outlook.office365.com/Mail.ReadWrite Allows the app to create, read, update, and delete mail in all mailboxes without a signed-in user.

我添加了这两者,并为所有用户授予了管理员同意.

I added both of them and granted admin consent for all users.

出于测试目的和简便起见,我未使用任何身份验证库(ADAL,MSAL等).我使用Postman获取访问令牌,然后在调试中设置token变量(请参阅后面的代码段).

For testing purposes and simplicity I did not use any auth libraries (ADAL, MSAL etc.). I used Postman to get access token, then set token variable in debug (see code snippet later in the post).

我尝试了不同的端点来获取访问令牌.

I tried different endpoints to get acess token.

  1. OAuth 2.0令牌端点(v2)
    POST: https://login.microsoftonline.com/<TENANT_ID>/oauth2/v2.0/token
        grant_type=client_credentials
        client_id=*** 
        client_secret=***
        scope=https://outlook.office.com/EWS.AccessAsUser.All

发送此请求会产生以下错误响应:

Sending this request produces the following error response:

AADSTS70011:提供的请求必须包含作用域"输入参数.输入参数"scope"提供的值无效.范围 https://outlook.office.com/EWS.AccessAsUser.All 不是有效.

AADSTS70011: The provided request must include a 'scope' input parameter. The provided value for the input parameter 'scope' is not valid. The scope https://outlook.office.com/EWS.AccessAsUser.All is not valid.

我尝试将scope更改为https://outlook.office.com/.default.访问令牌已返回,但对于EWS似乎无效. EWS客户端使用以下值x-ms-diagnostics响应标头引发401错误:

I tried changing scope to https://outlook.office.com/.default. Access token was returned, but it appeared to be invalid for EWS. EWS client throws 401 error with the following value of x-ms-diagnostics response header:

2000008; reason =该令牌不包含任何权限,或者权限无法理解."; error_category ="invalid_grant"

  1. OAuth 2.0令牌端点(v1)
    POST: https://login.microsoftonline.com/<TENANT_ID>/oauth2/token
        grant_type=client_credentials
        client_id=*** 
        client_secret=***
        resource=https://outlook.office.com

访问令牌已返回,但对于EWS也似乎无效. EWS客户端抛出与x-ms-diagnostics响应标头相同的值的401错误,如#1中所述.

Access token was returned, but also appeared to be invalid for EWS. EWS client throws 401 error with the same value of x-ms-diagnostics response header as described ealier in #1.

这是我用来通过Postman获得的访问令牌测试EWS客户端的代码示例:

Here is code sample that I used to test EWS client with access token acquired in Postman:

var token = "...";
var client = new ExchangeService
{
    Url = new Uri("https://outlook.office365.com/EWS/Exchange.asmx"),
    Credentials = new OAuthCredentials(token),
    ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress,
                 "[email protected]"),

};
var folder = Folder.Bind(client, WellKnownFolderName.SentItems);

推荐答案

我们遇到了类似的问题:我们希望使用服务帐户连接到单个邮箱,并仅使用EWS API进行一些操作(例如,在GAL)和full_access_as_app似乎有点过分.幸运的是,有可能:

We had a similar problem: We wanted to use a Service Account to connect to a single mailbox and just doing some stuff with the EWS API (e.g. searching in the GAL) and the full_access_as_app seems like an overkill.Fortunately it is possible:

  1. 遵循正常的委托";步骤

并使用它通过用户名/密码获取令牌:

And use this to get a token via username/password:

...
var cred = new NetworkCredential("UserName", "Password");
var authResult = await pca.AcquireTokenByUsernamePassword(new string[] { "https://outlook.office.com/EWS.AccessAsUser.All" }, cred.UserName, cred.SecurePassword).ExecuteAsync();
...
  1. 要进行此项工作,您需要启用将处理程序作为公共客户端".在认证"下> 高级设置"因为这使用了资源所有者密码凭证流". (此 SO答案对我很有帮助! )
  1. To make this work you need to enable the "Treat application as public client" under "Authentication" > "Advanced settings" because this uses the "Resource owner password credential flow". (This SO answer helped me alot!)

通过该设置,我们可以使用传统"用户名/密码方式,但使用OAuth和EWS API.

With that setup we could use a "tradional" username/password way, but using OAuth and the EWS API.

这篇关于如何在服务/守护程序应用程序中为EWS托管API获取OAuth2访问令牌的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-16 11:18