0
点赞
收藏
分享

微信扫一扫

使用 Azure Functions 和托管标识保护 Azure OpenAI 使用安全,手把手教学!

Azure OpenAI 服务提供对 OpenAI 高级语言模型的 REST API 访问,包括 GPT-4、GPT-4 Turbo with Vision、GPT-3.5-Turbo 和一系列 Embeddings 模型。这些最先进的模型具有很强的适应性,可以针对各种任务进行定制,例如生成内容、总结信息、解释图像、增强语义搜索以及将自然语言转换为代码。

为了满足每个人的不同需求和技术要求,可以通过多个接口访问 Azure OpenAI 服务:用于直接集成的 REST API、适合那些喜欢在 Python 环境中工作的人员的 Python SDK,以及 Azure OpenAI Studio,它为用户提供了友好的基于网络的界面,用于与模型交互。这种灵活性确保开发人员和企业能够以最适合其项目需求的方式利用 OpenAI 语言模型的强大功能。

目前建议企业通过微软官方合作伙伴获取服务,可以合规、稳定地提供企业用户使用ChatGPT的可能,满足国内发票需求,同时也能解决连接不稳定/响应速度慢/并发配额低等问题。


参考链接:

 微软 Azure OpenAI 申请

连接不稳定or响应速度慢如何解决?

