2015-03-19 4 views
2

Мне очень интересно использовать новый сервис, недавно выпущенный для секретного управления в Azure. Я нашел несколько примеров руководств, которые идут по тому, как взаимодействовать с ключевыми хранилищами с помощью командлетов powershell и C#, однако не нашли ничего общего с тем, чтобы начать работу с использованием остального API.Взаимодействие с Azure Key Vault с использованием python w/rest api

То, что меня особенно смущает, это обращение с oauth2 w/active directory. Я написал прослушиватель приложений oauth2, создал веб-приложение с экземпляром AD и теперь может генерировать «access_token». Мне очень не ясно, как действовать дальше этого, хотя, по-видимому, я последовательно получаю код 401 HTTP resp при попытке использовать мой access_token для выполнения вызова API ключа хранилища.

Любые руководства/советы по использованию лазурного ключа-хранилища с помощью python были бы очень признательны!

ответ

1

Вот несколько вещей, которые вы можете проверить:

  1. Когда вы делаете запрос на маркер однонаправленного канала, убедитесь, что вы включаете заголовок «ресурс», и что он установлен на "https://vault.azure.net ». Если вы этого не сделаете, вы получите токен, но вы не сможете получить к нему какие-либо данные хранилища.
  2. Когда вы делаете звонок на адрес vault.azure.net, убедитесь, что вы указали правильную «api-версию». Ее можно найти в файле API documentation. Текущее значение - «2015-02-01-preview».
  3. Конечно, убедитесь, что политика доступа к хранилищу ключей установлена ​​правильно для хранилища, к которому вы пытаетесь получить доступ.
0

Когда Key Vault возвращает ответ 401, он включает заголовок www-authenticate, содержащий полномочия и ресурс. Вы должны использовать оба, чтобы получить действительный токен на предъявителя. Затем вы можете повторить свой запрос с этим токеном, и если вы используете тот же токен при последующих запросах в том же хранилище, он не должен возвращать 401 до истечения срока действия токена.

Вы можете заранее знать полномочия и ресурсы, но, как правило, более надежны, чтобы подготовить код, чтобы всегда обрабатывать 401, особенно если вы используете несколько хранилищ.

Обязательно доверяйте только заголовку www-authenticate действительного SSL-соединения, иначе вы можете стать жертвой подмены!

5

Вот несколько шагов, которые вам нужно будет сделать, прежде чем следующий код будет работать ... Надеюсь, я все вспомнил!

  1. Вы должны иметь приложение в AD, по крайней мере, получить доступ

    Примечание: вам это нужно, чтобы получить CLIENT_ID и client_secret все равно затем запустить:

    лазурное keyvault комплект- policy --vault-name 'VAULTNAME' --spn CLIENT_ID --перм-секреты '["get"]'

  2. Вам также понадобится идентификатор для ваших секретов, который вы можете получить с помощью Azure CLI с использованием:

    лазурь keyvault секрет шоу [хранилище] [секрет]

    или

    лазурь keyvault секрет шоу -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('') 
+0

, кажется, что я не могу войти и получить access_token с этим кодом. – Wizmann

+0

@Wizmann какой ответ вы получаете? –

+0

@Peregrinus ответ «request.post» не имеет ключа «access_token». возможно, это связано с тем, что я привязываю свой ключ-хранилище с нестандартным AD. – Wizmann

0

Я написал простую оболочку python для API REST для Azure Key Vault. Вы можете проверить здесь 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") 
Смежные вопросы