You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python的simple_salesforce库通过Microsoft凭证STS登录Salesforce?

问题分析与解决方案

你的Salesforce组织配置了Azure AD作为身份提供商的SAML单点登录(STS),因此标准的用户名+密码+安全令牌登录方式会被组织安全策略拦截,必须采用适配SSO场景的OAuth2认证流程。以下是具体的Python实现方案:

一、先修正Connected App配置

  • 回调URL设置:
    • 若用授权码流,本地开发可填http://localhost:8080/callback(需和代码中配置完全一致);
    • 若用设备码流,可填占位URL如https://login.salesforce.com/services/oauth2/success(无需实际服务)。
  • OAuth范围:至少勾选api(用于API调用)、web,需要全权限则选full。
  • 权限与IP限制:确保Connected App的网络访问策略允许你的开发机器IP,且权限配置正确。

二、Python实现方案

方案1:设备码流(适合无浏览器的服务器环境)

无需本地浏览器,通过设备码引导用户在任意终端完成SSO登录,脚本自动轮询获取令牌:

import requests
import time
from simple_salesforce import Salesforce

# 配置参数
CLIENT_ID = "你的Connected App Consumer Key"
INSTANCE_URL = "https://domain.my.salesforce.com"
AUTH_ENDPOINT = f"{INSTANCE_URL}/services/oauth2/device"
TOKEN_ENDPOINT = f"{INSTANCE_URL}/services/oauth2/token"

# 获取设备码
device_resp = requests.post(AUTH_ENDPOINT, data={
    "client_id": CLIENT_ID,
    "scope": "api full"
}).json()

print(f"请打开链接登录: {device_resp['verification_uri']}")
print(f"输入验证代码: {device_resp['user_code']}")

# 轮询等待令牌
interval = device_resp['interval']
device_code = device_resp['device_code']
token_resp = {}
while True:
    token_resp = requests.post(TOKEN_ENDPOINT, data={
        "grant_type": "urn:ietf:params:oauth:grant-type:device_code",
        "client_id": CLIENT_ID,
        "device_code": device_code
    }).json()
    
    if 'access_token' in token_resp:
        break
    elif token_resp['error'] == 'authorization_pending':
        time.sleep(interval)
    else:
        raise Exception(f"认证失败: {token_resp['error_description']}")

# 初始化Salesforce客户端并测试
sf = Salesforce(
    instance_url=token_resp['instance_url'],
    session_id=token_resp['access_token']
)
print(sf.query("SELECT Id, Name FROM Account LIMIT 1"))

方案2:授权码流(适合有本地浏览器的开发环境)

自动打开本地浏览器引导完成Azure AD SSO,通过临时本地服务接收回调并获取令牌:

from flask import Flask, request
from simple_salesforce import Salesforce
import webbrowser
import requests

app = Flask(__name__)

# 配置参数
CLIENT_ID = "你的Connected App Consumer Key"
CLIENT_SECRET = "你的Connected App Consumer Secret"
REDIRECT_URI = "http://localhost:8080/callback"
INSTANCE_URL = "https://domain.my.salesforce.com"
AUTH_URL = f"{INSTANCE_URL}/services/oauth2/authorize"
TOKEN_URL = f"{INSTANCE_URL}/services/oauth2/token"

@app.route('/callback')
def callback():
    code = request.args.get('code')
    # 交换令牌
    token_resp = requests.post(TOKEN_URL, data={
        "grant_type": "authorization_code",
        "client_id": CLIENT_ID,
        "client_secret": CLIENT_SECRET,
        "redirect_uri": REDIRECT_URI,
        "code": code
    }).json()
    
    # 初始化客户端并测试
    sf = Salesforce(
        instance_url=token_resp['instance_url'],
        session_id=token_resp['access_token']
    )
    print(sf.query("SELECT Id, Name FROM Account LIMIT 1"))
    return "登录成功,可关闭此页面"

if __name__ == '__main__':
    # 打开浏览器引导登录
    auth_url = f"{AUTH_URL}?response_type=code&client_id={CLIENT_ID}&redirect_uri={REDIRECT_URI}&scope=api full"
    webbrowser.open(auth_url)
    app.run(port=8080)

三、关键注意事项

  • 不要尝试用用户名+密码+安全令牌登录,你的组织已强制启用SSO,该方式会被拦截。
  • 回调URL必须与代码配置完全一致,包括协议(http/https)和端口。
  • 生产环境建议使用HTTPS回调URL,本地开发可使用http://localhost。

内容的提问来源于stack exchange,提问作者Shubham Khaladkar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 06:57:19