如何通过Python应用无密码使用Entra ID连接Azure SQL数据库
解决Azure SQL Database无密码认证的可行方案
方案1:修复MSAL令牌获取报错,实现静默认证
你遇到的AADSTS650057/AADSTS100040错误,大多是资源ID配置错误或应用权限未正确设置导致的,按以下步骤调整:
- 确认目标资源:Azure SQL的正确资源标识是
https://database.windows.net/,请求令牌时scope需设为https://database.windows.net/.default,不要用数据库实例的具体ID - 配置Azure AD应用注册:在Azure门户创建应用注册,添加Azure SQL Database的对应权限(如
SqlDB.DataReader/SqlDB.DataWriter),并完成管理员同意 - 实现静默令牌缓存:首次运行需一次交互登录,后续MSAL会自动复用缓存令牌,无需重复输入密码。示例代码:
import msal import pyodbc # 替换为你的配置参数 CLIENT_ID = "你的应用注册ID" TENANT_ID = "你的租户ID" SCOPE = ["https://database.windows.net/.default"] DB_SERVER = "xxx.database.windows.net" DB_NAME = "你的数据库名" app = msal.PublicClientApplication(CLIENT_ID, authority=f"https://login.microsoftonline.com/{TENANT_ID}") # 优先从缓存取令牌 result = app.acquire_token_silent(SCOPE, account=None) if not result: # 首次登录需交互,之后缓存生效 result = app.acquire_token_interactive(SCOPE) if "access_token" in result: conn_str = f"DRIVER={{ODBC Driver 18 for SQL Server}};SERVER={DB_SERVER};DATABASE={DB_NAME};ENCRYPT=yes;Authentication=ActiveDirectoryAccessToken;UID=任意值;PWD={result['access_token']}" conn = pyodbc.connect(conn_str) # 执行数据库操作 else: print(result.get("error_description", "令牌获取失败"))
方案2:使用用户分配托管身份(本地开发首选)
适合本地开发环境,依赖Azure CLI完成一次认证后长期复用:
- 在Azure门户创建用户分配托管身份,将其添加为Azure SQL的数据库用户,并赋予对应权限(如
db_datareader) - 本地安装Azure CLI,执行
az login完成一次身份认证 - 使用Azure Identity库自动获取令牌,示例代码:
from azure.identity import DefaultAzureCredential import pyodbc DB_SERVER = "xxx.database.windows.net" DB_NAME = "你的数据库名" credential = DefaultAzureCredential() token = credential.get_token("https://database.windows.net/.default") conn_str = f"DRIVER={{ODBC Driver 18 for SQL Server}};SERVER={DB_SERVER};DATABASE={DB_NAME};ENCRYPT=yes;Authentication=ActiveDirectoryAccessToken;UID=任意值;PWD={token.token}" conn = pyodbc.connect(conn_str)
方案3:使用Azure AD服务主体(无人值守场景)
适合自动化脚本、Notebook等无需人工干预的场景:
- 创建Azure AD服务主体,将其添加为Azure SQL的数据库用户并配置权限
- 代码中通过服务主体的ID、密钥获取令牌,示例代码:
from azure.identity import ClientSecretCredential import pyodbc # 替换为你的服务主体配置 CLIENT_ID = "服务主体ID" CLIENT_SECRET = "服务主体密钥" TENANT_ID = "租户ID" DB_SERVER = "xxx.database.windows.net" DB_NAME = "你的数据库名" credential = ClientSecretCredential(tenant_id=TENANT_ID, client_id=CLIENT_ID, client_secret=CLIENT_SECRET) token = credential.get_token("https://database.windows.net/.default") conn_str = f"DRIVER={{ODBC Driver 18 for SQL Server}};SERVER={DB_SERVER};DATABASE={DB_NAME};ENCRYPT=yes;Authentication=ActiveDirectoryAccessToken;UID=任意值;PWD={token.token}" conn = pyodbc.connect(conn_str)
- 注意:服务主体密钥需妥善保管,建议通过环境变量或Azure Key Vault存储,不要硬编码在代码中。
内容的提问来源于stack exchange,提问作者ag_c1768918
相关产品推荐
相关产品推荐

