【Function】Azure Function通过托管身份或访问令牌连接Azure SQL数据库
推荐超级课程:
@TOC
这篇博客将展示如何使用Python函数应用通过托管身份或访问令牌连接Azure SQL数据库。
请注意,Azure Active Directory托管身份认证方法已从ODBC驱动程序的17.3.1.1版本开始添加,适用于系统分配和用户分配的身份。在Azure为Python函数提供的镜像中,ODBC驱动程序版本为17.8,这使得在Linux应用服务中可以使用此功能。
简而言之,本文将提供一步一步的指导、示例代码以及认证工作流程的介绍。
步骤:
- 通过门户创建一个Linux Python函数应用
- 在新的函数应用中设置托管身份,通过启用身份并在门户中保存。这将自动为您生成一个对象(主体)ID。
- 在Azure SQL数据库中分配角色。
搜索您自己的帐户并保存为管理员。
注意:或者,您可以搜索函数应用的名称并将其设置为管理员,那么该函数应用将拥有数据库的管理员权限,并且您可以跳过第4步和第5步。
- 进入数据库的查询编辑器,确保使用上一步设置的帐户登录,而不是用户名和密码。否则第5步将以下面的异常失败。
“无法执行查询。错误:无法创建主体’xxxx’。只有使用Active Directory帐户建立的连接可以创建其他Active Directory用户。”
- 运行以下查询为函数应用创建用户并更改角色。您可以选择根据需求更改这些角色的一部分。
CREATE USER "yourfunctionappname" FROM EXTERNAL PROVIDER;
ALTER ROLE db_datareader ADD MEMBER "yourfunctionappname"
ALTER ROLE db_datawriter ADD MEMBER "yourfunctionappname"
ALTER ROLE db_ddladmin ADD MEMBER "yourfunctionappname"
- 使用以下示例代码构建您自己的项目并部署到函数应用。
示例代码:
以下是当在本地运行时如何使用Azure访问令牌,在函数应用中运行时使用托管身份的示例代码。令牌部分需要替换为您自己的。基本上,它使用 “pyodbc.connect(connection_string+’;Authentication=ActiveDirectoryMsi’)” 通过托管身份进行认证。
此外,“MSI_SECRET” 用于指示我们是在本地运行还是在函数应用中运行,当函数应用启用托管身份时,它将自动作为环境变量创建。
完整的演示项目可以在本文链接资源文件中找到。
import logging
import azure.functions as func
import os
import pyodbc
import struct
def main(req: func.HttpRequest) -> func.HttpResponse:
logging.info('Python HTTP trigger function processed a request.')
server="your-sqlserver.database.windows.net"
database="your_db"
driver="{ODBC Driver 18 for SQL Server}"
query="SELECT * FROM dbo.users"
# 可选使用用户名和密码进行认证
# username = 'name'
# password = 'pass'
db_token = ''
connection_string = 'DRIVER='+driver+';SERVER='+server+';DATABASE='+database
#当启用MSI时
if os.getenv("MSI_SECRET"):
conn = pyodbc.connect(connection_string+';Authentication=ActiveDirectoryMsi')
#在本地运行时使用
else:
SQL_COPT_SS_ACCESS_TOKEN = 1256
exptoken = b''
for i in bytes(db_token, "UTF-8"):
exptoken += bytes({i})
exptoken += bytes(1)
tokenstruct = struct.pack("=i", len(exptoken)) + exptoken
conn = pyodbc.connect(connection_string, attrs_before = { SQL_COPT_SS_ACCESS_TOKEN:tokenstruct })
# 当使用用户名和密码进行认证时,取消注释以下行
# conn = pyodbc.connect('DRIVER='+driver+';SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password)
cursor = conn.cursor()
cursor.execute(query)
row = cursor.fetchone()
while row:
print(row[0])
row = cursor.fetchone()
return func.HttpResponse(
'Success',
status_code=200
)
工作流程:
以下是这两种认证方式的流程,了解它们可以帮助我们理解幕后发生的事情。
- 托管身份:
当我们为函数应用启用托管身份时,将自动为其生成一个服务主体,然后按照以下步骤在数据库中进行认证。
具有托管身份的函数应用 -> 使用服务主体向数据库发送请求 -> 数据库检查相应的数据库用户及其权限 -> 通过认证。
- 访问令牌:
访问令牌可以通过在本地执行az account get-access-token --resource=[https://database.windows.net/](https://urldefense.com/v3/__https:/database.windows.net/__;!!F8kG8IHFARY!J4BoTpaJDMrxKmQWfXabxmweGXuWFiGZpwTUUniCcDAE68BMwm-Ef_LAH_Kokjc$) --query accessToken
生成,然后我们持有这个令牌进行认证。请注意,令牌的默认有效期为一小时,这意味着当它过期时我们需要重新获取。
az login -> az account get-access-token -> 本地函数使用令牌在SQL数据库中进行认证 -> 数据库检查数据库用户是否存在以及权限是否授予 -> 通过认证。
感谢阅读。希望您喜欢。