外部資源,例如 Microsoft 36五、Azure 門戶(https://portal.azure.cn/)以及成千上萬的其餘 SaaS 應用程序。html
內部資源,例如公司網絡和 Intranet 上的應用,以及由本身的組織開發的任何雲應用。node
在官方的示例文檔中,咱們能夠發現Python 應用程序以使用 Azure 資源(虛擬機 VM)的託管標識(Identity)從 Azure Key Vault 讀取信息,那若是一樣的Python應用代碼,若是想在非Azure託管的客戶端運行,如何來實現呢?如何來解決以下的錯誤呢?python
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個關鍵步驟:api
下文爲整個方案的操做步驟安全
使用azure.identity庫中的DefaultAzureCredential函數,默認會去檢測當前環境中是否包含AZURE_CLIENT_ID,AZURE_TENANT_ID,AZURE_CLIENT_SECRET三個變量。網絡
能夠在代碼中輸出上一步中設定的環境變量,以驗證值是否正確。app
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}'.")
DefaultAzureCredential方法返回credential對象,若是須要知道請求中使用的token值,調用get_token方法,同時須要指定scope,如這裏使用的爲"https://vault.azure.cn/.default"ide
credential = DefaultAzureCredential() token = credential.get_token("https://vault.azure.cn/.default") print(token)
測試結果如圖:函數
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 : http://www.javashuo.com/article/p-waqgmoyh-nz.html