使用MFA Active Directory交互式身份验证在Python中连接到Azure SQL,而不使用Microsoft. IdentityModel. Clients. ActiveDirectory dll

dkqlctbz  于 2023-06-24  发布在  Python
关注(0)|答案(3)|浏览(137)

要使用MFA(在SSMS中称为“Active Directory - Universal”)连接到Azure SQL数据库,Microsoft建议使用Microsoft.IdentityModel.Clients.ActiveDirectory连接C#,目前只有一个教程
在Python或Powershell的常规ODBC连接字符串中设置Authentication='Active Directory Interactive';会导致以下错误

Cannot find an authentication provider for 'ActiveDirectoryInteractive'

这似乎是因为根据微软在https://learn.microsoft.com/en-us/azure/sql-database/active-directory-interactive-connect-azure-sql-db上的示例代码,在创建连接时,您需要显式创建自己的auth provider类:

public static void Main(string[] args)
        {
            var provider = new ActiveDirectoryAuthProvider();

            SC.SqlAuthenticationProvider.SetProvider(
                SC.SqlAuthenticationMethod.ActiveDirectoryInteractive,
                //SC.SqlAuthenticationMethod.ActiveDirectoryIntegrated,  // Alternatives.
                //SC.SqlAuthenticationMethod.ActiveDirectoryPassword,
                provider);

            Program.Connection();
        }

我想连接pyodbc,所以我不能实现ActiveDirectoryInteractive提供程序。
是否有任何方法可以使用OAuth获取令牌并在连接字符串中使用它,或者在不使用.NET的情况下实现ActiveDirectoryInteractive提供程序?

6bc51xsx

6bc51xsx1#

在MacOS / Linux下使用AAD MFA认证

我也遇到了同样的问题,但在MacOS上。如上所述,使用“ActiveDirectoryInteractive”的ODBC选项仅适用于Windows。
如果你想看到这篇文章的更详细的版本,请查看我在Medium上的文章,否则请继续阅读。;)

需求

为了使用AAD MFA连接到数据库,我还使用了pyodbc,但使用了访问令牌。要获得令牌,您需要做几件事:

  1. Azure CLI
  2. Microsoft ODBC Driver for SQL Server (Linux-MAC)

使用说明

在运行以下代码之前,必须使用azure cli进行身份验证,从cmd运行:az login

from azure.identity import AzureCliCredential
import struct
import pyodbc 

# input params
server = '<your server address>'
database = '<database name>'
query = 'SELECT * from dbo.Address;'

# Use the cli credential to get a token after the user has signed in via the Azure CLI 'az login' command.
credential = AzureCliCredential()
databaseToken = credential.get_token('https://database.windows.net/')

# get bytes from token obtained
tokenb = bytes(databaseToken[0], "UTF-8")
exptoken = b'';
for i in tokenb:
 exptoken += bytes({i});
 exptoken += bytes(1);
tokenstruct = struct.pack("=i", len(exptoken)) + exptoken;

# build connection string using acquired token
connString = "Driver={ODBC Driver 17 for SQL Server};SERVER="+server+";DATABASE="+database+""
SQL_COPT_SS_ACCESS_TOKEN = 1256 
conn = pyodbc.connect(connString, attrs_before = {SQL_COPT_SS_ACCESS_TOKEN:tokenstruct});

# sample query
cursor = conn.cursor()
cursor.execute(query)
row = cursor.fetchone()
while row:
    print (str(row[0]) + " " + str(row[1]))
    row = cursor.fetchone()

故障排除

有些人使用上面的代码时可能会遇到不同的行为,具体取决于ODBC驱动程序和MacOS的版本。
1.确保始终使用ODBC驱动程序的最新版本
1.如果您的连接返回类似于“SSL Provider:[错误:0A 000086:SSL例程::证书验证失败:无法获取本地颁发者证书](-1)'。将TrustServerCertificate=Yes;添加到连接字符串可以提供帮助。

参考资料

https://pypi.org/project/azure-identity/
https://github.com/AzureAD/azure-activedirectory-library-for-python/wiki/Connect-to-Azure-SQL-Database

tjvv9vkg

tjvv9vkg2#

ODBC driver支持MFA身份验证,但仅限于Windows:

我在Python pyodbc中测试过,它也可以工作。
下面是我的pyodbc代码,它通过AAD MFA身份验证连接到我的Azure SQL数据库:

import pyodbc
server = '***.database.windows.net'
database = 'Mydatabase'
username ='****@****.com'
Authentication='ActiveDirectoryInteractive'
driver= '{ODBC Driver 17 for SQL Server}'
conn = pyodbc.connect('DRIVER='+driver+
                      ';SERVER='+server+
                      ';PORT=1433;DATABASE='+database+
                      ';UID='+username+
                      ';AUTHENTICATION='+Authentication
                      )

print(conn)

它在我的windows环境中工作得很好。

希望这能帮上忙。

b4wnujal

b4wnujal3#

如果直接在UTF-16 LE中编码,则不需要像示例中那样使用循环。
因此,这也会起作用。

# get bytes from token obtained
tokenb = bytes(databaseToken[0], "UTF-16-LE")
tokenstruct = struct.pack("=i", len(tokenb)) + tokenb;

相关问题