【Function】Azure Function通过托管身份或访问令牌连接Azure SQL数据库

2022-03-17T13:53:29+08:00 | 3分钟阅读 | 更新于 2022-03-17T13:53:29+08:00

Macro Zhao

【Function】Azure Function通过托管身份或访问令牌连接Azure SQL数据库

推荐超级课程:

@TOC

这篇博客将展示如何使用Python函数应用通过托管身份或访问令牌连接Azure SQL数据库。

请注意,Azure Active Directory托管身份认证方法已从ODBC驱动程序的17.3.1.1版本开始添加,适用于系统分配和用户分配的身份。在Azure为Python函数提供的镜像中,ODBC驱动程序版本为17.8,这使得在Linux应用服务中可以使用此功能。

简而言之,本文将提供一步一步的指导、示例代码以及认证工作流程的介绍。

步骤:

  1. 通过门户创建一个Linux Python函数应用

  1. 在新的函数应用中设置托管身份,通过启用身份并在门户中保存。这将自动为您生成一个对象(主体)ID。

  1. 在Azure SQL数据库中分配角色。

搜索您自己的帐户并保存为管理员。

注意:或者,您可以搜索函数应用的名称并将其设置为管理员,那么该函数应用将拥有数据库的管理员权限,并且您可以跳过第4步和第5步。

  1. 进入数据库的查询编辑器,确保使用上一步设置的帐户登录,而不是用户名和密码。否则第5步将以下面的异常失败。

“无法执行查询。错误:无法创建主体’xxxx’。只有使用Active Directory帐户建立的连接可以创建其他Active Directory用户。”

  1. 运行以下查询为函数应用创建用户并更改角色。您可以选择根据需求更改这些角色的一部分。
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"
  1. 使用以下示例代码构建您自己的项目并部署到函数应用。

示例代码:

以下是当在本地运行时如何使用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数据库中进行认证 -> 数据库检查数据库用户是否存在以及权限是否授予 -> 通过认证。

感谢阅读。希望您喜欢。

© 2011 - 2025 Macro Zhao的分享站

关于我

如遇到加载502错误,请尝试刷新😄

Hi,欢迎访问 Macro Zhao 的博客。Macro Zhao(或 Macro)是我在互联网上经常使用的名字。

我是一个热衷于技术探索和分享的IT工程师,在这里我会记录分享一些关于技术、工作和生活上的事情。

我的CSDN博客:
https://macro-zhao.blog.csdn.net/

欢迎你通过评论或者邮件与我交流。
Mail Me

推荐好玩(You'll Like)
  • AI 动·画
    • 这是一款有趣·免费的能让您画的画中的角色动起来的AI工具。
    • 支持几十种动作生成。
我的项目(My Projects)
  • 爱学习网

  • 小乙日语App

    • 这是一个帮助日语学习者学习日语的App。
      (当然初衷也是为了自用😄)
    • 界面干净,简洁,漂亮!
    • 其中包含 N1 + N2 的全部单词和语法。
    • 不需注册,更不需要订阅!完全免费!
  • 小乙日文阅读器

    • 词汇不够?照样能读日语名著!
    • 越读积累越多,积跬步致千里!
    • 哪里不会点哪里!妈妈再也不担心我读不了原版读物了!
赞助我(Sponsor Me)

如果你喜欢我的作品或者发现它们对你有所帮助,可以考虑给我买一杯咖啡 ☕️。这将激励我在未来创作和分享更多的项目和技术。🦾

👉 请我喝一杯咖啡

If you like my works or find them helpful, please consider buying me a cup of coffee ☕️. It inspires me to create and share more projects in the future. 🦾

👉 Buy me a coffee