使用exchangelib连接O365时出现Invalid credentials认证错误
问题根源
你配置的是Delegated permissions(委托权限),但代码中错误使用了Application权限的认证方式,导致凭证无效。exchangelib中不同权限类型对应不同的OAuth2认证类:
- Delegated权限:需要用户参与授权(如设备流、授权码流),对应
OAuth2DeviceCredentials或OAuth2AuthorizationCodeCredentials - Application权限:无用户交互,用客户端凭据,对应
OAuth2Credentials(需额外配置服务主体名称)
解决方案
方案1:使用Delegated权限(需用户交互授权)
适合桌面/本地脚本,通过设备流让用户登录授权:
from exchangelib import Account, OAuth2DeviceCredentials, DELEGATE # 初始化设备流凭据 credentials = OAuth2DeviceCredentials( client_id='你的客户端ID', tenant_id='你的租户ID' ) # 运行时会打印授权链接和验证码,需用户在浏览器打开链接输入验证码完成登录 account = Account( primary_smtp_address='xxx@yyy.com', credentials=credentials, autodiscover=True, access_type=DELEGATE ) # 测试访问收件箱 for item in account.inbox.all().order_by("-datetime_received")[:10]: print(item.subject, item.sender, item.datetime_received)
方案2:使用Application权限(无用户交互)
如果需要脚本自动运行,无需用户参与,需修改应用注册配置:
- 在Azure AD应用注册中,将权限改为Application权限,添加
EWS.AccessAsApp权限并提交管理员同意 - 使用以下代码:
from exchangelib import Account, OAuth2Credentials, IMPERSONATION credentials = OAuth2Credentials( client_id='你的客户端ID', client_secret='你的客户端密钥', tenant_id='你的租户ID', # 必须指定Office365的服务主体名称 service_principal_name='https://outlook.office365.com/' ) # Application权限必须使用IMPERSONATION类型 account = Account( primary_smtp_address='xxx@yyy.com', credentials=credentials, autodiscover=True, access_type=IMPERSONATION ) # 测试访问收件箱 for item in account.inbox.all().order_by("-datetime_received")[:10]: print(item.subject, item.sender, item.datetime_received)
关键检查项
- 确认应用注册中的权限类型(Delegated/Application)与代码中的认证方式匹配
- 确保权限已获得管理员同意(租户范围应用必须由管理员批准)
- 核对client_id、client_secret、tenant_id无拼写错误或多余空格
- 如果用Delegated权限,需确保用户登录的账号有权访问目标邮箱
内容的提问来源于stack exchange,提问作者Sachin
相关产品推荐
相关产品推荐

