簡體   English   中英

使用 python w/rest api 與 Azure Key Vault 交互

[英]Interacting with Azure Key Vault using python w/ rest api

我對使用最近發布的用於 Azure 中的機密管理的新服務非常感興趣。 我找到了一些示例指南,介紹了如何通過 powershell cmdlet 和 c# 與 Key Vault 交互,但是在開始使用 rest API 方面還沒有找到太多內容。

我特別困惑的是對 oauth2 和活動目錄的處理。 我編寫了一個 oauth2 應用程序偵聽器,使用 AD 實例構建了一個 Web 應用程序,現在可以生成“access_token”。 但是,我不清楚如何進行此操作,因為每當嘗試使用我的 access_token 執行密鑰庫 API 調用時,我似乎始終收到 401 HTTP 響應代碼。

任何有關在 python 中使用 Azure Key Vault 的指南/提示將不勝感激!

以下是在以下代碼生效之前您需要執行的一些步驟...希望我記住了一切!

  1. 您需要在 AD 中有一個應用程序,至少可以訪問

    注意:無論如何,您都需要它來獲取 CLIENT_ID 和 CLIENT_SECRET 然后運行:

    azure keyvault set-policy --vault-name 'VAULTNAME' --spn CLIENT_ID --perms-to-secrets '["get"]'

  2. 您還需要用於您的機密的 ID,您可以使用 Azure CLI 使用:

    azure keyvault 秘密顯示 [保險庫] [秘密]

    或者

    azure keyvault secret show -h # 如果不清楚

  3. 復制密鑰(URL 中的最后一個參數)

然后以下代碼將允許您使用 oauth2 查詢密鑰保管庫:

import json
import requests

AUTHORITY_HOST = "login.windows.net"
TENANT_ID      = < your tenant id >
CLIENT_ID      = < your client id >
CLIENT_SECRET  = < your client secret >
VAULT          = 'MyVault'

data = { "grant_type" : "client_credentials", 
        "client_id" : CLIENT_ID, 
        "client_secret" : CLIENT_SECRET, 
        "resource" : "https://vault.azure.net"
    }

secrets = [( "i_like_pie", "8a7680a2cf5e4d539494aa0ce265297" )]

headers = { "Content-Type" : "application/x-www-form-urlencoded" }

r = requests.post("https://login.windows.net/{}/oauth2/token".format(TENANT_ID), data=data, headers=headers)
access_token = r.json()['access_token']

for secret, secret_id in secrets.iteritems():

    headers = {"Authorization":"Bearer {}".format(access_token) }
    r = requests.get('https://{}.vault.azure.net/secrets/{}/{}?api-version=2015-06-01'.format(VAULT, secret, secret_id), headers=headers)

    print('##### {} #####'.format(secret))
    print(r.json())
    print('')

您可以檢查以下幾項內容:

  1. 請求 Bearer 令牌時,請確保包含“資源”標頭,並將其設置為“ https://vault.azure.net ”。 如果不這樣做,您將獲得一個令牌,但您將無法使用它訪問任何保險庫數據。
  2. 調用 vault.azure.net URL 時,請確保包含正確的“api-version”。它可以在API 文檔中找到。 當前值為“2015-02-01-preview”。
  3. 當然,請檢查是否為您嘗試訪問的保管庫正確設置了 Key Vault 訪問策略。

對於使用 Key Vault 的 REST API,參考文檔服務文檔應該會有所幫助。

現在通過 Azure SDK 可以更輕松地將 Key Vault 與 Python 結合使用。 有三個 Python 包用於處理現有的保管庫數據,一個用於創建/管理保管庫:

azure-identity也是應該與這些一起用於身份驗證的包。

借助 SDK,使用訪問令牌處理來自授權應用程序的現有保管庫就像創建憑據和客戶端一樣簡單:

from azure.identity import DefaultAzureCredential
from azure.keyvault.secrets import SecretClient

credential = DefaultAzureCredential()
client = SecretClient("https://{vault-name}.vault.azure.net", credential)
secret = client.get_secret("secret-name")

(我使用 Python 開發 Azure SDK)

當 Key Vault 返回 401 響應時,它包含一個包含權限和資源的www-authenticate標頭。 您必須同時使用兩者才能獲得有效的不記名令牌。 然后您可以使用該令牌重做您的請求,並且如果您在針對同一保管庫的后續請求中使用相同的令牌,則在令牌到期之前它不應返回 401。

您可以提前知道權限和資源,但准備您的代碼以始終處理 401 通常會更健壯,特別是在您使用多個保管庫時。

確保只信任有效 SSL 連接的www-authenticate標頭,否則您可能成為欺騙的受害者!

我為 Azure Key Vault 的 REST API 編寫了一個簡單的 Python 包裝器。 您可以在此處查看AzureKeyVaultPythonSDK

邏輯的外殼在這里

class AzureKeyVaultManager(object):

section_name="KeyVaultSection"

# Constructor
def __init__(self, fileName="private.properties"):
    prop_file=os.path.dirname(os.path.realpath(sys.argv[0])) + "/" + fileName
    config = ConfigParser.RawConfigParser()
    config.read(prop_file)
    self.client_id=config.get(self.section_name,'client.id')
    self.client_secret=config.get(self.section_name,'client.secret')
    self.tenant_id=config.get(self.section_name,'tenant.id')
    self.resource=config.get(self.section_name,'resource')
    self.key_vault=config.get(self.section_name,'key.vault')

# Authenticate
def initialize(self):
    if self.client_id and self.client_secret and self.tenant_id and self.resource and self.key_vault:
        print "Got all the properties from file "
        token_url="https://login.windows.net/{0}/oauth2/token".format(self.tenant_id)
        payload = {'client_id':self.client_id, 'client_secret':self.client_secret, 'resource':self.resource, 'grant_type':'client_credentials'}
        response=requests.post(token_url, data=payload).json()
        self.access_token=response['access_token']
    else:
        raise ValueError("Couldn't get the key vault properties from properties file")

# Get secret from a specific keyvault
def getSecretFromKeyVault(self, secretName, keyVault=None):
    if keyVault is None:
        keyVault=self.key_vault

    endpoint = 'https://{0}.vault.azure.net/secrets/{1}?api-version=2015-06-01'.format(keyVault, secretName)
    headers = {"Authorization": 'Bearer ' + self.access_token}
    response = requests.get(endpoint,headers=headers).json()

    if 'value' in response:
        return response['value']
    else:
        raise ValueError("Value not found in response")

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM