Justin Kruskie
Justin Kruskie

Reputation: 422

Python Connect To Exchange /w Windows Auth

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 = '[email protected]'

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

Upvotes: 0

Views: 6250

Answers (3)

Alviy
Alviy

Reputation: 1

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 = '[email protected]'
    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()

Upvotes: 0

Justin Kruskie
Justin Kruskie

Reputation: 422

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;

Upvotes: 1

Biorez
Biorez

Reputation: 59

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 = '[email protected]'
    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')

Upvotes: 2

Related Questions