如何使用Python在AWS Lambda中访问启用MFA的SharePoint Excel文件
问题原因
报错AADSTS50076的核心原因是账号启用MFA后,Azure AD禁止使用普通的用户名密码方式直接获取访问令牌,原有基于用户凭证的认证逻辑失效。
推荐解决方案:使用Azure AD服务主体认证
该方案无需依赖用户账号,完全绕开MFA限制,适合AWS Lambda这类无人值守的自动化运行场景,配置步骤如下:
1. Azure AD端配置
- 登录Azure门户进入Azure Active Directory,打开「应用注册」页面,点击「新注册」,填写自定义应用名称,账户类型选择「仅当前组织目录中的账户」,无需填写重定向URI,完成注册。
- 注册完成后记录三个核心参数:客户端ID(Client ID)、租户ID(Tenant ID)。
- 进入「证书和密码」页面,点击「新建客户端密码」,设置有效期后保存生成的密码值(仅生成时可见,需及时存储)。
- 进入「API权限」页面,点击「添加权限」,选择SharePoint -> 应用程序权限,根据需求选择权限(如只读场景选
Sites.Read.All),权限添加完成后点击「授予管理员同意」完成权限授权。
2. Lambda侧配置
将客户端ID、租户ID、客户端密码三个参数加密后存入Lambda环境变量,和原有存储用户名密码的逻辑一致,使用KMS加密存储避免明文泄露。
3. 代码修改示例
from office365.runtime.auth.authentication_context import AuthenticationContext from office365.sharepoint.client_context import ClientContext from office365.sharepoint.files.file import File import xlrd import io import pandas as pd import urllib3 import boto3 from base64 import b64decode import os from datetime import date # 加密参数解密,和原有逻辑一致,对应三个新的环境变量 ENCRYPTED_CLIENT_ID = os.environ['client_id'] ENCRYPTED_CLIENT_SECRET = os.environ['client_secret'] ENCRYPTED_TENANT_ID = os.environ['tenant_id'] DECRYPTED_CLIENT_ID = boto3.client('kms').decrypt( CiphertextBlob=b64decode(ENCRYPTED_CLIENT_ID), EncryptionContext={'LambdaFunctionName': os.environ['AWS_LAMBDA_FUNCTION_NAME']} )['Plaintext'].decode('utf-8') DECRYPTED_CLIENT_SECRET = boto3.client('kms').decrypt( CiphertextBlob=b64decode(ENCRYPTED_CLIENT_SECRET), EncryptionContext={'LambdaFunctionName': os.environ['AWS_LAMBDA_FUNCTION_NAME']} )['Plaintext'].decode('utf-8') DECRYPTED_TENANT_ID = boto3.client('kms').decrypt( CiphertextBlob=b64decode(ENCRYPTED_TENANT_ID), EncryptionContext={'LambdaFunctionName': os.environ['AWS_LAMBDA_FUNCTION_NAME']} )['Plaintext'].decode('utf-8') def lambda_handler(event, context): http = urllib3.PoolManager() # 原有日期逻辑保持不变 today = date.today() d2 = today.strftime("%B %d") month = today.strftime("%B") # 替换为你实际的SharePoint站点根路径 site_url = "https://epiuse-my.sharepoint.com/personal/xxx" ctx_auth = AuthenticationContext(site_url) # 改用客户端凭证方式获取令牌 if ctx_auth.acquire_token_for_client(DECRYPTED_CLIENT_ID, DECRYPTED_CLIENT_SECRET, DECRYPTED_TENANT_ID): ctx = ClientContext(site_url, ctx_auth) # 替换为实际文件的相对路径 file_url = "/personal/202021.xlsx" response = File.open_binary(ctx, file_url) # 后续用pandas/xlrd处理Excel内容的逻辑保持不变
备选方案:使用应用密码
如果你的Azure AD租户允许用户创建应用密码,可以在账号的安全信息页面为该账号生成专门用于第三方应用登录的应用密码,替换原有代码中的普通账号密码即可使用,该方案无需修改其他代码,但安全性低于服务主体方案,且受租户策略限制。
内容的提问来源于stack exchange,提问作者ADARSH K
相关产品推荐
相关产品推荐

