You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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_descEXTERNAL_USERauthentication_type_descAZURE_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

火山引擎 最新活动