我想使用具有 MSI(托管服务身份)身份验证的 python Azure函数访问 Azure SQL数据库。
我正在尝试从Azure函数的python中查找如何将Azure sql与MSI连接,但是我没有任何信息。
是否可以使用Azure Functions中的MSI访问Azure SQL Server数据库?
我想访问Azure SQL数据库而不使用python的azure函数在我的代码中传递凭据。
我从azure函数中为python启用了 identity 选项。
答案 0 :(得分:0)
如果您只想在Azure函数中隐藏Azure SQL连接字符串,则使用Azure Key Vault和MSI将是此处的最佳做法:仅将Azure SQL连接字符串保存为Azure密钥库中的秘密,然后按照{{ 3}}对Azure函数进行一些配置将满足您的要求:您的信誉将永远不会出现在Azure函数中。
我创建了一个密钥保险库,并将我的SQL服务器连接字符串作为密钥存储在Azure密钥保险库中,请注意秘密标识符,因为我们稍后将使用它: this guide
转到密钥库,为功能msi配置访问策略,以确保您的功能可以访问密钥: 在配置后保存:
这是我的python演示代码,很容易看到,我正在从Azure Web应用程序中读取“ SQLConn”:
import logging
import os
import azure.functions as func
import pyodbc
def main(req: func.HttpRequest) -> func.HttpResponse:
logging.info('Python HTTP trigger function processed a request.')
cnxn = pyodbc.connect(os.environ["SQLConn"])
cursor = cnxn.cursor()
cursor.execute("select @@version")
row = cursor.fetchall()
return func.HttpResponse(str(row))
值应为:
@Microsoft.KeyVault(SecretUri=<secret_uri_with_version which you noted from key valut>)
完成这些步骤后,您的azure函数将能够从密钥库中获取SQL连接字符串,并且不会在函数应用程序设置中得到补偿,并且无需更改任何代码。
答案 1 :(得分:0)
我刚刚做了一个快速测试。完整的一步一步在这里:https://github.com/crgarcia12/azure-function-msi-python
总结:
您需要:
Authentication=ActiveDirectoryMsi
中使用 pyodbc.connect
。要将 MSI 用户添加到数据库,您必须使用 AAD 管理员进行连接,然后运行此查询:
CREATE USER "<MSI user display name>" FROM EXTERNAL PROVIDER;
ALTER ROLE db_datareader ADD MEMBER "<MSI user display name>" -- grant permission to read to database
ALTER ROLE db_datawriter ADD MEMBER "<MSI user display name>" -- grant permission to write to database
<MSI user display name>
通常是 Azure 函数名称。您也可以在 PowerShell 中使用 Get-AzureADObjectByObjectId -ObjectIds
获取它
这是一个hello-world函数的源代码:
import logging
import azure.functions as func
# Sql driver
import pyodbc
def main(req: func.HttpRequest) -> func.HttpResponse:
try:
logging.info('Python HTTP trigger function processed a request.')
# Connecting to Azure SQl the standard way
server = 'tcp:<servername>.database.windows.net'
database = '<dbname>'
driver = '{ODBC Driver 17 for SQL Server}' # Driver 13 did not work for me
with pyodbc.connect(
"Driver="
+ driver
+ ";Server="
+ server
+ ";PORT=1433;Database="
+ database
+ ";Authentication=ActiveDirectoryMsi", # This is important :)
) as conn:
logging.info("Successful connection to database")
with conn.cursor() as cursor:
#Sample select query
cursor.execute("SELECT Name FROM People;")
peopleNames = ''
row = cursor.fetchone()
while row:
peopleNames += str(row[0]).strip() + " "
row = cursor.fetchone()
return func.HttpResponse(f"Hello {peopleNames}!")
except Exception as e:
return func.HttpResponse(str(e))