0

I am trying to create a script in Python 3.8 script that can connect to an Exchange server and retrieve emails from a mailbox. I am trying to authenticate with Exchange by using the currently authenticated user. I can authenticate fine if I use a username and password. (Trying to not store any passwords or anything, just use the currently authenticated user.)

I am using Python 3.8 and Exchangelib to connect Exchange but cannot figure out how to use Windows Auth(If possible).

Any help to try to accomplish this is appreciated.

Thanks

Example of what I'm trying to do:

from exchangelib import DELEGATE, IMPERSONATION, Account, Credentials, OAuth2Credentials, \
    OAuth2AuthorizationCodeCredentials, FaultTolerance, Configuration, NTLM, GSSAPI, SSPI, \
    OAUTH2, Build, Version
from exchangelib.autodiscover import AutodiscoverProtocol

exchange_email = 'mailboxIWantToAccess@domain.com'

account = Account(exchange_email, autodiscover=True)
# account = Account(exchange_email, credentials=credentials, autodiscover=True)

account.root.refresh()
account.public_folders_root.refresh()

print(account.root.tree())

Error I am getting:

Traceback (most recent call last):
  File "c:/Users/jk354/Documents/git.ourgitserver.com/client-info/script-ex.py", line 233, in <module>
    account = Account(exchange_email, autodiscover=True)
  File "C:\Users\jk354\AppData\Local\Programs\Python\Python38-32\lib\site-packages\exchangelib\account.py", line 85, in __init__
    self.ad_response, self.protocol = discover(
  File "C:\Users\jk354\AppData\Local\Programs\Python\Python38-32\lib\site-packages\exchangelib\autodiscover\discovery.py", line 23, in discover
    return Autodiscovery(
  File "C:\Users\jk354\AppData\Local\Programs\Python\Python38-32\lib\site-packages\exchangelib\autodiscover\discovery.py", line 88, in discover
    ad_protocol = autodiscover_cache[cache_key]
  File "C:\Users\jk354\AppData\Local\Programs\Python\Python38-32\lib\site-packages\exchangelib\autodiscover\cache.py", line 97, in __getitem__
    protocol = AutodiscoverProtocol(config=Configuration(
  File "C:\Users\jk354\AppData\Local\Programs\Python\Python38-32\lib\site-packages\exchangelib\protocol.py", line 73, in __init__
    self._session_pool = self._create_session_pool()
  File "C:\Users\jk354\AppData\Local\Programs\Python\Python38-32\lib\site-packages\exchangelib\protocol.py", line 160, in _create_session_pool
    session_pool.put(self.create_session(), block=False)
  File "C:\Users\jk354\AppData\Local\Programs\Python\Python38-32\lib\site-packages\exchangelib\protocol.py", line 233, in create_session
    with self.credentials.lock:
AttributeError: 'NoneType' object has no attribute 'lock'

https://github.com/ecederstrand/exchangelib

jkruskie
  • 412
  • 4
  • 15
  • 1
    What do you mean by Windows Authentication? NTLM? SSPI? Kerberos? exchangelib doesn't autodetect which authentication type you want to use, so you have to specify it explicitly with the `auth_type` argument to `Account`. See https://github.com/ecederstrand/exchangelib#setup-and-connecting – Erik Cederstrand Jan 30 '20 at 13:42
  • @ErikCederstrand I am not completely sure of which one I'd use. I have never done anything like this before I cannot find any good examples of what I am trying to do. I have tried to set the auth_type but however still achieve the same results. – jkruskie Jan 31 '20 at 13:11

3 Answers3

2

I'm using exchangelib in a Windows/Exchangeserver environment, this is my login code:

import getpass
from exchangelib import Configuration
from exchangelib import Credentials, Account

def login():
    email = 'user@domain.com'
    passwd = getpass.getpass(prompt='Password: ')
    user_credentials = Credentials(email, passwd)
    config = Configuration(server='exchangeserver',
                           credentials=user_credentials)
    account = Account(primary_smtp_address=email, config=config,
                           credentials=user_credentials, autodiscover=False) #maybe try =True
    return account

def main():
    user_account = authenticate()
    print(user_account.root.tree()) #printing the inbox

main()
input('Press enter to exit')
Biorez
  • 59
  • 8
  • I just updated my question as I noticed it was not very clear. I am able to successfully connect to exchange via username and password. However, I would like to try to connect WITHOUT using a password. I have a mailbox that my account has access to, I would like to be able to use the currently authenticated user, which is me, to connect to exchange. – jkruskie Feb 05 '20 at 18:51
1

Said screw it and switched to C#. I am using EWS Managed API.

https://learn.microsoft.com/en-us/exchange/client-developer/exchange-web-services/get-started-with-ews-managed-api-client-applications

I am able to connect to Exchange using the currently authenticated user by using this line:

service.UseDefaultCredentials = true;
jkruskie
  • 412
  • 4
  • 15
0

Finally working kerberos sample for me

from requests_kerberos import HTTPKerberosAuth
from exchangelib import DELEGATE, Account, Credentials, Configuration
import exchangelib.autodiscover


def auth_model(**kwargs):
    #get kerberos ticket 
    return HTTPKerberosAuth()


def connect(server, email, username, password=1):
    from exchangelib.protocol import BaseProtocol, NoVerifyHTTPAdapter
    # Care! Ignor Exchange self-signed SSL cert
    BaseProtocol.HTTP_ADAPTER_CLS = NoVerifyHTTPAdapter

    # fill Credential object with empty fields    
    creds = Credentials(
        username="",
        password=""
    )

    # add kerberos as GSSAPI auth_type
    exchangelib.transport.AUTH_TYPE_MAP["GSSAPI"] = auth_model

    # Create Config
    config = Configuration(server=server,credentials=creds, auth_type="GSSAPI")
    # return result
    return Account(primary_smtp_address=email, autodiscover=False, config = config, access_type=DELEGATE)

def main():
    # Connection details
    server = 'mail.domain.ex'
    email = 'person@domain.ex'
    username = 'domain\person'
    account = connect(server, email, username)

    for item in account.inbox.all().order_by('-datetime_received')[:100]:
        print(item.subject, item.sender, item.datetime_received)

main()
Alviy
  • 1
  • 1