I am using exchangelib for some end-to-end testing purposes of our mail system. Currently, when making a request, I am returned a 501.
# Tell exchangelib to use this adapter class instead of the default
BaseProtocol.HTTP_ADAPTER_CLS = NoVerifyHTTPAdapter
...
version = Version(api_version="Exchange2013_SP1", build=Build(15, 0, 847))
credentials = Credentials(username=outlook_profile['Username'], password=outlook_profile['Password'])
config = Configuration(server="<SERVICEURL>", credentials=credentials, auth_type=NTLM, version=version)
account = Account(primary_smtp_address="<USER>@<DOMAIN>", config=config, autodiscover=False, access_type=DELEGATE)
print(account.inbox.total_count)
Error:
WARNING:exchangelib.services.common:EWS https://<SERVICEURL>/EWS/Exchange.asmx, account <USER>@<DOMAIN>: Exception in _get_elements: Traceback (most recent call last):
File "C:\Python38\lib\site-packages\cached_property.py", line 69, in __get__
return obj_dict[name]
KeyError: 'root'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Python38\lib\site-packages\exchangelib\services\common.py", line 84, in _get_elements
response = self._get_response_xml(payload=payload)
File "C:\Python38\lib\site-packages\exchangelib\services\common.py", line 150, in _get_response_xml
r, session = post_ratelimited(
File "C:\Python38\lib\site-packages\exchangelib\util.py", line 770, in post_ratelimited
_raise_response_errors(r, protocol, log_msg, log_vals) # Always raises an exception
File "C:\Python38\lib\site-packages\exchangelib\util.py", line 851, in _raise_response_errors
raise TransportError(str('Unknown failure\n') + log_msg % log_vals)
exchangelib.errors.TransportError: Unknown failure
Retry: 0
Waited: 10
Timeout: 120
Session: 24770
Thread: 34952
Auth type: <requests_ntlm.requests_ntlm.HttpNtlmAuth object at 0x000001B2F697A310>
URL: https://<SERVICEURL>/EWS/Exchange.asmx
HTTP adapter: <exchangelib.protocol.NoVerifyHTTPAdapter object at 0x000001B2F697A0A0>
Allow redirects: False
Streaming: False
Response time: 0.0779999999795109
Status code: 501
Request headers: {'User-Agent': 'exchangelib/3.2.0 (python-requests/2.23.0)', 'Accept-Encoding': 'gzip, deflate', 'Accept': '*/*', 'Connection': 'Keep-Alive', 'Content-Type': 'text/xml; charset=utf-8', 'X-AnchorMailbox': '<USER>@<DOMAIN>', 'Content-Length': '1304', 'Authorization': 'NTLM <HASH>'}
Response headers: {'Date': 'Wed, 10 Jun 2020 21:38:09 GMT', 'X-Frame-Options': 'SAMEORIGIN', 'X-XSS-Protection': '1; mode=block', 'X-Content-Type-Options': 'nosniff', 'Connection': 'close', 'Content-Length': '87', 'Content-Type': 'text/html'}
Request data: b'<?xml version=\'1.0\' encoding=\'utf-8\'?>\n<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"><s:Header><t:RequestServerVersion Version="Exchange2013_SP1"/><t:ExchangeImpersonation><t:ConnectingSID><t:PrimarySmtpAddress><USER>@<DOMAIN></t:PrimarySmtpAddress></t:ConnectingSID></t:ExchangeImpersonation><t:TimeZoneContext><t:TimeZoneDefinition Id="UTC"/></t:TimeZoneContext></s:Header><s:Body><m:GetFolder><m:FolderShape><t:BaseShape>IdOnly</t:BaseShape><t:AdditionalProperties><t:FieldURI FieldURI="folder:FolderId"/><t:FieldURI FieldURI="folder:ChildFolderCount"/><t:FieldURI FieldURI="folder:EffectiveRights"/><t:FieldURI FieldURI="folder:FolderClass"/><t:FieldURI FieldURI="folder:DisplayName"/><t:FieldURI FieldURI="folder:ParentFolderId"/><t:FieldURI FieldURI="folder:TotalCount"/><t:FieldURI FieldURI="folder:UnreadCount"/></t:AdditionalProperties></m:FolderShape><m:FolderIds><t:DistinguishedFolderId Id="root"><t:Mailbox><t:EmailAddress><USER>@<DOMAIN></t:EmailAddress><t:RoutingType>SMTP</t:RoutingType><t:MailboxType>Mailbox</t:MailboxType></t:Mailbox></t:DistinguishedFolderId></m:FolderIds></m:GetFolder></s:Body></s:Envelope>'
Response data: b'<html><head><title>501 Invalid Request</title></head><body>Invalid Request: ??</body>\r\n'
However, when I connect (successfully) to my email system using a powershell EWS library, I can see that my Request body looks quite different, especially in terms of the soap:Envelope
tag:
POST https://<SERVICEURL>/EWS/Exchange.asmx HTTP/1.1
Content-Type: text/xml; charset=utf-8
Accept: text/xml
User-Agent: ExchangeServicesClient/15.00.0847.030
Accept-Encoding: gzip,deflate
Authorization: NTLM <HASH>
Host: <SERVICEURL>
Content-Length: 673
Expect: 100-continue
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<t:RequestServerVersion Version="Exchange2013_SP1" />
</soap:Header>
<soap:Body>
<m:GetFolder>
<m:FolderShape>
<t:BaseShape>AllProperties</t:BaseShape>
</m:FolderShape>
<m:FolderIds>
<t:DistinguishedFolderId Id="inbox" />
</m:FolderIds>
</m:GetFolder>
</soap:Body>
</soap:Envelope>
Also, if I instead target the autodiscover URL using exchangelib
, I can resolve the server correctly, but still get the same 501 error. So the credentials are correctly configured.
I can provide other information if needed. Any help would be greatly welcome.
Update 1
Instead of using the exchangelib
module, I was able to correctly authenticate and query the server by splitting up the requests:
session = requests.Session()
session.mount('https://', adapter)
session.headers.update({'Content-Type': 'text/xml; charset=utf-8', 'Expect': '100-continue'})
session.auth = HttpNtlmAuth(domain\\username, password)
session.post('https://SERVICEURL/EWS/Exchange.asmx', verify=False)
session.post('https://SERVICEURL/EWS/Exchange.asmx', data=body, verify=False)
Here, body
is the exact request body excahngelib
generated to query the inbox:
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">' \
<s:Header>
<t:RequestServerVersion Version="Exchange2013_SP1"/>
<t:TimeZoneContext>
<t:TimeZoneDefinition Id="UTC"/>
</t:TimeZoneContext>
</s:Header>
<s:Body>
<m:GetFolder>
<m:FolderShape>
<t:BaseShape>IdOnly</t:BaseShape>
<t:AdditionalProperties>
<t:FieldURI FieldURI="folder:FolderId"/>
<t:FieldURI FieldURI="folder:ChildFolderCount"/>
<t:FieldURI FieldURI="folder:EffectiveRights"/>
<t:FieldURI FieldURI="folder:FolderClass"/>
<t:FieldURI FieldURI="folder:DisplayName"/>
<t:FieldURI FieldURI="folder:ParentFolderId"/>
<t:FieldURI FieldURI="folder:TotalCount"/>
<t:FieldURI FieldURI="folder:UnreadCount"/>
</t:AdditionalProperties>
</m:FolderShape>
<m:FolderIds>
<t:DistinguishedFolderId Id="root">
<t:Mailbox>
<t:EmailAddress>username@domain</t:EmailAddress>
<t:RoutingType>SMTP</t:RoutingType>
<t:MailboxType>Mailbox</t:MailboxType>
</t:Mailbox>
</t:DistinguishedFolderId>
</m:FolderIds>
</m:GetFolder>
</s:Body>
</s:Envelope>