pyodbc是否支持使用AD访问令牌而不是用户/密码连接到Azure SQL数据库



目前,我使用设备代码凭据来访问Azure AD。

device_code_credential = DeviceCodeCredential(
azure_client_id,
tenant_id=azure_tenant_id,
authority=azure_authority_uri)

但我仍然需要使用Azure帐户用户名/密码来连接到Azure SQL服务器

driver = 'ODBC Driver 17 for SQL Server'
db_connection_string = f'DRIVER={driver};SERVER={server};' 
f'DATABASE={database};UID={user_name};PWD={password};'
f'Authentication=ActiveDirectoryPassword;'
'Encrypt=yes;TrustServerCertificate=no;Connection Timeout=30;'
connector = pyodbc.connect(db_connection_string)

在linux/MacOS下的python中,有没有任何方法可以允许我使用device_code_credential和access_token连接到Azure SQL server?

https://github.com/mkleehammer/pyodbc/issues/228

我只得到了这个链接,它似乎不起作用。

有人有完整的工作样本吗?

您可以参考本教程:用于python的AzureAD/azure Active Directory库:连接到azure SQL数据库。

通过ADAL Python从Azure Active Directory(AAD(获取令牌,连接到Azure SQL数据库是可行的。我们目前还没有完整的样本,但本文概述了一些关键成分。

  1. 按照使用访问令牌连接的说明提供您的申请。这里还有另一篇类似的博客文章
  2. 您的SQL管理员需要将应用程序注册的权限添加到您尝试访问的特定数据库。请参阅中的详细信息此博客文章对Azure SQL DB的基于令牌的身份验证支持使用Mirek H Sztajno的Azure AD身份验证
  3. 这两份文件都没有特别强调以上,但您需要使用https://database.windows.net/作为资源字符串。请注意,您需要保留尾部斜杠,否则,所发布的令牌将不起作用
  4. 将上面的配置输入ADAL Python的客户端凭据样品
  5. 获得访问令牌后,在pyodbc中以这种方式使用它连接到SQL数据库

这适用于AAD访问令牌。在Python 2.x:中,如上面链接的页面上所述,扩展令牌并预先设置长度的示例代码

token = "eyJ0eXAiOi...";
exptoken = "";
for i in token:
exptoken += i;
exptoken += chr(0);
tokenstruct = struct.pack("=i", len(exptoken)) + exptoken;
conn = pyodbc.connect(connstr, attrs_before = { 1256:bytearray(tokenstruct) });

3.x只是由于恼人的字符/字节分割而稍微涉及更多:

token = b"eyJ0eXAiOi...";
exptoken = b"";
for i in token:
exptoken += bytes({i});
exptoken += bytes(1);
tokenstruct = struct.pack("=i", len(exptoken)) + exptoken;
conn = pyodbc.connect(connstr, attrs_before = { 1256:tokenstruct });

(SQL_COPT_SS_ACCESS_TOKEN是1256;它特定于msodbcsql驱动程序,因此pyodbc没有定义它,而且很可能不会。(

希望这能有所帮助。

您可以通过获得代币

from azure.identity import DeviceCodeCredential
# Recommended to allocate a new ClientID in your tenant.
AZURE_CLI_CLIENT_ID = "04b07795-8ddb-461a-bbee-02f9e1bf7b46"
credential = DeviceCodeCredential(client_id=AZURE_CLI_CLIENT_ID)
databaseToken = credential.get_token('https://database.windows.net/.default')

然后使用databaseToken.token作为AAD访问令牌,如Leon Yue的回答所述。

最新更新