我正在尝试使用 SOAP 调用 EWS 并将旧的 Legacy Auth 代码替换为 OAuth。 但我总是收到“500 - 请求无效。”
我能够使用 c# 和 nugets“Microsoft.Identity.Client”和“Microsoft.Exchange.WebServices”获得令牌。 它可以列出我邮箱中的文件夹,我可以在这些文件夹中接收电子邮件。
但是我不能使用 C# 应用程序,因为我们的应用程序在 Access (VBA) 中,并且代码与 SOAP 的逻辑耦合。 5-10 年前制作应用程序的人不记得应用程序的逻辑,现在需要数据......
我可以使用的是来自这个小型概念证明的访问令牌。 因此,我尝试使用从 Microsoft.Identity.Client 获得的访问令牌并将其添加到 VBA 调用中,它似乎有效,因为我没有获得 401/403。 最初我有 401,因为我没有 Azure 的正确权限,但现在看起来没问题。
就像在 c# 代码中一样,我已经将模拟添加到 SOAP 请求以保持与 c# 代码相同。
这是 SOAP 请求
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
>
<soap:Header>
<t:ExchangeImpersonation>
<t:ConnectingSID>
<t:PrimarySmtpAddress>
[email protected]
</t:PrimarySmtpAddress>
</t:ConnectingSID>
</t:ExchangeImpersonation>
</soap:Header>
<soap:Body>
<GetFolder xmlns="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
<FolderShape>
<t:BaseShape>Default</t:BaseShape>
</FolderShape>
<FolderIds>
<t:DistinguishedFolderId Id="inbox"/>
</FolderIds>
</GetFolder>
</soap:Body>
</soap:Envelope>
服务不是很冗长,所以我不知道请求有什么问题!
<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<Action xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none" s:mustUnderstand="1">*</Action>
</s:Header>
<s:Body>
<s:Fault>
<faultcode xmlns:a="http://schemas.microsoft.com/exchange/services/2006/types">a:ErrorInvalidRequest</faultcode>
<faultstring xml:lang="en-US">The request is invalid.</faultstring>
<detail>
<e:ResponseCode xmlns:e="http://schemas.microsoft.com/exchange/services/2006/errors">ErrorInvalidRequest</e:ResponseCode>
<e:Message xmlns:e="http://schemas.microsoft.com/exchange/services/2006/errors">The request is invalid.</e:Message>
</detail>
</s:Fault>
</s:Body>
</s:Envelope>
为了测试,我在这里为 GetFolder 服务获取了 XML 的主要部分
https://learn.microsoft.com/en-us/exchange/client-developer/web-service-reference/getfolder-operation
我找到了要在此处添加的标题
https://learn.microsoft.com/en-us/exchange/client-developer/exchange-web-services/how-to-identify-the-account-to-impersonate
与c#请求相比,这个请求有什么问题?
他们使用相同的访问令牌,尝试执行相同的操作。 但是 SOAP 调用失败了。
如果您从 Microsoft 文档中提取示例,那么您的架构不正确,这就是问题所在。例如
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
>
和
<GetFolder xmlns="https://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
应该是
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
>
和
<GetFolder xmlns="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
EWS 中的 XML 模式始终是 http 而不是 https(请注意,这只是一个模式声明,它与所使用的实际协议无关),Microsoft 通过错误地更新其文档中的模式值在其 Exchange 文档中创建了一个问题。当我发现它们时,我已经修复了其中的一些,但是有很多问题。