用于交换模拟的 Azure AD 应用程序专用访问令牌
Azure AD app-only access tokens for exchange impersonation
我一直在关注 this resource 在 azure 上创建一个应用程序,该应用程序使用 azure 活动目录对自身进行身份验证。我们想使用这个与交换和 EWS 管理的身份验证交互的令牌 API 来模拟我们组织中的每个人,而无需他们登录。
我已经在 Azure 上向我们的组织注册了一个应用程序并授予了交换权限。创建证书并使用它设置我们的 azure 应用程序后,我可以通过以下代码使用 ADAL 获取仅限应用程序的访问令牌...
string authority = "https://login.windows.net/{tenant}/oauth2/authorize";
AuthenticationContext authenticationContext = new AuthenticationContext(authority, false);
var certPath = @"C:\path\to\cert\Cert.pfx";
var certfile = System.IO.File.OpenRead(certPath);
var certificateBytes = new byte[certfile.Length];
certfile.Read(certificateBytes, 0, (int)certfile.Length);
var cert = new X509Certificate2(
certificateBytes,
PRIVATE_KEY_PASSWORD,
X509KeyStorageFlags.Exportable |
X509KeyStorageFlags.MachineKeySet |
X509KeyStorageFlags.PersistKeySet);
ClientAssertionCertificate cac = new ClientAssertionCertificate(CLIENT_ID, cert);
var token = await authenticationContext.AcquireTokenAsync("https://outlook.office365.com/", cac);
有了这个令牌,与托管的 Ews 交互的代码 API 看起来像这样..
ServicePointManager.ServerCertificateValidationCallback = CertificateValidationCallBack;
_ExchangeService = new ExchangeService(ExchangeVersion.Exchange2013_SP1) {
Credentials = new OAuthCredentials(token),
Url = new Uri("https://outlook.office365.com/ews/exchange.asmx"),
ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.PrincipalName, "me@email.com"),
};
_ExchangeService.HttpHeaders.Add("X-AnchorMailbox", "me@email.com");
这似乎是通过托管 api 设置模拟的正确方法,尽管每个请求 returns 都是 401 未经授权的错误。
我的问题归结为,我是不是做错了什么?还是我需要做其他事情才能让我的应用程序访问交换服务器?
我关注的 article 确实提到了客户同意流程,但该部分的详细信息并不清楚。我能否在不提示他们同意的情况下向所有人授予我的应用程序权限。
我有一个代码几乎相同的工作解决方案。
我可以确定的唯一区别是身份验证上下文 URL,即 https://login.microsoftonline.com/*tenant-id*
。
还有,我用new ImpersonatedUserId(ConnectingIdType.SmtpAddress, email);
您确定 me@email.com 是完整的登录名,还是只是电子邮件地址?
它正在我这边工作,请首先确认您已设置 使用具有对所有邮箱的完全访问权限的 Exchange Web 服务 Office 365 Exchange Online 的应用程序权限 到受 Azure AD 保护的应用:
为了测试,您可以尝试以下代码:
ExchangeService exchangeService = new ExchangeService(ExchangeVersion.Exchange2013);
exchangeService.Url = new Uri("https://outlook.office365.com/ews/exchange.asmx");
exchangeService.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "sp.tech@o365e3w15.onmicrosoft.com");
exchangeService.HttpHeaders.Add("X-AnchorMailbox", "sp.tech@o365e3w15.onmicrosoft.com");
exchangeService.TraceEnabled = true;
exchangeService.TraceFlags = TraceFlags.All;
exchangeService.Credentials = new OAuthCredentials(token.AccessToken);
Folder newFolder = new Folder(exchangeService);
newFolder.DisplayName = "TestFolder";
newFolder.Save(WellKnownFolderName.Inbox);
这将在目标帐户的收件箱中创建一个新文件夹。
我一直在关注 this resource 在 azure 上创建一个应用程序,该应用程序使用 azure 活动目录对自身进行身份验证。我们想使用这个与交换和 EWS 管理的身份验证交互的令牌 API 来模拟我们组织中的每个人,而无需他们登录。
我已经在 Azure 上向我们的组织注册了一个应用程序并授予了交换权限。创建证书并使用它设置我们的 azure 应用程序后,我可以通过以下代码使用 ADAL 获取仅限应用程序的访问令牌...
string authority = "https://login.windows.net/{tenant}/oauth2/authorize";
AuthenticationContext authenticationContext = new AuthenticationContext(authority, false);
var certPath = @"C:\path\to\cert\Cert.pfx";
var certfile = System.IO.File.OpenRead(certPath);
var certificateBytes = new byte[certfile.Length];
certfile.Read(certificateBytes, 0, (int)certfile.Length);
var cert = new X509Certificate2(
certificateBytes,
PRIVATE_KEY_PASSWORD,
X509KeyStorageFlags.Exportable |
X509KeyStorageFlags.MachineKeySet |
X509KeyStorageFlags.PersistKeySet);
ClientAssertionCertificate cac = new ClientAssertionCertificate(CLIENT_ID, cert);
var token = await authenticationContext.AcquireTokenAsync("https://outlook.office365.com/", cac);
有了这个令牌,与托管的 Ews 交互的代码 API 看起来像这样..
ServicePointManager.ServerCertificateValidationCallback = CertificateValidationCallBack;
_ExchangeService = new ExchangeService(ExchangeVersion.Exchange2013_SP1) {
Credentials = new OAuthCredentials(token),
Url = new Uri("https://outlook.office365.com/ews/exchange.asmx"),
ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.PrincipalName, "me@email.com"),
};
_ExchangeService.HttpHeaders.Add("X-AnchorMailbox", "me@email.com");
这似乎是通过托管 api 设置模拟的正确方法,尽管每个请求 returns 都是 401 未经授权的错误。
我的问题归结为,我是不是做错了什么?还是我需要做其他事情才能让我的应用程序访问交换服务器?
我关注的 article 确实提到了客户同意流程,但该部分的详细信息并不清楚。我能否在不提示他们同意的情况下向所有人授予我的应用程序权限。
我有一个代码几乎相同的工作解决方案。
我可以确定的唯一区别是身份验证上下文 URL,即 https://login.microsoftonline.com/*tenant-id*
。
还有,我用new ImpersonatedUserId(ConnectingIdType.SmtpAddress, email);
您确定 me@email.com 是完整的登录名,还是只是电子邮件地址?
它正在我这边工作,请首先确认您已设置 使用具有对所有邮箱的完全访问权限的 Exchange Web 服务 Office 365 Exchange Online 的应用程序权限 到受 Azure AD 保护的应用:
ExchangeService exchangeService = new ExchangeService(ExchangeVersion.Exchange2013);
exchangeService.Url = new Uri("https://outlook.office365.com/ews/exchange.asmx");
exchangeService.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "sp.tech@o365e3w15.onmicrosoft.com");
exchangeService.HttpHeaders.Add("X-AnchorMailbox", "sp.tech@o365e3w15.onmicrosoft.com");
exchangeService.TraceEnabled = true;
exchangeService.TraceFlags = TraceFlags.All;
exchangeService.Credentials = new OAuthCredentials(token.AccessToken);
Folder newFolder = new Folder(exchangeService);
newFolder.DisplayName = "TestFolder";
newFolder.Save(WellKnownFolderName.Inbox);
这将在目标帐户的收件箱中创建一个新文件夹。