2. Exchangelib3.2官方文档 —— 与Exchange服务器建立连接

建立连接

from exchangelib import DELEGATE, IMPERSONATION, Account, Credentials
#用户名格式为“域名\用户名形式”,有些Exchange服务器需要邮件地址形式`myusername@example.com`,例如Office365。另外,还支持UPN格式。
credentials = Credentials(username='MYWINDOMAIN\\myusername', password='topsecret')

#如果长时间在脚本中运行,可能需要启用容错。容错意味着,如果服务器不可用或响应错误消息,则大幅回退请求并休眠,直到某个阈值后放弃该请求。这样可以防止自动化脚本压垮故障或过载的服务器,并隐藏大型Exchange安装中经常发生的间歇性服务中断情况。
#帐户实例是您要连接到的Exchange服务器上的帐户,这可以是与认证关联的帐户,也可以是授予访问权限的任何其他帐户。例如,如果要访问共享文件夹,需要使用共享文件夹所属帐户的电子邮件地址创建帐户实例,然后通过此帐户访问共享文件夹。
#`primary_smtp_address`为分配给该账户的SMTP地址,如果启用自动发现,也可以使用别名。

my_account = Account(primary_smtp_address='myusername@example.com', credentials=credentials,
                     autodiscover=True, access_type=DELEGATE)
johns_account = Account(primary_smtp_address='john@example.com', credentials=credentials,
                        autodiscover=True, access_type=DELEGATE)
marys_account = Account(primary_smtp_address='mary@example.com', credentials=credentials,
                        autodiscover=True, access_type=DELEGATE)
still_marys_account = Account(primary_smtp_address='alias_for_mary@example.com',
                              credentials=credentials, autodiscover=True, access_type=DELEGATE)

# 在Account对象中,将保存所有的自动发现的数据:
my_account.ad_response

# 设置账户信息,然后启用自动发现,就可以查找到EWS的终结点
account = Account(primary_smtp_address='john@example.com', credentials=credentials,
                  autodiscover=True, access_type=DELEGATE)

# 如果认证拥有目标账户的模拟访问权限,则需要设置`access_type`为IMPERSONATION:
account = Account(primary_smtp_address='john@example.com', credentials=credentials,
                  autodiscover=True, access_type=IMPERSONATION)

优化连接

from exchangelib import DELEGATE, Account, Configuration, Credentials, NTLM, Build, Version
# 根据MSDN文档, 如果在使用模拟访问时指定帐户的UPN或SID,则可以避免每次请求都进行AD查找。 EWS不能提供这些信息,需要您通过其他方法来获取,例如进行一次AD查找:
account = Account(...)
account.identity.sid = 'S-my-sid'
account.identity.upn = 'john@subdomain.example.com'

# 如果服务器不支持自动发现,或者希望减少自动发现的开销,请使用配置对象来指定服务器位置:
credentials = Credentials(...)
config = Configuration(server='mail.example.com', credentials=credentials)
account = Account(primary_smtp_address='john@example.com', config=config,
                  autodiscover=False, access_type=DELEGATE)

# `exchangelib`将尝试猜测服务器版本和身份验证方法。如果你希望看到关于验证方法和版本的错误信息,或避免额外的网络流量,可以显式设置身份验证方法和版本:
version = Version(build=Build(15, 0, 12, 34))
config = Configuration(
    server='example.com', credentials=credentials, version=version, auth_type=NTLM
)

容错

from exchangelib import Account, FaultTolerance, Configuration, Credentials
from exchangelib.autodiscover import Autodiscovery
# 默认情况下,我们对服务器返回的所有异常都认为操作失败。如果要启用容错,请在配置中添加重试策略。然后我们将针对某些暂时性错误进行重试。默认情况下,我们会大幅后退,然后最多一个小时以后进行重试。
# 配置如下:
credentials = Credentials(...)
config = Configuration(retry_policy=FaultTolerance(max_wait=3600), credentials=credentials)
account = Account(primary_smtp_address='john@example.com', config=config)

# 自动发现功能也将使用此策略,但仅适用于最终的自动发现终结点。以下代码展示如何更改自动发现候选服务器的策略。
Autodiscovery.INITIAL_RETRY_POLICY = FaultTolerance(max_wait=30)

Kerberos和SSPI认证

from exchangelib import Configuration, GSSAPI, SSPI
# Kerberos and SSPI authentication are supported via the GSSAPI and SSPI auth types.
config = Configuration(auth_type=GSSAPI)
config = Configuration(auth_type=SSPI)

基于证书的认证 (CBA)

from exchangelib import Configuration, BaseProtocol, CBA, TLSClientAuth
TLSClientAuth.cert_file = '/path/to/client.pem'
BaseProtocol.HTTP_ADAPTER_CLS = TLSClientAuth
config = Configuration(auth_type=CBA)

OAuth身份认证

# OAuth认证使用`OAUTH2`和`OAuth2Credentials`来实现。对于访问多个帐户的应用程序,使用`OAuth2AuthorizationCodeCredentials`很有用.
from exchangelib import Configuration, OAuth2Credentials, OAuth2AuthorizationCodeCredentials, \
    Identity, OAUTH2
