简体   繁体   English

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

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

I am very interested in using the new service recently released for secret management within Azure.我对使用最近发布的用于 Azure 中的机密管理的新服务非常感兴趣。 I have found a few example guides walking through how to interact with key vault via powershell cmdlets and c#, however haven't found much at all in regards to getting started with using the rest API.我找到了一些示例指南,介绍了如何通过 powershell cmdlet 和 c# 与 Key Vault 交互,但是在开始使用 rest API 方面还没有找到太多内容。

The thing I am particularly confused with is the handling of oauth2 w/ active directory.我特别困惑的是对 oauth2 和活动目录的处理。 I have written a oauth2 application listener, built a web application with an AD instance and can now generate a "access_token".我编写了一个 oauth2 应用程序侦听器,使用 AD 实例构建了一个 Web 应用程序,现在可以生成“access_token”。 It is very unclear to me how to proceed beyond this though, as I seem to consistently receive a 401 HTTP resp code whenever attempting to use my access_token to perform a key vault API call.但是,我不清楚如何进行此操作,因为每当尝试使用我的 access_token 执行密钥库 API 调用时,我似乎始终收到 401 HTTP 响应代码。

Any guides / tips on using azure key vault with python would be greatly appreciated!任何有关在 python 中使用 Azure Key Vault 的指南/提示将不胜感激!

Here are some steps you'll need to do before the following code will work... Hopefully I remembered everything!以下是在以下代码生效之前您需要执行的一些步骤...希望我记住了一切!

  1. You'll need to have an application in AD with at least get access您需要在 AD 中有一个应用程序,至少可以访问

    note: you need this to get the CLIENT_ID and CLIENT_SECRET anyway then run:注意:无论如何,您都需要它来获取 CLIENT_ID 和 CLIENT_SECRET 然后运行:

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

  2. You'll also need the id's for your secrets, which you can get with the Azure CLI using:您还需要用于您的机密的 ID,您可以使用 Azure CLI 使用:

    azure keyvault secret show [vault] [secret] azure keyvault 秘密显示 [保险库] [秘密]

    or或者

    azure keyvault secret show -h # if this is unclear azure keyvault secret show -h # 如果不清楚

  3. Copy the key (last argument in the URL)复制密钥(URL 中的最后一个参数)

Then the following code will allow you to query the key vault using oauth2:然后以下代码将允许您使用 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('')

Here are a couple of things that you can check:您可以检查以下几项内容:

  1. When you make the request for the Bearer token, make sure that you include the "resource" header, and that it is set to " https://vault.azure.net ".请求 Bearer 令牌时,请确保包含“资源”标头,并将其设置为“ https://vault.azure.net ”。 If you don't, you'll get a token, but you won't be able to access any vault data with it.如果不这样做,您将获得一个令牌,但您将无法使用它访问任何保险库数据。
  2. When you make a call to the vault.azure.net URL, make sure you include the correct "api-version" It can be found in the API documentation .调用 vault.azure.net URL 时,请确保包含正确的“api-version”。它可以在API 文档中找到。 The current value is "2015-02-01-preview".当前值为“2015-02-01-preview”。
  3. Of course, check that the Key Vault Access Policy is set correctly for the vault you are trying to access.当然,请检查是否为您尝试访问的保管库正确设置了 Key Vault 访问策略。

For working with Key Vault's REST API, there's reference documentation and service documentation that should help.对于使用 Key Vault 的 REST API,参考文档服务文档应该会有所帮助。

Using Key Vault with Python is now more easily done with the Azure SDK.现在通过 Azure SDK 可以更轻松地将 Key Vault 与 Python 结合使用。 There are three Python packages for working with existing vault data, and one for creating/managing vaults:有三个 Python 包用于处理现有的保管库数据,一个用于创建/管理保管库:

azure-identity is also the package that should be used with these for authentication. azure-identity也是应该与这些一起用于身份验证的包。

With the SDK, using an access token to work with an existing vault from an authorized application is as easy as creating a credential and client:借助 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")

(I work on the Azure SDK in Python) (我使用 Python 开发 Azure SDK)

When Key Vault returns a 401 response, it includes a www-authenticate header containing authority and resource.当 Key Vault 返回 401 响应时,它包含一个包含权限和资源的www-authenticate标头。 You must use both to get a valid bearer token.您必须同时使用两者才能获得有效的不记名令牌。 Then you can redo your request with that token, and if you use the same token on subsequent requests against the same vault, it shouldn't return a 401 until the token expires.然后您可以使用该令牌重做您的请求,并且如果您在针对同一保管库的后续请求中使用相同的令牌,则在令牌到期之前它不应返回 401。

You can know the authority and resource in advance, but it's generally more robust to prepare your code to always handle the 401, specially if you use multiple vaults.您可以提前知道权限和资源,但准备您的代码以始终处理 401 通常会更健壮,特别是在您使用多个保管库时。

Be sure to only trust on a www-authenticate header of a valid SSL connection, otherwise you might be a victim of spoofing!确保只信任有效 SSL 连接的www-authenticate标头,否则您可能成为欺骗的受害者!

I have written a simple python wrapper for the REST APIs for Azure Key Vault.我为 Azure Key Vault 的 REST API 编写了一个简单的 Python 包装器。 You can check out out here AzureKeyVaultPythonSDK您可以在此处查看AzureKeyVaultPythonSDK

Crust of the logic is here逻辑的外壳在这里

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