使用Python SDK的开发人员通常遵循以下步骤:

  1. 从 Azure 获取唯一密钥和终结点。
  2. 将这些凭据配置为环境变量,确保它们可供应用程序随时使用。
  3. 实现类似于下面的代码片段来实例化 Azure OpenAI 客户端:client = AzureOpenAI( azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT"), api_key=os.getenv("AZURE_OPENAI_API_KEY"), api_version="2024-02-01" )
  4. 定义与项目目标相符的使用场景,例如聊天、内容完成或助理功能。

在开发函数应用或 Web 应用时,标准做法是将敏感数据(例如密钥)存储在 local.settings.json 文件中以进行本地测试。部署到云环境时,这些值通常通过应用程序配置设置进行管理。为了增强安全性,工程师利用 Azure KeyVault 直接在应用程序中安全地存储和访问所有密钥。

然而,即使采取了这些安全措施,漏洞仍然可能出现。常见风险包括意外对源代码或配置文件中的敏感信息进行硬编码、在不安全的位置不正确地存储机密信息,或者轮换和撤销实践不足,可能导致暴露时间延长。

这些挑战凸显了开发人员在管理关键安全组件(例如机密、凭证、证书和密钥)时面临的困难。 Azure 托管身份提供了强大的解决方案,通过自动化这些元素的安全管理来减轻开发人员的负担。

Azure OpenAI 可用于许多基于云的场景,例如 Azure Functions、应用服务,甚至在 Databricks 上运行的 jupyter 笔记本。在本教程中,我们将指导您创建一个 Azure 函数,该函数使用托管标识建立与 OpenAI 服务的安全连接。

准备

首先创建一个基本的 Azure 函数,调用函数 process_image并将其部署在 Azure 平台上。如需全面的指导,请参阅此处提供的文档。我们的函数需要http触发器和V2编程模型。该项目应该这样组织


使用 Azure Functions 和托管标识保护 Azure OpenAI 使用安全,手把手教学!_Azure


使用 Postman 或 Web 浏览器测试您的函数并确保其运行良好并且您的环境已准备就绪。


使用 Azure Functions 和托管标识保护 Azure OpenAI 使用安全,手把手教学!_Azure_02



使用 Azure Functions 和托管标识保护 Azure OpenAI 使用安全,手把手教学!_Azure_03


随后,继续建立 Azure OpenAI 资源及其部署,这可以通过遵循提供的参考中概述的说明轻松完成。建议为部署分配与型号名称相同的名称,以便于识别。

配置部署和 Azure OpenAI 资源后,请确保记录部署名称和 OpenAI 资源名称以供将来参考。

尽管本教程使用 GPT-4 视觉模型,但这些步骤同样适用于您可能选择实现的任何基于文本的模型。

配置

让我们继续配置托管身份。如前所述,虽然开发人员可以将机密安全地存储在 Azure Key Vault 或应用程序设置中,但服务需要一种机制来从 Azure Key Vault 检索这些机密。托管身份通过在 Microsoft Entra ID 中授予自动控制的身份来提供无缝解决方案,应用程序可以利用该身份对与 Microsoft Entra 兼容的资源进行身份验证。这使得应用程序能够轻松获取 Microsoft Entra 令牌,而无需直接管理敏感凭据。

托管身份有两种类型:系统分配和用户分配:

  • 系统分配。某些 Azure 资源允许您直接在资源上启用托管标识。当启用系统分配的托管标识时,Microsoft Entra ID 会为该标识创建特殊类型的服务主体。服务主体与该 Azure 资源的生命周期相关联。删除 Azure 资源时,Azure 会自动为你删除服务主体。根据设计,只有该 Azure 资源可以使用此标识从 Microsoft Entra ID 获取令牌。您授予托管身份对一项或多项服务的访问权限。系统分配的服务主体的名称始终与其创建的 Azure 资源的名称相同。对于部署槽,其系统分配的标识名称为 <app-name>/slots/<slot-name>。
  • 用户分配。您还可以创建托管标识作为单独的 Azure 资源。您可以创建用户分配的托管标识并将其分配给一个或多个 Azure 资源。当启用用户分配的托管标识时,Microsoft Entra ID 会创建一个服务主体,独立于使用它的资源进行管理。用户分配的身份可由多个资源使用。您授予对一项或多项服务的托管身份访问权限。

您需要适当范围(您的资源组或订阅)的“所有者”权限才能创建所需的资源并处理角色。

本指南将向您展示如何创建系统分配的托管标识。启用系统分配的托管标识是一种一键式体验。您可以在创建函数应用时或在现有函数应用的属性中执行此操作。转到您的函数应用程序,然后在左侧的“设置”部分下找到“身份”。


使用 Azure Functions 和托管标识保护 Azure OpenAI 使用安全,手把手教学!_Azure_04



使用 Azure Functions 和托管标识保护 Azure OpenAI 使用安全,手把手教学!_Azure_05


通过 Azure 资源的托管标识,您的应用程序可以获得访问令牌,以对使用 Microsoft Entra 身份验证的资源进行身份验证。因此,您需要向我们的 Function App 的身份授予对 Azure 资源管理器中资源的访问权限,在本例中为 Azure Open AI。我们将读者角色分配给资源范围内的托管身份。


使用 Azure Functions 和托管标识保护 Azure OpenAI 使用安全,手把手教学!_Azure_06


接下来,关键的一步。您需要创建一个令牌才能访问该服务。在虚拟环境中安装 Azure Identity。

pip install azure-identity

导入库

from azure.identity import DefaultAzureCredential, get_bearer_token_provider

并在 Azure 函数中使用此代码来创建令牌

token_provider = get_bearer_token_provider(DefaultAzureCredential(), "https://cognitiveservices.azure.com/.default")

接下来,安装openai python包

pip install openai

以同样的方式导入库

from openai import AzureOpenAI

将两个环境变量添加到local.settings.json中,即GPT4V_DEPLOYMENTGPT4V_DEPLOYMENT,它们与您的端点 url 和部署名称相匹配。 接下来,您需要初始化 OpenAI 客户端

api_base = os.environ["GPT4V_ENDPOINT"]
deployment_name = os.environ["GPT4V_DEPLOYMENT"]
api_version = '2023-12-01-preview'

client = AzureOpenAI(
    azure_ad_token_provider=token_provider,
    api_version=api_version,
    azure_endpoint=f"{api_base}openai/deployments/{deployment_name}/extensions",
)

您可能已经注意到,我们仍然使用端点和部署名称,但我们不再需要代码中的任何秘密,这是一个很大的优势。

示例场景

为了展示一个示例,我们将创建一个简单的服务,根据用户指令检查输入图像。为此,我们将从 http 输入获取图像,将其存储在临时存储中(此步骤对于创建有效的数据 url 是必需的),然后将图像发送到 OpenAI。

import azure.functions as func
import logging


import os
import base64
import json

from mimetypes import guess_type

from openai import AzureOpenAI
from azure.identity import DefaultAzureCredential, get_bearer_token_provider

app = func.FunctionApp(http_auth_level=func.AuthLevel.ADMIN)


@app.route(route="process_image")
def process_image_custom(req: func.HttpRequest) -> func.HttpResponse:
    instructions = str(req.params.get('instructions'))
    api_base = os.environ["GPT4V_ENDPOINT"]

    token_provider = get_bearer_token_provider(DefaultAzureCredential(), "https://cognitiveservices.azure.com/.default")

    deployment_name = os.environ["GPT4V_DEPLOYMENT"]
    api_version = '2023-12-01-preview'

    image = req.get_body()
    image_path = "/tmp/temp.jpg"

    with open(image_path, "wb") as image_bytes:
        image_bytes.write(image)

    encoded_image_url = local_image_to_data_url(image_path)

    client = AzureOpenAI(
        azure_ad_token_provider=token_provider,  
        api_version=api_version,
        base_url=f"{api_base}openai/deployments/{deployment_name}/extensions",
    )
    response = client.chat.completions.create(
        model=deployment_name,
        messages=[
            { "role": "system", "content": "You are a helpful assistant helping to analyze input images based on user instructions" },
            { "role": "user", "content": [  
                { 
                    "type": "text", 
                    "text": instructions 
                },
                { 
                    "type": "image_url",
                    "image_url": {
                        "url": encoded_image_url
                    }
                }
            ] } 
        ],
        max_tokens=1000 
    )

    output = response.choices[0].message.content

    
    return func.HttpResponse(output)


def local_image_to_data_url(image_path):
    mime_type, _ = guess_type(image_path)
    if mime_type is None:
        mime_type = 'application/octet-stream'

    with open(image_path, "rb") as image_file:
        base64_encoded_data = base64.b64encode(image_file.read()).decode('utf-8')

    return f"data:{mime_type};base64,{base64_encoded_data}"

结论

本教程演示了如何应用不需要密钥共享的不同 Azure OpenAI 场景,因此更适合生产环境。这种情况有几个优点。如果您使用托管身份,则无需处理凭据。事实上,您甚至无法访问凭据。此外,您可以使用托管标识对支持 Microsoft Entra 身份验证的任何资源(包括您自己的应用程序)进行身份验证。最后,托管身份可以免费使用,如果您有多个使用 OpenAI 的应用程序,这一点也很重要。我希望这可以帮助你。

举报

相关推荐

0 条评论