64位Delphi应用Redemption GetFreeBusy调用Office365遇HTTP401错误
我开发了一个64位Delphi应用,使用64位Redemption 5.27组件获取Outlook的忙闲信息,环境如下:
- Office 365(64位Outlook客户端)
- Redemption 5.27(64位)
- Outlook已登录配置好的账号并运行
- 目标:获取当前用户的忙闲信息
故障现象
调用AddressEntry.GetFreeBusy时触发401未授权错误:
来自https://outlook.office365.com/autodiscover/autodiscover.xml的HTTP错误401
最小复现代码(Delphi)
RDOSession := CoRDOSession.Create; RDOSession.Logon('', '', False, False, 0, True); AddressEntry := RDOSession.AddressBook.ResolveName('email@company.com', False, 0); if AddressEntry <> nil then AddressEntry.GetFreeBusy(Today, 30, True);
ResolveName功能正常,可正确解析邮箱- 仅
GetFreeBusy调用抛出401错误
补充信息
- 同一机器、同一Outlook配置下,原生Outlook对象模型的
Recipient.FreeBusy可正常获取忙闲信息 - 仅Redemption的
GetFreeBusy路径出现问题 - 升级至Redemption 6.6后问题依旧
- 此前32位环境搭配32位Outlook时,相同代码运行正常
1. AddressEntry.GetFreeBusy是否支持Office 365/Exchange Online?
支持,但该方法依赖Exchange旧版忙闲查询协议(基于传统认证的Autodiscover+EWS流程),在Exchange Online强制现代认证的环境下容易触发权限问题,尤其是租户禁用NTLM等传统认证方式时。
2. 此场景下Redemption获取忙闲信息是否需要OAuth或特殊配置?
是。Exchange Online目前强制要求现代认证(OAuth 2.0),传统NTLM认证已逐步被禁用。Redemption的AddressEntry.GetFreeBusy默认可能尝试旧认证方式,导致401错误。
需完成以下配置:
- 在Azure AD注册应用,申请对应OAuth权限(如
Calendars.Read或Calendars.Read.Shared,根据是否需要访问其他用户忙闲信息选择) - 使用Redemption的OAuth登录API替代传统的
RDOSession.Logon
3. Redemption在Exchange Online中获取忙闲信息的推荐方案?
推荐以下两种方式:
方式一:OAuth登录后调用GetFreeBusy
先获取Azure OAuth令牌,再通过Redemption的OAuth登录接口初始化会话:
var OAuthToken: string; begin // 自行实现Azure AD OAuth令牌获取逻辑 OAuthToken := GetAzureADOAuthToken(); RDOSession := CoRDOSession.Create; RDOSession.LogonHostedExchangeMailbox('email@company.com', OAuthToken); AddressEntry := RDOSession.AddressBook.ResolveName('email@company.com', False, 0); if Assigned(AddressEntry) then AddressEntry.GetFreeBusy(Today, 30, True); end;
方式二:通过Redemption封装的EWS获取
利用RDOExchangeMailboxStore直接调用EWS的GetUserAvailability接口:
var Store: IRDOExchangeMailboxStore; RequestXML, ResponseXML: string; begin RDOSession := CoRDOSession.Create; RDOSession.LogonHostedExchangeMailbox('email@company.com', OAuthToken); Store := RDOSession.Stores.DefaultStore as IRDOExchangeMailboxStore; // 构造EWS GetUserAvailability请求XML RequestXML := '<soap:Envelope...>'; // 完整EWS请求内容 ResponseXML := Store.EWS.HttpPost('/ews/exchange.asmx', RequestXML); // 解析ResponseXML获取忙闲数据 end;
如果上述方式仍有问题,可直接调用Microsoft Graph API的/users/{id}/calendar/getSchedule接口,这是Exchange Online官方推荐的现代方案,Redemption可辅助处理令牌关联。
4. 能否保持32位应用实现忙闲信息获取?
可以,但需严格遵循位数匹配规则:
- 32位应用必须搭配32位Redemption和32位Outlook客户端,否则32位进程无法加载64位Outlook的MAPI组件,导致Redemption加载失败。
如果机器上已安装64位Outlook,有两种替代方案:
- 卸载64位Outlook,安装32位版本,搭配32位Redemption和32位应用
- 绕过本地Outlook,直接使用Redemption的
LogonHostedExchangeMailbox方法通过OAuth连接Exchange Online,这种方式无需本地安装Outlook,仅需32位Redemption组件即可让32位应用正常工作
内容的提问来源于stack exchange,提问作者jqbd

