Authentication in Azure OpenAI Service(openai.error.permissionerror key based authentication is disa
I. 问题背景
A. 身份验证毛病
1. AuthenticationError唆使API密钥或令牌无效、过期或被撤消。
2. 毛病可能由拼写毛病、格式毛病或安全问题引发。
B. 禁用基于密钥的身份验证
1. disableLocalAuth属性可以禁止AOIA实例基于API密钥进行身份验证。
II. PowerShell脚本中的密钥身份验证
A. 使用powerShell脚本创建存储帐户
1. 调用New-AzStorageAccount函数并提供必要参数。
2. 可能遇到基于密钥的身份验证禁用毛病。
III. 代码中的API密钥身份验证
A. 在代码中调用OpenAI服务API
1. 提供API密钥进行身份验证。
2. 可能遇到身份验证毛病,提示定阅密钥无效。
IV. 禁用其他身份验证方法
A. Azure App配置资源中禁用令牌身份验证
1. 在Azure门户中定位Azure App配置资源。
2. 在设置下找到Access keys设置,并禁用令牌身份验证方法。
V. 谢绝访问毛病
A. 访问被谢绝的毛病消息
1. 排查和修复与AWS Identity and Access Management (IAM)相关的访问被谢绝毛病消息。
2. 毛病可能由权限问题或无效的定阅密钥引发。
VI. 管理Azure OpenAI资源的访问权限
A. 查看和编辑利用程序详细信息
1. 转到资源管理下的Keys and Endpoint,查看和编辑利用程序详细信息。
2. 可以通过管理资源的访问权限来调剂身份验证方法。
openai.error.permissionerror key based authentication is disabled for this resource的进一步展开说明
使用Python SDK通过Azure AD进行身份验证的方法已更新为2023年4月3日
大家好!
在AI领域,我一直忙于深入研究。我一直在浏览Tom Taulli的一本名为“Artificial Intelligence Basics: A Non-Technical Introduction”的好书。这本书对我理解AI技术的术语和背景帮助很大。结合这本书,我一直在研究Azure的OpenAI服务,并密切关注该服务的基础设施和安全性方面。
在上一篇文章中,我介绍了客户可使用Azure Active Directory(AAD)身份验证来保护其特定实例的控制选项。本文将更深入地研究这个问题。准备好投入代码和HTTP事务的细节当中吧!让我们开始吧!
在我深入介绍OpenAI如何支持AAD身份验证之前,我想先了解一下管理平面和数据平面的概念。管理平面用于管理资源,数据平面用于管理资源中托管的数据。Azure中的许多服务都有单独的管理平面和数据平面。Azure存储就是这样一项服务,它与OpenAI服务的身份验证有些类似。
当客户创建Azure存储帐户时,他们需要通过与位于management.azure.com端点后面的ARM API的交互来完成此操作。他们一定要对AAD进行身份验证以获得访问令牌,以访问API。然后,通过Azure RBAC进行授权以验证用户、托管标识或服务主体对资源具有的权限。创建存储帐户后,客户可以将加密密钥从平台管理密钥(PMK,也就是由Microsoft管理的密钥)更改成客户管理密钥(CMK),启用软删除或启用存储防火墙等网络控制。这些都是针对资源的操作。
一旦客户准备将blob数据上传到存储帐户,他们将通过数据平面操作来实现。这是通过Blob Service API来完成的。此API托管在blob.core.windows.net端点后面,操作包括创建blob或删除blob。客户有两种身份验证方法。第一种方法是较旧的方法,触及使用称为存储帐户访问密钥的静态密钥。每一个存储帐户在创建存储帐户时都会取得两个这样的密钥。直接使用这些密钥,可以完全访问存储帐户中的所有操作和所有托管的数据(SAS令牌可以用于限制访问的操作、时间和范围,但在我们讨论OpenAI服务时其实不相关)。这不是理想的方法,对吧?第二种方法是推荐的方法,触及使用AAD身份验证。在这类方法中,安全拜托对AAD进行身份验证,并接收访问令牌,然后通过Azure RBAC对操作进行授权。请记住,这些都是针对资源中托管的数据的操作。
Azure存储中的管理平面与数据平面的身份验证
我为何要向您介绍Azure存储身份验证的基础知识?是由于Azure OpenAI服务的工作方式非常类似。
首先让我们讨论Azure OpenAI服务的管理平面。与Azure存储(和Azure的其他服务)一样,通过management.azure.com端点后面的ARM API对其进行管理。当客户想要创建Azure OpenAI服务实例、将其从PMK切换到CMK,或设置重定向日志的诊断设置(我将在以后的文章中介绍日志记录)时,他们将使用管理平面。所有这些操作都需要对AAD进行身份验证并通过Azure RBAC进行授权(我将在以后的文章中介绍授权)。
简单吧?现在让我们来看看数据平面的复杂性。
每当客户创建Azure OpenAI服务实例时,都会创建两个API密钥。这些API密钥允许客户完全访问所有数据平面操作。这些操作包括管理模型的部署、管理已上传到服务实例并用于微调模型的训练数据、管理微调模型和列出可用模型。这些操作是针对Azure OpenAI服务API履行的,该API位于一个具有openai.azure.com(例如:myservice.openai.azure.com)的唯一标签后面。几近所有你在Azure OpenAI Studio中要做的工作都可以通过这些密钥完成。如果您选择使用这些密钥,您需要通过安全管理面授权来控制对这些密钥的访问,也就是通过Azure RBAC进行授权。
Azure OpenAI服务API密钥
在上面的图片中,我有一个选项可以重新生成密钥,以防出现要挟或遵照组织的密钥轮换流程。在轮换密钥时,提供了两个密钥以便继续访问服务。
下面是我使用OpenAI Python SDK的一小段简单代码。在代码中,我向模型提供一个提示,并要求它为我完成,并使用其中一个API密钥进行身份验证。
import logging import sys import os import openai def main(): # 设置日志记录 try: logging.basicConfig( level=logging.ERROR, format=’%asctime)s – %(name)s – %(levelname)s – %(message)s’, handlers=[logging.StreamHandler(sys.stdout)] ) except: logging.error(‘Failed to setup logging: ‘, exc_info=True) try: # 设置OpenAI变量 openai.api_type = “azure” openai.api_base = os.getenv(‘OPENAI_API_BASE’) openai.api_version = “2023⑴2-01” openai.api_key = os.getenv(‘OPENAI_API_KEY’) response = openai.Completion.create( engine=os.getenv(‘DEPLOYMENT_NAME’), prompt=’Once upon a time’ ) print(response.choices[0].text) except: logging.error(‘Failed to respond to prompt: ‘, exc_info=True) if __name__ == “__main__”: main()
模型很有创意,给我提供了以下的回答。
如果你仔细看,你会注意到关于我的会话安全性的正告。我之所以会收到这个毛病,是由于我在OpenAI库中关闭了证书验证,以便使用Fiddler拦截调用。现在,我告知你,关闭证书验证是一件很麻烦的事,由于SDK的开发者试图保护用户不受坏人的伤害。长话短说,Azure的Python SDK没有提供像Azure Python SDK中的要求库那样的关闭证书检查的选项(可以通过在底层使用的要求库中传递一个verify=False的参数来关闭证书检查)。虽然开发者提供了一个名为verify_ssl_certs的属性,但它实际上没有起作用。由于大多数Python SDK都在内部使用requests库,所以我查看了我的计算机上的该库,并找到了api_requestor.py文件。在这个文件中,我注释掉了开发者的代码,并将verify=False属性添加到正在创建的Session对象中,该对象将创建一个requests的Sessions对象。
在OpenAI Python SDK中关闭证书验证
现在不要在任何重要的环境中这样做。如果您的环境中出现证书验证失败的情况,您应当通知您的信息安全团队。证书验证绝对是必不可少的,以确保上游服务器的身份,并下降中间人攻击的风险。
一旦我能够在HTTPS会话中插入Fiddler,我就可以够捕获对话。在下面的截图中,您可以看到SDK传递了api-key头部。请注意该头部名称,由于当我们讨论AAD身份验证时,它将变得相关。如果你已在使用OpenAI的服务,那末这应当看起来很熟习。微软很好地支持了现有的SDK,当使用其中一个API密钥时。
这时候你可能会想:“这些都很好,Matt,但我想使用Azure AD身份验证以获得AAD相对静态密钥提供的所有安全优势。”是的,我知道,我正在告知你。你不能责怪我有一点迷恋Fiddler吧?
好吧,现在让我们来谈谈Azure OpenAI服务的数据平面上的AAD身份验证。可能吗?是的,但有一些注意事项。公共文档及第了一个使用curl进行此操作的示例。但是,curl很合适演示一个概念,但更有可能使用首选编程语言的SDK。由于Python实际上是我唯一知道的编程语言(PowerShell不算,我也不想由于知道一些Perl就暴露自己的年龄),让我使用我们爱好的AAD SDK,MSAL,来演示这个进程。
对这个示例,我将使用服务主体,但如果您的代码在Azure中运行,则应当使用托管标识。在创建服务主体时,我授与它在包括Azure OpenAI服务实例的资源组上具有认知服务用户RBAC角色的权限,这是文档中建议的做法。这是为了授权服务主体访问数据平面操作。服务上还有几个其他的RBAC角色,但如我之前所说,我将在以后的文章中介绍授权。一旦创建并分配了适当的RBAC角色的服务主体,我修改了我的代码,以包括一个函数,该函数调用MSAL以获得访问范围为认知服务的访问令牌,Azure OpenAI服务属于该范围。然后,我将该令牌作为API密钥传递给调用Azure OpenAI服务API的代码中。
import logging import sys import os import openai from msal import ConfidentialClientApplication def get_sp_access_token(client_id, client_credential, tenant_name, scopes): logging.info(‘Attempting to obtain an access token…’) result = None print(tenant_name) app = ConfidentialClientApplication( client_id=client_id, client_credential=client_credential, authority=f”https://login.microsoftonline.com/{tenant_name}”, ) result = app.acquire_token_for_client(scopes=scopes) if “access_token” in result: logging.info(‘Access token successfully acquired’) return result[‘access_token’] else: logging.error(‘Unable to obtain access token’) logging.error(f”Error was: {result[‘error’]}”) logging.error(f”Error description was: {result[‘error_description’]}”) logging.error(f”Error correlation_id was: {result[‘correlation_id’]}”) raise Exception(‘Failed to obtain access token’) def main(): # 设置日志记录 try: logging.basicConfig( level=logging.ERROR, format=’%asctime)s – %(name)s – %(levelname)s – %(message)s’, handlers=[logging.StreamHandler(sys.stdout)] ) except: logging.error(‘Failed to setup logging: ‘, exc_info=True) try: # 获得访问令牌 token = get_sp_access_token( client_id = os.getenv(‘CLIENT_ID’), client_credential = os.getenv(‘CLIENT_SECRET’), tenant_name = os.getenv(‘TENANT_ID’), scopes = “https://cognitiveservices.azure.com/.default” ) except: logging.error(‘Failed to obtain access token: ‘, exc_info=True) try: # 设置OpenAI变量 openai.api_type = “azure” openai.api_base = os.getenv(‘OPENAI_API_BASE’) openai.api_version = “2023⑴2-01” openai.api_key = token response = openai.Completion.create( engine=os.getenv(‘DEPLOYMENT_NAME’), prompt=’Once upon a time’ ) print(response.choices[0].text) except: logging.error(‘Failed to summarize file: ‘, exc_info=True) if __name__ == “__main__”: main()
让我们尝试履行一下,看看产生了甚么。
哎呀!产生了甚么?如果您还记得之条件到过的,API密钥是通过api-key头部传递的。但是,为了使用AAD提供的访问令牌,我们一定要在Authorization头部中传递它,就像在Microsoft的公共文档中所示的示例中那样。
curl ${endpoint%/}/openai/deployments/YOUR_DEPLOYMENT_NAME/completions?api-version=2023⑴2-01 -H “Content-Type: application/json” -H “Authorization: Bearer $accessToken” -d ‘{ “prompt”: “Once upon a time” }’
荣幸的是,这个问题有一个解决办法,而不需要您修改OpenAI SDK。如果您再次查看库中的api_requestor.py文件,您会发现它提供了覆盖要求中传递的headers的能力。
有了这个思路,我做了一些小的修改。我删除api_key属性,并在传递给Azure OpenAI服务API的要求中添加了一个Authorization头,其中包括从AAD返回的访问令牌。
import logging import sys import os import openai from msal import ConfidentialClientApplication def get_sp_access_token(client_id, client_credential, tenant_name, scopes): logging.info(‘Attempting to obtain an access token…’) result = None print(tenant_name) app = ConfidentialClientApplication( client_id=client_id, client_credential=client_credential, authority=f”https://login.microsoftonline.com/{tenant_name}”, ) result = app.acquire_token_for_client(scopes=scopes) if “access_token” in result: logging.info(‘Access token successfully acquired’) return result[‘access_token’] else: logging.error(‘Unable to obtain access token’) logging.error(f”Error was: {result[‘error’]}”) logging.error(f”Error description was: {result[‘error_description’]}”) logging.error(f”Error correlation_id was: {result[‘correlation_id’]}”) raise Exception(‘Failed to obtain access token’) def main(): # 设置日志记录 try: logging.basicConfig( level=logging.ERROR, format=’%asctime)s – %(name)s – %(levelname)s – %(message)s’, handlers=[logging.StreamHandler(sys.stdout)] ) except: logging.error(‘Failed to setup logging: ‘, exc_info=True) try: # 获得访问令牌 token = get_sp_access_token( client_id = os.getenv(‘CLIENT_ID’), client_credential = os.getenv(‘CLIENT_SECRET’), tenant_name = os.getenv(‘TENANT_ID’), scopes = “https://cognitiveservices.azure.com/.default” ) print(token) except: logging.error(‘Failed to obtain access token: ‘, exc_info=True) try: # 设置OpenAI变量 openai.api_type = “azure” openai.api_base = os.getenv(‘OPENAI_API_BASE’) openai.api_key = token openai.api_version = “2023⑴2-01” response = openai.Completion.create( engine=os.getenv(‘DEPLOYMENT_NAME’), prompt=’Once upon a time’, headers={ ‘Authorization’: f’Bearer {token}’ } ) print(response.choices[0].text) except: logging.error(‘Failed to summarize file: ‘, exc_info=True) if __name__ == “__main__”: main()
运行代码的结果是成功的!
2023年4月3日更新-今天我在研究服务的另外一个方面时,发现了关于怎样使用更简单的方法与Azure AD进行身份验证的文档。在下面的代码中,我指定了openai.api_type为azure_ad,这允许我通过openai_api_key属性直接传递令牌,而不需要传递自定义头部。这样会简单一些!
import logging import sys import os import openai from msal import ConfidentialClientApplication def get_sp_access_token(client_id, client_credential, tenant_name, scopes): logging.info(‘Attempting to obtain an access token…’) result = None print(tenant_name) app = ConfidentialClientApplication( client_id=client_id, client_credential=client_credential, authority=f”https://login.microsoftonline.com/{tenant_name}”, ) result = app.acquire_token_for_client(scopes=scopes) if “access_token” in result: logging.info(‘Access token successfully acquired’) return result[‘access_token’] else: logging.error(‘Unable to obtain access token’) logging.error(f”Error was: {result[‘error’]}”) logging.error(f”Error description was: {result[‘error_description’]}”) logging.error(f”Error correlation_id was: {result[‘correlation_id’]}”) raise Exception(‘Failed to obtain access token’) def main(): # 设置日志记录 try: logging.basicConfig( level=logging.ERROR, format=’%asctime)s – %(name)s – %(levelname)s – %(message)s’, handlers=[logging.StreamHandler(sys.stdout)] ) except: logging.error(‘Failed to setup logging: ‘, exc_info=True) try: # 获得访问令牌 token = get_sp_access_token( client_id = os.getenv(‘CLIENT_ID’), client_credential = os.getenv(‘CLIENT_SECRET’), tenant_name = os.getenv(‘TENANT_ID’), scopes = “https://cognitiveservices.azure.com/.default” ) print(token) except: logging.error(‘Failed to obtain access token: ‘, exc_info=True) try: # 设置OpenAI变量 openai.api_type = “azure_ad” openai.api_base = os.getenv(‘OPENAI_API_BASE’) openai.api_key = token openai.api_version = “2023⑴2-01” response = openai.Completion.create( engine=os.getenv(‘DEPLOYMENT_NAME’), prompt=’Once upon a time ‘ ) print(response.choices[0].text) except: logging.error(‘Failed to summarize file: ‘, exc_info=True) if __name__ == “__main__”: main()
让我像ChatGPT一样给你一个摘要,总结一下今天我们学到的东西。
Azure OpenAI服务有管理平面和数据平面。
Azure OpenAI服务的数据平面支持两种身份验证方法,包括静态API密钥和Azure AD。
静态API密钥对数据平面操作具有完全权限。这些密钥应在符合组织密钥轮换政策的框架内进行轮换。
Python的OpenAI SDK(我将假定其他语言也是如此)默许会发送一个api-key头部。可以通过在要求中覆盖头部的方式将其改成发送一个包括从AAD取得的访问令牌的Authorization头部。
建议在可能的情况下使用Azure AD身份验证,以利用Azure AD的所有功能,包括使用托管标识、改进的日志记录和基于服务主体的条件访问。
好了,这就结束了本文。我将在本周晚些时候将上面的代码示例上传到我的GitHub上。在接下来的一篇博文中,我将介绍该服务的授权和日志记录方面。
希望您从中取得了一些价值,并祝您在AI的旅程中好运!
openai.error.permissionerror key based authentication is disabled for this resource的常见问答Q&A
问题1:甚么是“AuthenticationError”?
答案:“AuthenticationError”是一个毛病类型,表示身份验证毛病。它表示你的API密钥或令牌无效、过期或被撤消。这多是由于拼写毛病、格式毛病或安全性问题酿成的。
子点:
- 例子:当你尝试访问Azure OpenAI服务提供的API时,如果你的API密钥不正确或无效,你可能会收到一个AuthenticationError。
- 其他相关信息:为了解决此毛病,你需要确保使用正确的API密钥,并验证其有效性和权限。
问题2:怎样在Azure OpenAI服务中禁用访问密钥身份验证?
答案:要在Azure OpenAI服务中禁用访问密钥身份验证,你可以依照以下步骤进行操作:
- 导航至Azure门户,并打开Azure OpenAI服务实例。
- 找到disableLocalAuth属性,并将其设置为true。
这样就能够禁止基于API密钥的身份验证,并仅允许其他身份验证方法。
子点:
- 例子:在Azure OpenAI服务中,你可以通过在服务实例中设置disableLocalAuth属性为true来禁用API密钥身份验证。
- 其他相关信息:禁用访问密钥身份验证可以提高安全性,并向API访问者提供其他身份验证选项。
问题3:怎么解决Azure OpenAI服务中的”openai.error.AuthenticationError”毛病?
答案:要解决Azure OpenAI服务中的”openai.error.AuthenticationError”毛病,你可以采取以下步骤:
- 确保API密钥或令牌正确并有效。
- 验证API密钥或令牌的权限和访问范围。
- 检查API密钥或令牌会不会已过期或被撤消。
- 确认API密钥或令牌的格式会不会正确。
- 如果使用了其他身份验证方法,请验证其会不会正确配置。
通过履行上述步骤,你应当能够解决”openai.error.AuthenticationError”毛病并成功进行身份验证。
子点:
- 例子:如果你在使用Azure OpenAI服务的API时收到”openai.error.AuthenticationError”毛病,多是由于API密钥无效、过期或权限不正确致使的。
- 其他相关信息:解决此毛病通常触及对API密钥进行验证和配置,以确保其正确性和权限。
问题4:怎么配置Azure OpenAI服务的身份验证?
答案:要配置Azure OpenAI服务的身份验证,你可以依照以下步骤进行操作:
- 导航至Azure门户,并打开Azure OpenAI服务实例。
- 找到身份验证设置,并根据需要进行配置。
- 选择合适你的身份验证方法,如基于API密钥、令牌或其他方式。
- 根据所选的身份验证方法,提供正确的API密钥、令牌或其他凭据。
- 确保所提供的身份验证凭据正确无误并具有正确的权限。
通过依照上述步骤配置身份验证,你可以确保在使用Azure OpenAI服务时进行有效的身份验证。
子点:
- 例子:在Azure OpenAI服务中,你可以通过提供正确的API密钥或令牌来配置身份验证,并根据需要选择其他身份验证选项。
- 其他相关信息:正确配置身份验证可以确保只有经过授权的用户才能访问Azure OpenAI服务的API。