使用 OAuth 令牌验证和获取 EWS 数据
Posted
技术标签:
【中文标题】使用 OAuth 令牌验证和获取 EWS 数据【英文标题】:Authenticate and fetch EWS data using OAuth token 【发布时间】:2016-11-28 09:11:05 【问题描述】:我正在尝试使用 EWS-java-api 构建一个 android 应用程序,以使用适用于 android 的 Active Directory 身份验证库为 office365 用户获取带有 oAuth2 令牌的 EWS 数据。类似于本文中针对 .net 显示的内容。 下面是代码:
// Code to acquire token after registering the native application in Azure active directory
authenticationContext.acquireToken(<activity context>,
"<resource id: copied from the manifest file tag <resourceAppId> of Azure active directory after adding permission>",
"<Application id of the registered app in AAD>",
"<Application Redirect URI>", email, PromptBehavior.Always, "", AuthenticationCallback);
//We receive AuthenticationResult object containing authentication token in AuthenticationCallback onSuccess method and then call an async task to fetch EWS data
ExchangeService exchangeService = new ExchangeService();
exchangeService.setTraceEnabled(true);
exchangeService.getHttpHeaders().put("Authorization", "Bearer " + mAuthenticationResult.getAccessToken());
exchangeService.setUrl(URI.create("https://outlook.office365.com/EWS/Exchange.asmx"));
我能够获得 oAuth 令牌,但我无法接收交换数据,它在使用以下代码获取数据时给了我未经授权和被禁止的访问。
CalendarFolder calendarFolder = CalendarFolder.bind(service, WellKnownFolderName.Calendar);
findResults = calendarFolder.findAppointments(new CalendarView(startDate, endDate));
另外,我不确定我在 azure 门户中设置的配置。如果您能告诉如何设置 Azure AD 应用程序以通过 android 中的 oAuth 身份验证获取 EWS 数据,那就太好了。
编辑:
以下是我的访问令牌的声明:
这是我为访问令牌获取的 JSON。并使用此访问令牌,我得到的错误是访问日历文件夹时出现 401 未经授权的访问。
JSON:
typ: "JWT",
alg: "RS256",
x5t: "RrQqu9rydBVRWmcocuXUb20HGRM",
kid: "RrQqu9rydBVRWmcocuXUb20HGRM"
.
aud: "6ae5db95-0af3-45b6-afce-17851abc9d55",
iss: "https://sts.windows.net/06d03691-efd5-43c5-8ec9-81e57c75f63c/",
iat: 1480554267,
nbf: 1480554267,
exp: 1480558167,
acr: "1",
amr: [
"pwd"
],
appid: "410db643-4efc-4dac-8e6f-bbf05da561e1",
appidacr: "0",
e_exp: 10800,
family_name: "Dhingra",
given_name: "Surbhi",
ipaddr: "112.110.19.113",
name: "Surbhi Dhingra",
oid: "52c73152-0add-4e68-8d60-54c03a35a4b9",
platf: "1",
scp: "user_impersonation",
sub: "hUaeKxiMI-m7nNNo2c5kMYd501Blw5QQ9SNPnP1Ei_c",
tid: "06d03691-efd5-43c5-8ec9-81e57c75f63c",
unique_name: "surbhi.dhingra@<onmicrosoft domain>.com",
upn: "surbhi.dhingra@<onmicrosoft domain>.com",
ver: "1.0"
.
错误日志:microsoft.exchange.webservices.data.core.exception.service.remote.ServiceRequestException:请求失败。请求失败。远程服务器返回错误:(401)Unauthorized 在 microsoft.exchange.webservices.data.core.request.SimpleServiceRequestBase.internalExecute(SimpleServiceRequestBase.java:74) W/System.err:在 microsoft.exchange.webservices.data.core.request.MultiResponseServiceRequest.execute(MultiResponseServiceRequest.java:158) W/System.err:在 microsoft.exchange.webservices.data.core.ExchangeService.bindToFolder(ExchangeService.java:504) 在 microsoft.exchange.webservices.data.core.ExchangeService.bindToFolder(ExchangeService.java:523) 在 microsoft.exchange.webservices.data.core.service.folder.CalendarFolder.bind(CalendarFolder.java:60) 在 microsoft.exchange.webservices.data.core.service.folder.CalendarFolder.bind(CalendarFolder.java:108)
【问题讨论】:
您能否分享一下您收到的具体错误消息,以及出现在您的访问令牌中的声明?您可以使用这样的网站从原始访问令牌中提取声明:calebb.net 我最初的猜测是访问 EWS 数据确实需要在您的客户端应用程序上进行一定数量的设置,而您似乎还没有完成。我上面要求的信息应该有助于澄清这一点。 @ShawnTabrizi:感谢您的帮助,这是我获取访问令牌的 JSON。并使用此访问令牌,我得到的错误是访问日历文件夹时出现 401 未经授权的访问。 【参考方案1】:似乎有一个已回答的 SO 线程 EWS error message: "403: Forbidden - Not enough scopes" 与您的问题类似。
只有 Office 365 REST API 支持精细访问,例如“从所有邮箱读取和写入电子邮件”。对于 EWS,您需要“使用具有对所有邮箱的完全访问权限的 Exchange Web 服务”的权限。如果您在查找此权限时遇到问题,请告诉我们。
所以你需要在管理门户的Azure AD中移动到你的应用程序的CONFIGURE
选项卡,然后将Office 365 Exchange Online
权限添加到你的应用程序并启用Use Exchange Web Services with full access to all mailboxes
,最后保存你的配置,请看步骤和如下图。
在 Azure AD 中移动到应用程序的 CONFIGURE
选项卡
将Office 365 Exchange Online
权限添加到您的应用程序
启用Use Exchange Web Services with full access to all mailboxes
保存您的配置。
【讨论】:
我已经用错误日志编辑了我的答案,请仔细阅读它们。我无法访问 Azure 经典门户,但我正在添加新门户的权限。我正在生成 2 个应用程序,一个是 Native 和一个 web api,在 web api 应用程序中,我正在添加 office 365 在线交换,并启用了完全访问权限,如您的答案所示。我在我的本机应用程序权限中添加了这个 Web api 应用程序,并使用由此生成的相同资源 ID。不过,我收到了未经授权的错误。我也在 Web api 应用程序中生成一个密钥,我在我的代码中使用 SecretKeyFactory。【参考方案2】:感谢您提供访问令牌。 问题似乎是您为错误的受众(资源)获取了令牌。
如果您查看您的令牌,您会看到有一个“aud”声明,它定义了应该接受您的访问令牌的资源。
调用 Exchange 时,您应该有资源的令牌:“https://outlook.office.com”
您拥有的令牌似乎是针对特定 App ID 的,可能是您在自己的租户中拥有的应用之一。
请在此处查看我们公开的各种邮件 API 的参考信息: https://msdn.microsoft.com/en-us/office/office365/api/mail-rest-operations
并在此处查看我们的示例: https://dev.office.com/code-samples#?filters=exchange,outlook
我希望这会有所帮助!
【讨论】:
以上是关于使用 OAuth 令牌验证和获取 EWS 数据的主要内容,如果未能解决你的问题,请参考以下文章
使用 EWS 和 OAuth 2 的 Office 365 日历 API
Spring Security OAuth 2:如何在 oauth/token 请求后获取访问令牌和附加数据