from oauthlib.oauth2 import OAuth2Token
credentials = OAuth2Credentials(client_id='MY_ID', client_secret='MY_SECRET', tenant_id='TENANT_ID')
# 使用OAuth2可能需要设置模拟访问标头。如果遇到有关模拟访问错误,请添加OAuth2认证帐户的有关信息:
credentials = OAuth2Credentials(..., identity=Identity(primary_smtp_address='svc_acct@example.com'))
credentials = OAuth2AuthorizationCodeCredentials(..., identity=Identity(upn='svc_acct@subdomain.example.com'))

credentials = OAuth2AuthorizationCodeCredentials(client_id='MY_ID', client_secret='MY_SECRET', authorization_code='AUTH_CODE')
credentials = OAuth2AuthorizationCodeCredentials(
    client_id='MY_ID', client_secret='MY_SECRET', access_token=OAuth2Token(access_token='EXISTING_TOKEN')
)
config = Configuration(credentials=credentials, auth_type=OAUTH2)

# 当应用程序使用exchangelib刷新访问令牌时可能希望存储刷新的令牌,这样用户就不必重新授权。 为此,需要继承OAuth2AuthorizationCodeCredentials类,然后重写on_token_auto_refreshed()方法:
class MyCredentials(OAuth2AuthorizationCodeCredentials):
    def on_token_auto_refreshed(self, access_token):
        store_it_somewhere(access_token)
        # Let the object update its internal state!
        super().on_token_auto_refreshed(access_token)

# 对于需要外部程序来提供访问令牌的应用, 需要继承OAuth2AuthorizationCodeCredentials重写refresh()方法:
class MyCredentials(OAuth2AuthorizationCodeCredentials):
    def refresh(self):
        self.access_token = ...

缓存自动发现结果

from exchangelib import Configuration, Credentials, Account, DELEGATE
# 如果您经常连接到同一帐户,则可以缓存自动发现结果以便以后跳过自动发现操作:
account = Account(...)
ews_url = account.protocol.service_endpoint
ews_auth_type = account.protocol.auth_type
primary_smtp_address = account.primary_smtp_address
# 保存版本信息是可选的,可以用来避免一次或多次往返以猜测正确的Exchange服务器版本。
version = account.version

# 现在您就可以创建一个不是用自动发现而使用结果缓存的账户:
credentials = Credentials(...)
config = Configuration(service_endpoint=ews_url, credentials=credentials, auth_type=ews_auth_type, version=version)
account = Account(
    primary_smtp_address=primary_smtp_address, 
    config=config, autodiscover=False, 
    access_type=DELEGATE,
)

# 自动发现操作需要很多时间,特别是找出特定电子邮件域所关联的自动发现服务器。因此,我们将在磁盘上创建一个可以长期保存的、每个用户的、包含先前成功的域->自动发现服务器查找结果的文件。此文件在进程之间共享,在程序退出时不会删除。 

# 如果域中的电子邮件自动发现操作失败,则该域的缓存项将自动删除。如果需要,可以完全清除整个缓存:
from exchangelib.autodiscover import clear_cache
clear_cache()

代理和自定义TLS验证

如果需要代理支持或自定义TLS验证,则可以使用自定义requests.adapters类,如该内容所述。
以下代码是根据连接的服务器使用不同自定义根证书的示例:

from urllib.parse import urlparse
import requests.adapters
from exchangelib.protocol import BaseProtocol

class RootCAAdapter(requests.adapters.HTTPAdapter):
    """使用硬编码指定根证书路径的一个HTTP"""
    def cert_verify(self, conn, url, verify, cert):
        cert_file = {
            'example.com': '/path/to/example.com.crt',
            'mail.internal': '/path/to/mail.internal.crt',
        }[urlparse(url).hostname]
        super().cert_verify(conn=conn, url=url, verify=cert_file, cert=cert)

# 设置exchangelib的新适配器类:
BaseProtocol.HTTP_ADAPTER_CLS = RootCAAdapter

以下代码是支持代理功能的示例:

import requests.adapters
from exchangelib.protocol import BaseProtocol

class ProxyAdapter(requests.adapters.HTTPAdapter):
    def send(self, *args, **kwargs):
        kwargs['proxies'] = {
            'http': 'http://10.0.0.1:1243',
            'https': 'http://10.0.0.1:4321',
        }
        return super().send(*args, **kwargs)

# 设置exchangelib的新适配器类:
BaseProtocol.HTTP_ADAPTER_CLS = ProxyAdapter

exchangelib提供了一个忽略TLS验证错误的适配器示例:

from exchangelib.protocol import BaseProtocol, NoVerifyHTTPAdapter

# 设置exchangelib的新适配器类:
BaseProtocol.HTTP_ADAPTER_CLS = NoVerifyHTTPAdapter

User-Agent

您可以自定义User-Agent参数。默认情况下,exchangelib的User-Agent参数为exchangelib/<version>(python-requests/<version>)

from exchangelib.protocol import BaseProtocol

# 设置exchangelib的新user-agent
BaseProtocol.USERAGENT = "Auto-Reply/0.1.0"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值