【Azure Developer】Python代码通过AAD认证访问微软Azure密钥保管库(Azure Key Vault)中机密信息(Secret)

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 【Azure Developer】Python代码通过AAD认证访问微软Azure密钥保管库(Azure Key Vault)中机密信息(Secret)

关键字说明

什么是 Azure Active Directory?Azure Active Directory(Azure AD, AAD) 是 Microsoft 的基于云的标识和访问管理服务,可帮助员工登录和访问 Azure 中的资源:

  • 外部资源,例如 Microsoft 365、Azure 门户(https://portal.azure.cn/)以及成千上万的其他 SaaS 应用程序。
  • 内部资源,例如公司网络和 Intranet 上的应用,以及由自己的组织开发的任何云应用。

什么是Azure Key Vault?Azure Key Vault 是一个用于安全地存储和访问机密的云服务。 机密是你想要严格控制对其的访问的任何内容,例如 API 密钥、密码、证书或加密密钥。 Key Vault 服务支持:保管库。 保管库支持存储软件密钥、机密和证书。

  • 机密管理 - Azure Key Vault 可以用来安全地存储令牌、密码、证书、API 密钥和其他机密,并对其访问进行严格控制
  • 密钥管理 - Azure Key Vault 也可用作密钥管理解决方案。 可以通过 Azure Key Vault 轻松创建和控制用于加密数据的加密密钥。
  • 证书管理 - Azure Key Vault 也是一项服务,可用来轻松预配、管理和部署公用和专用传输层安全性/安全套接字层 (TLS/SSL) 证书,以用于 Azure 以及内部连接资源。

 

问题描述

在官方的示例文档中,我们可以发现Python 应用程序以使用 Azure 资源(虚拟机 VM)的托管标识(Identity)从 Azure Key Vault 读取信息,那如果同样的Python应用代码,如果想在非Azure托管的客户端运行,如何来实现呢?如何来解决如下的错误呢?

EnvironmentCredential.get_token failed: EnvironmentCredential authentication unavailable. Environment variables are not fully configured.
ManagedIdentityCredential.get_token failed: ManagedIdentityCredential authentication unavailable, no managed identity endpoint found.
SharedTokenCacheCredential.get_token failed: Azure Active Directory error '(invalid_resource) AADSTS500011: The resource principal named https://vault.azure.cn was not found in 
the tenant named xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You might have sent your authentication request to the wrong tenant.
Trace ID: 11af8f36-693a-4105-8a6c-9e271a1b9f00
Correlation ID: 43cc4c0d-fd23-4b84-a03b-284ff93484a4
Timestamp: 2021-01-16 07:58:47Z'
DefaultAzureCredential.get_token failed: SharedTokenCacheCredential raised unexpected error "Azure Active Directory error '(invalid_resource) AADSTS500011: The resource principal named https://vault.azure.cn was not found in the tenant named xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You might have sent your authentication request to the wrong tenant.
Trace ID: 11af8f36-693a-4105-8a6c-9e271a1b9f00
Correlation ID: 43cc4c0d-fd23-4b84-a03b-284ff93484a4
Timestamp: 2021-01-16 07:58:47Z'"
DefaultAzureCredential failed to retrieve a token from the included credentials.
Attempted credentials:
        EnvironmentCredential: EnvironmentCredential authentication unavailable. Environment variables are not fully configured.
        ManagedIdentityCredential: ManagedIdentityCredential authentication unavailable, no managed identity endpoint found.
        SharedTokenCacheCredential: Azure Active Directory error '(invalid_resource) AADSTS500011: The resource principal named https://vault.azure.cn was not found in the tenant named xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You might have sent your authentication request to the wrong tenant.
Trace ID: 11af8f36-693a-4105-8a6c-9e271a1b9f00
Correlation ID: 43cc4c0d-fd23-4b84-a03b-284ff93484a4
Timestamp: 2021-01-16 07:58:47Z'
Traceback (most recent call last):
  File "case.py", line 26, in <module>
    retrieved_secret = client.get_secret(secretName)
  File "C:\Users\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\azure\core\tracing\decorator.py", line 83, in wrapper_use_tracer
    return func(*args, **kwargs)
  File "C:\Users\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\azure\keyvault\secrets\_client.py", line 67, in get_secret
    bundle = self._client.get_secret(
  File "C:\Users\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\azure\keyvault\secrets\_generated\_operations_mixin.py", line 1475, in get_secret
    return mixin_instance.get_secret(vault_base_url, secret_name, secret_version, **kwargs)
  File "C:\Users\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\azure\keyvault\secrets\_generated\v7_1\operations\_key_vault_client_operations.py", line 276, in get_secret
    pipeline_response = self._client._pipeline.run(request, stream=False, **kwargs)
  File "C:\Users\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\azure\core\pipeline\_base.py", line 211, in run
    return first_node.send(pipeline_request)  # type: ignore
  File "C:\Users\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\azure\core\pipeline\_base.py", line 71, in send
    response = self.next.send(request)
  File "C:\Users\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\azure\core\pipeline\_base.py", line 71, in send
    response = self.next.send(request)
  File "C:\Users\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\azure\core\pipeline\_base.py", line 71, in send
    response = self.next.send(request)
  [Previous line repeated 2 more times]
  File "C:\Users\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\azure\core\pipeline\policies\_redirect.py", line 157, in send
    response = self.next.send(request)
  File "C:\Users\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\azure\core\pipeline\policies\_retry.py", line 436, in send
    response = self.next.send(request)
  File "C:\Users\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\azure\keyvault\secrets\_shared\challenge_auth_policy.py", line 111, in send
    self._handle_challenge(request, challenge)
  File "C:\Users\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\azure\keyvault\secrets\_shared\challenge_auth_policy.py", line 137, in _handle_challenge
    self._token = self._credential.get_token(scope)
  File "C:\Users\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\azure\identity\_credentials\default.py", line 144, in get_token
    return super(DefaultAzureCredential, self).get_token(*scopes, **kwargs)
  File "C:\Users\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.8_qbz5n2kfra8p0\LocalCache\local-packages\Python38\site-packages\azure\identity\_credentials\chained.py", line 90, in get_token
    raise ClientAuthenticationError(message=message)
azure.core.exceptions.ClientAuthenticationError: DefaultAzureCredential failed to retrieve a token from the included credentials.
Attempted credentials:
        EnvironmentCredential: EnvironmentCredential authentication unavailable. Environment variables are not fully configured.
        ManagedIdentityCredential: ManagedIdentityCredential authentication unavailable, no managed identity endpoint found.
        SharedTokenCacheCredential: Azure Active Directory error '(invalid_resource) AADSTS500011: The resource principal named https://vault.azure.cn was not found in the tenant named xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. This can happen if the application has not been installed by the administrator of the tenant or consented to by any user in the tenant. You might have sent your authentication request to the wrong tenant.
Trace ID: 11af8f36-693a-4105-8a6c-9e271a1b9f00
Correlation ID: 43cc4c0d-fd23-4b84-a03b-284ff93484a4
Timestamp: 2021-01-16 07:58:47Z'

解决思路

根据错误提示,需要在Azure AD中为Python应用程序注册一个授权应用(AAD Application)。并获取AAD应用中的客户端访问密码(Secret)客户端ID(Client ID),租户ID(Tenant ID),配置Python应用端的环境变量,调用azure.identity库中的DefaultAzureCredential函数,完成访问Key Vault资源的授权。整个方案需要以下3个关键步骤:

  1. 注册AAD应用并设置客户端密码
  2. 在Key Vault中对AAD应用完成访问授权(Access Policy)
  3. 配置Python应用端的环境变量

下文为整个方案的操作步骤

 

操作步骤

一:注册AAD 应用,复制出应用的关键信息(Client ID, Tenant ID, Object ID)

二:设置AAD 应用客户端密码

  • 在AAD应用页面,进入“证书和密码”页面,点击“新客户端密码”按钮,添加新的Secret(因密码值只能在最开始创建时可见,所以必须在离开页面前复制它

三:在Key Vault中设置访问授权

  • 登录Azure门户,进入Key Vault页面(https://portal.azure.cn/#blade/HubsExtension/BrowseResourceBlade/resourceType/Microsoft.KeyVault%2Fvaults)
  • 选择“Access policies”,点击“Add access policy”,使用第一步中的AAD应用名称或Application ID作为Principal。点击“Add”后“Save”。

四:设置环境变量

使用azure.identity库中的DefaultAzureCredential函数,默认会去检测当前环境中是否包含AZURE_CLIENT_ID,AZURE_TENANT_ID,AZURE_CLIENT_SECRET三个变量。

  • AZURE_CLIENT_ID:第一步中的Client ID
  • AZURE_TENANT_ID:第一步中的Tenant ID
  • AZURE_CLIENT_SECRET:第二步中的Secret Value

五:运行Python应用

可以在代码中输出上一步中设定的环境变量,以验证值是否正确。

import os
import cmd
from azure.keyvault.secrets import SecretClient
from azure.identity import DefaultAzureCredential
# print('AZURE_TENANT_ID:' +os.environ["AZURE_TENANT_ID"])
# print('AZURE_CLIENT_ID:' +os.environ["AZURE_CLIENT_ID"])
# print('AZURE_CLIENT_SECRET:' +os.environ["AZURE_CLIENT_SECRET"])
keyVaultName = 'mykeyvalue01'
secretName = 'mysecret'
KVUri = f"https://{keyVaultName}.vault.azure.cn"
print(KVUri)
credential = DefaultAzureCredential()
token = credential.get_token("https://vault.azure.cn/.default")
print(token)
client = SecretClient(vault_url=KVUri, credential=credential)
retrieved_secret = client.get_secret(secretName)
print(f"Your secret is '{retrieved_secret.value}'.")
print(f"Your secret properties not_before(nbf) is '{retrieved_secret.properties.not_before}'.")
print(f"Your secret properties expires_on is '{retrieved_secret.properties.expires_on}'.")

 

六:附加:如何获取代码中的Token值

DefaultAzureCredential方法返回credential对象,如果需要知道请求中使用的token值,调用get_token方法,同时需要指定scope,如这里使用的为"https://vault.azure.cn/.default"

credential = DefaultAzureCredential()

token = credential.get_token("https://vault.azure.cn/.default")

print(token)

测试结果如图:

 

 

 

附录一:如遗忘以上第三步,没有在Key Vault中对AAD应用赋予访问策略(Access Policy),则获取的错误消息为

azure.core.exceptions.HttpResponseError: (Forbidden) The user, group or application 'appid=xxxxxxxx-05ad-4999-8679-xxxxxxxxxxxx;oid=xxxxxxxx-e256-4650-8ef8-xxxxxxxxxxxx;iss=https://sts.chinacloudapi.cn/xxxxxxxx-66d7-47a8-8f9f-xxxxxxxxxxxx/' does not have secrets get permission on key vault 'keyvault01;location=chinanorth'. For help resolving this issue, please see https://go.microsoft.com/fwlink/?linkid=2125287

 

参考资料

什么是 Azure Active Directory? https://docs.microsoft.com/zh-cn/azure/active-directory/fundamentals/active-directory-whatis

关于 Azure Key Vault: https://docs.azure.cn/zh-cn/key-vault/general/overview

Azure Key Vault 基本概念 : https://docs.azure.cn/zh-cn/key-vault/general/basic-concepts

将 Azure Key Vault 与通过 Python 编写的虚拟机配合使用 :https://docs.azure.cn/zh-cn/key-vault/general/tutorial-python-virtual-machine

DefaultAzureCredential get_token : https://docs.microsoft.com/en-us/python/api/azure-identity/azure.identity.defaultazurecredential?view=azure-python#get-token--scopes----kwargs-

使用Postman获取Azure AD中注册应用程序的授权Token,及为Azure REST API设置Authorization : https://www.cnblogs.com/lulight/p/14279338.html

目录
打赏
0
0
0
0
203
分享
相关文章
【Azure Developer】分享两段Python代码处理表格(CSV格式)数据 : 根据每列的内容生成SQL语句
本文介绍了使用Python Pandas处理数据收集任务中格式不统一的问题。针对两种情况:服务名对应多人拥有状态(1/0表示),以及服务名与人名重复列的情况,分别采用双层for循环和字典数据结构实现数据转换,最终生成Name对应的Services列表(逗号分隔)。此方法高效解决大量数据的人工处理难题,减少错误并提升效率。文中附带代码示例及执行结果截图,便于理解和实践。
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
64 7
【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
实战指南:通过1688开放平台API获取商品详情数据(附Python代码及避坑指南)
1688作为国内最大的B2B供应链平台,其API为企业提供合法合规的JSON数据源,直接获取批发价、SKU库存等核心数据。相比爬虫方案,官方API避免了反爬严格、数据缺失和法律风险等问题。企业接入1688商品API需完成资质认证、创建应用、签名机制解析及调用接口四步。应用场景包括智能采购系统、供应商评估模型和跨境选品分析。提供高频问题解决方案及安全合规实践,确保数据安全与合法使用。立即访问1688开放平台,解锁B2B数据宝藏!
【Azure Developer】编写Python SDK代码实现从China Azure中VM Disk中创建磁盘快照Snapshot
本文介绍如何使用Python SDK为中国区微软云(China Azure)中的虚拟机磁盘创建快照。通过Azure Python SDK的Snapshot Class,指定`location`和`creation_data`参数,使用`Copy`选项从现有磁盘创建快照。代码示例展示了如何配置Default Azure Credential,并设置特定于中国区Azure的`base_url`和`credential_scopes`。参考资料包括官方文档和相关API说明。
|
2月前
|
Python高性能编程:五种核心优化技术的原理与Python代码
Python在高性能应用场景中常因执行速度不及C、C++等编译型语言而受质疑,但通过合理利用标准库的优化特性,如`__slots__`机制、列表推导式、`@lru_cache`装饰器和生成器等,可以显著提升代码效率。本文详细介绍了这些实用的性能优化技术,帮助开发者在不牺牲代码质量的前提下提高程序性能。实验数据表明,这些优化方法能在内存使用和计算效率方面带来显著改进,适用于大规模数据处理、递归计算等场景。
91 5
Python高性能编程:五种核心优化技术的原理与Python代码
Python 高级编程与实战:深入理解性能优化与调试技巧
本文深入探讨了Python的性能优化与调试技巧,涵盖profiling、caching、Cython等优化工具,以及pdb、logging、assert等调试方法。通过实战项目,如优化斐波那契数列计算和调试Web应用,帮助读者掌握这些技术,提升编程效率。附有进一步学习资源,助力读者深入学习。
Python 高级编程与实战:深入理解数据科学与机器学习
本文深入探讨了Python在数据科学与机器学习中的应用,介绍了pandas、numpy、matplotlib等数据科学工具,以及scikit-learn、tensorflow、keras等机器学习库。通过实战项目,如数据可视化和鸢尾花数据集分类,帮助读者掌握这些技术。最后提供了进一步学习资源,助力提升Python编程技能。
|
6天前
|
[oeasy]python074_ai辅助编程_水果程序_fruits_apple_banana_加法_python之禅
本文回顾了从模块导入变量和函数的方法,并通过一个求和程序实例,讲解了Python中输入处理、类型转换及异常处理的应用。重点分析了“明了胜于晦涩”(Explicit is better than implicit)的Python之禅理念,强调代码应清晰明确。最后总结了加法运算程序的实现过程,并预告后续内容将深入探讨变量类型的隐式与显式问题。附有相关资源链接供进一步学习。
19 4

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等