使用Azure托管服务身份(MSI)连接Azure SQL Server数据库

时间:2019-09-05 07:27:25

标签: python python-3.x azure-sql-database azure-functions azure-managed-identity

我想使用具有 MSI(托管服务身份)身份验证的 python Azure函数访问 Azure SQL数据库

我正在尝试从Azure函数的python中查找如何将Azure sql与MSI连接,但是我没有任何信息。

是否可以使用Azure Functions中的MSI访问Azure SQL Server数据库?

我想访问Azure SQL数据库而不使用python的azure函数在我的代码中传递凭据。

我从azure函数中为python启用了 identity 选项。

2 个答案:

答案 0 :(得分:0)

如果您只想在Azure函数中隐藏Azure SQL连接字符串,则使用Azure Key Vault和MSI将是此处的最佳做法:仅将Azure SQL连接字符串保存为Azure密钥库中的秘密,然后按照{{ 3}}对Azure函数进行一些配置将满足您的要求:您的信誉将永远不会出现在Azure函数中。

我创建了一个密钥保险库,并将我的SQL服务器连接字符串作为密钥存储在Azure密钥保险库中,请注意秘密标识符,因为我们稍后将使用它: this guide

转到密钥库,为功能msi配置访问策略,以确保您的功能可以访问密钥: enter image description here enter image description here 在配置后保存: enter image description here

这是我的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))

让我们在应用程序设置中设置其值: enter image description here

值应为:

@Microsoft.KeyVault(SecretUri=<secret_uri_with_version which you noted from key valut>)

完成这些步骤后,您的azure函数将能够从密钥库中获取SQL连接字符串,并且不会在函数应用程序设置中得到补偿,并且无需更改任何代码。

顺便说一句,如果您仍然想使用MSI来获取访问令牌以连接到Azure SQL enter image description here,这将对您有所帮助。

答案 1 :(得分:0)

我刚刚做了一个快速测试。完整的一步一步在这里:https://github.com/crgarcia12/azure-function-msi-python

总结:

您需要:

  1. 启用 Azure 功能托管服务标识 (MSI)
  2. 为 Azure SQL Server 启用 AAD 集成
  3. 将 Azure Function MSI 用户添加到数据库
  4. 在您的 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))