如何使用Python通过服务主体认证连接Azure SQL数据库
所需依赖安装
你需要先安装2个Python库,以及1个系统级驱动:
azure-identity:微软官方Azure身份认证SDK,封装了服务主体生成令牌的全流程,不用自己手写HTTP请求对接AAD接口,对新手友好pyodbc:Python生态下连接SQL Server的标准库,支持传入AAD访问令牌完成Azure SQL认证
注意:
pyodbc依赖系统层面的ODBC驱动,你需要提前在本地安装ODBC Driver 17/18 for SQL Server,这部分不是pip能安装的,装完再装Python库,否则运行时会报驱动不存在的错误。
执行以下pip命令安装Python依赖:
pip install azure-identity pyodbc
分步实现指引
前置校验
在写代码前先确认2个配置,否则跑代码会报权限错误:
- 你持有的服务主体已经在目标Azure SQL数据库内完成了用户映射和权限分配:仅在Azure门户给服务主体分配资源角色没用,需要在目标库内执行SQL创建对应外部用户,并授予读写等需要的权限
- 你已经收集齐必填参数:Azure租户ID(tenant id)、服务主体客户端ID(client id)、服务主体客户端密钥(client secret)、目标Azure SQL的服务地址、要连接的数据库名
核心逻辑说明
- 用
ClientSecretCredential类传入租户、客户端ID、密钥初始化认证客户端,注意申请令牌的资源范围必须固定写https://database.windows.net/.default,这是Azure SQL的令牌受众,写错了令牌无法通过校验 - 拿到访问令牌后,不要在连接字符串里写用户名密码,通过pyodbc的连接前置属性传入令牌即可完成认证,注意令牌需要转成
utf-16-le编码的字节格式,直接传字符串会认证失败
可直接运行的完整代码
from azure.identity import ClientSecretCredential import pyodbc # ========== 替换为你自己的配置参数 ========== AZURE_TENANT_ID = "你的Azure AD租户ID" SP_CLIENT_ID = "服务主体的Client ID" SP_CLIENT_SECRET = "服务主体的Client Secret" SQL_SERVER_ADDR = "Azure SQL地址,例如mydb.database.windows.net" TARGET_DB_NAME = "要连接的数据库名称" # ========================================== # 步骤1:生成Azure SQL可用的访问令牌 credential = ClientSecretCredential( tenant_id=AZURE_TENANT_ID, client_id=SP_CLIENT_ID, client_secret=SP_CLIENT_SECRET ) token_res = credential.get_token("https://database.windows.net/.default") access_token = token_res.token # 步骤2:构造连接,传入令牌完成认证 conn_str = ( f"DRIVER={{ODBC Driver 18 for SQL Server}};" f"SERVER={SQL_SERVER_ADDR};" f"DATABASE={TARGET_DB_NAME};" "Encrypt=yes;" "TrustServerCertificate=no;" "Connection Timeout=30;" ) # 1256是pyodbc中SQL_COPT_SS_ACCESS_TOKEN参数的固定数值,不需要额外导入常量 db_conn = pyodbc.connect( conn_str, attrs_before={1256: access_token.encode("utf-16-le")} ) # 测试连接是否正常 cursor = db_conn.cursor() cursor.execute("SELECT @@VERSION") db_version = cursor.fetchone() print(f"连接成功,数据库版本:{db_version[0]}") # 资源释放 cursor.close() db_conn.close()
新手常见踩坑
- 不要自己手写requests请求调用AAD接口拿令牌,很容易写错请求头、参数或者令牌格式,直接用官方
azure-identity库的封装方法,出错概率极低 - 令牌必须编码为
utf-16-le格式的字节串传入,直接传原始字符串会报登录失败,这是SQL Server ODBC驱动对AAD令牌的固定格式要求 - 如果报
Invalid authorization specification,先检查服务主体是不是已经在目标数据库内创建了对应外部用户,有没有分配足够的操作权限 - 如果报驱动找不到,先确认本地已经正确安装了对应版本的ODBC Driver for SQL Server,安装完重启终端再跑代码
内容的提问来源于stack exchange,提问作者Zoltaire
相关产品推荐
相关产品推荐

