Search code examples
c#vbams-accessoauth-2.0exchangewebservices

Exchange (EWS SOAP) Get Folder with Impersonation return 500 - Invalid Request


I'm trying to call EWS with SOAP and replace the old Legacy Auth code to OAuth. But i'm always getting a "500 - The request is invalid."

I'm able to get a Token with c# and the nugets "Microsoft.Identity.Client" and "Microsoft.Exchange.WebServices". It can list my folders in my mailbox and i can get email in those folders.

enter image description here

But i cannot use the C# app because our app is in Access (VBA) and the code is coupled to the logic of SOAP. The guy that has made the app like 5-10 years ago doesnt remember the logic of the app and the data is required now...

The thing i could use is the Access Token from this small proof of concept. So, i tried to use the access token i've got from Microsoft.Identity.Client and add it to the VBA call, it seems to work because i doesnt get a 401/403. Initialy i had 401 because i didnt have the right permission on Azure but it seems ok now.

Like in the c# code i've added the Impersonation to the SOAP request to stay the same as c# code.

Here is the SOAP request

<?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>

The service is not really verbose, so i dont know what's wrong in the request!

<?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>

To test, i've took the major part of the XML here for the GetFolder service

https://learn.microsoft.com/en-us/exchange/client-developer/web-service-reference/getfolder-operation

and i've found the header to add here

https://learn.microsoft.com/en-us/exchange/client-developer/exchange-web-services/how-to-identify-the-account-to-impersonate

What's wrong with this request compared to the c# request?

They use the same Access Token, try to do the same action. But the SOAP call is failling.


Solution

  • Your Schema is incorrect if you have pulled the example from the Microsoft documentation then that is the problem. eg

    <soap:Envelope 
        xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
        xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types"
    >
    

    and

        <GetFolder xmlns="https://schemas.microsoft.com/exchange/services/2006/messages"
               xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
    

    should be

    <soap:Envelope 
        xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
        xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"
    >
    

    and

        <GetFolder xmlns="http://schemas.microsoft.com/exchange/services/2006/messages"
               xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
    

    The XML schemas in EWS are always http not https (note this is just a schema declaration it has nothing to do with the actual protocol being used), Microsoft created an issue in their Exchange docs by wrongly updating the schema value in their docs. I've fixed a few of the them as I found them but there a many issues.