Python应用配置Azure SQL Database无密码连接时遭遇登录失败问题求助
Python应用配置Azure SQL Database无密码连接时遭遇登录失败问题求助
看起来你已经按照官方文档走完了大部分配置流程,但卡在了令牌认证登录这一步。我来分享几个常见的排查方向和解决方法,你可以逐一验证:
1. 检查ODBC驱动版本匹配问题
你的连接字符串里指定的是Driver={ODBC Driver 18 for SQL Server},但错误提示里显示实际调用的是ODBC Driver 17,版本不兼容很可能是诱因之一:
- 先确认本地是否已安装ODBC Driver 18 for SQL Server,未安装的话请先下载安装对应版本
- 打开系统的「ODBC数据源管理器」,切换到「驱动程序」标签页,确认「ODBC Driver 18 for SQL Server」是可用状态
- 确保连接字符串里的驱动名称和已安装的版本完全一致,避免系统默认 fallback 到旧版本驱动
2. 验证令牌对应的身份是否正确
DefaultAzureCredential会按优先级尝试多种身份源(环境变量、Azure CLI、Visual Studio、交互式浏览器等),你需要确认实际获取令牌的身份就是你在数据库中授权的user@domain:
- 在
get_conn函数中添加调试代码,打印获取到的令牌所属身份:token = credential.get_token("https://database.windows.net/.default") print(f"Authenticated identity: {token.claims.get('name')}, UPN: {token.claims.get('upn')}") - 如果你是通过Azure CLI获取身份,执行
az account show确认当前登录账号是否为user@domain,若不是则用az login -u user@domain切换到目标账号
3. 核对数据库用户与Entra ID用户的映射
即使执行了创建用户的SQL脚本,也可能因Entra ID用户的**用户主体名称(UPN)**与SQL中的配置不一致导致认证失败:
- 登录Azure Portal,找到目标Entra ID用户,复制其完整的UPN,确保和SQL脚本中
[user@domain]的拼写、大小写、域名后缀完全一致 - 在数据库中执行以下SQL,确认用户存在且类型正确:
正常结果应该是SELECT name, type_desc, authentication_type_desc FROM sys.database_principals WHERE name = 'user@domain';type_desc为EXTERNAL_USER,authentication_type_desc为AZURE_ACTIVE_DIRECTORY
4. 检查令牌传递的细节
你的令牌处理逻辑大体正确,但可以优化验证:
- 确认
token.encode("UTF-16-LE")的编码是否正确,这是SQL Server要求的令牌编码格式,不过可以尝试用更简洁的写法:token = credential.get_token("https://database.windows.net/.default") token_struct = struct.pack("<I", len(token.token)) + token.token.encode("UTF-16-LE") - 若启用了交互式浏览器认证,确保弹出的浏览器中登录的是已授权的
user@domain账号,避免误登其他账号
5. 验证SQL Server的Entra ID基础配置
- 登录Azure Portal,进入你的SQL Server资源,在「设置」→「Azure Active Directory」中,确认Azure AD管理员已设置为正确的Entra ID用户(若使用组账号则需确保组已被授权)
- 确认SQL Server的防火墙规则允许你的本地IP地址访问,虽然当前错误是登录失败,但防火墙拦截也可能引发异常表现,可先临时允许所有IP测试排除
快速验证小技巧
用Azure CLI直接执行数据库查询,快速排查是数据库授权问题还是代码问题:
az sql db query -n <database-name> -s <database-server-name> -q "SELECT TOP 1 * FROM Persons"
如果这个命令能成功返回数据,说明数据库授权和身份是正常的,问题出在Python代码的驱动或令牌传递环节;如果命令也失败,则重点排查数据库的Entra ID配置。
希望这些排查方向能帮你定位到问题,有新的测试结果可以随时补充上来!
备注:内容来源于stack exchange,提问作者Rakesh V




