在不使用 Microsoft.IdentityModel.Clients.ActiveDirectory dll 的情况下使用 MFA Active Directory 交互式身份验证连接到 Python 中的 Azure SQL
Connect to Azure SQL in Python with MFA Active Directory Interactive Authentication without using Microsoft.IdentityModel.Clients.ActiveDirectory dll
使用 MFA 连接到 Azure SQL 数据库(在 SSMS 中作为 "Active Directory - Universal")Microsoft 推荐并且目前只有使用 Microsoft.IdentityModel.Clients.ActiveDirectory[=17 连接 C# 的教程=]
在来自 Python 或 Powershell 的常规 ODBC 连接字符串中设置 Authentication='Active Directory Interactive';
会导致错误
Cannot find an authentication provider for 'ActiveDirectoryInteractive'
这似乎是因为根据 Microsoft 在 https://docs.microsoft.com/en-us/azure/sql-database/active-directory-interactive-connect-azure-sql-db 的示例代码,您需要在创建连接时显式创建自己的身份验证提供程序 class:
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 提供程序?
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 环境中运行良好。
希望对您有所帮助。
从 MacOS 使用 AAD MFA 进行身份验证/Linux
我在 MacO 上遇到了同样的问题。如上所述,使用“ActiveDirectoryInteractive”的 ODBC 选项仅适用于 Windows.
为了使用 AAD MFA 连接到数据库,我还使用了 pyodbc,但使用了访问令牌。要获得令牌,您需要做几件事:
要求
说明
在你 运行 下面的代码之前,你必须使用 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 的版本。
- 确保始终使用最新版本的 ODBC 驱动程序
- 如果您的连接 returns 出现类似于 'SSL Provider: [error:0A000086:SSL routines::certificate verify failed:unable to get local issuer certificate] (-1)' 的错误。在连接字符串中添加
TrustServerCertificate=Yes;
会有帮助。
参考资料
使用 MFA 连接到 Azure SQL 数据库(在 SSMS 中作为 "Active Directory - Universal")Microsoft 推荐并且目前只有使用 Microsoft.IdentityModel.Clients.ActiveDirectory[=17 连接 C# 的教程=]
在来自 Python 或 Powershell 的常规 ODBC 连接字符串中设置 Authentication='Active Directory Interactive';
会导致错误
Cannot find an authentication provider for 'ActiveDirectoryInteractive'
这似乎是因为根据 Microsoft 在 https://docs.microsoft.com/en-us/azure/sql-database/active-directory-interactive-connect-azure-sql-db 的示例代码,您需要在创建连接时显式创建自己的身份验证提供程序 class:
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 提供程序?
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 环境中运行良好。
希望对您有所帮助。
从 MacOS 使用 AAD MFA 进行身份验证/Linux
我在 MacO 上遇到了同样的问题。如上所述,使用“ActiveDirectoryInteractive”的 ODBC 选项仅适用于 Windows.
为了使用 AAD MFA 连接到数据库,我还使用了 pyodbc,但使用了访问令牌。要获得令牌,您需要做几件事:
要求
说明
在你 运行 下面的代码之前,你必须使用 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 的版本。
- 确保始终使用最新版本的 ODBC 驱动程序
- 如果您的连接 returns 出现类似于 'SSL Provider: [error:0A000086:SSL routines::certificate verify failed:unable to get local issuer certificate] (-1)' 的错误。在连接字符串中添加
TrustServerCertificate=Yes;
会有帮助。
参考资料