使用simple-salesforce连接启用MFA的Salesforce报错,需触发MFA验证
解决simple-salesforce连接启用MFA的Salesforce认证问题
当你的Salesforce组织启用了多因素认证(MFA)和单点登录(SSO)时,传统的「用户名+密码+安全令牌」初始化方式会触发INVALID_SSO_GATEWAY_URL错误,因为这种认证方式已被SSO/MFA策略限制。要实现带MFA验证的连接,推荐使用设备验证码流(Device Authorization Flow),运行代码时会引导用户完成MFA验证。
步骤1:创建Salesforce连接应用(Connected App)
- 登录Salesforce后台,进入「设置」>「应用程序」>「应用程序管理器」>「新建连接应用」
- 填写基本信息(应用名称、API名称、联系人邮箱)
- 勾选「启用OAuth设置」,配置以下项:
- 回调URL:随便填一个有效值(比如
https://login.salesforce.com/services/oauth2/success,设备流不会实际用到,但必填) - 选中「设备验证码流」选项
- 在「选定的OAuth范围」中添加所需权限,至少包含
API和refresh_token(如需访问报表,可添加Analytics)
- 回调URL:随便填一个有效值(比如
- 保存应用,记录生成的「消费者密钥(Consumer Key)」和「消费者机密(Consumer Secret)」
步骤2:使用设备流认证的代码实现
import requests import time from simple_salesforce import Salesforce # 替换为你的连接应用信息和环境配置 CLIENT_ID = "你的Consumer Key" CLIENT_SECRET = "你的Consumer Secret" DOMAIN = "login" # 沙盒环境改为"test" TARGET_REPORT_ID = "你要访问的报表ID" # 1. 请求设备验证码 device_auth_url = f"https://{DOMAIN}.salesforce.com/services/oauth2/device" device_payload = { "client_id": CLIENT_ID, "client_secret": CLIENT_SECRET, "scope": "api refresh_token analytics" } device_resp = requests.post(device_auth_url, data=device_payload) device_info = device_resp.json() # 提示用户完成MFA验证 print(f"请打开链接: {device_info['verification_uri']}") print(f"输入验证码: {device_info['user_code']}") print("完成验证后按回车键继续...") input() # 2. 轮询获取访问令牌 token_url = f"https://{DOMAIN}.salesforce.com/services/oauth2/token" token_payload = { "grant_type": "urn:ietf:params:oauth:grant-type:device_code", "client_id": CLIENT_ID, "client_secret": CLIENT_SECRET, "device_code": device_info["device_code"] } while True: token_resp = requests.post(token_url, data=token_payload) token_data = token_resp.json() if token_resp.status_code == 200: break if token_data["error"] == "authorization_pending": time.sleep(device_info["interval"]) else: raise RuntimeError(f"认证失败: {token_data['error_description']}") # 3. 初始化Salesforce实例并访问报表 sf = Salesforce( instance_url=token_data["instance_url"], session_id=token_data["access_token"], refresh_token=token_data["refresh_token"] ) # 获取报表数据 report_result = sf.restful(f"/services/data/v59.0/analytics/reports/{TARGET_REPORT_ID}") print("报表数据获取成功:") print(report_result)
注意事项
- 连接应用的权限必须覆盖你的业务需求,比如访问报表需要
Analytics权限 - 若需长期使用会话,可保存
refresh_token,后续用其刷新access_token,无需重复触发MFA - 沙盒环境需将
DOMAIN变量改为test,对应沙盒登录域名
内容的提问来源于stack exchange,提问作者Vanitha Rosy VA
相关产品推荐
相关产品推荐

