2015-03-19 5 views
2

Je suis très intéressé par l'utilisation du nouveau service récemment publié pour la gestion secrète dans Azure. J'ai trouvé quelques exemples de guides expliquant comment interagir avec le coffre-fort par l'intermédiaire de cmdlets powershell et C#, mais je n'ai pas trouvé grand-chose pour commencer à utiliser l'API de repos.Interaction avec Azure Key Vault à l'aide de python w/rest api

Ce qui me dérange particulièrement, c'est la gestion de oauth2 w/Active Directory. J'ai écrit un écouteur d'application oauth2, construit une application web avec une instance AD ​​et peux maintenant générer un "access_token". Je ne comprends pas très bien comment aller au-delà de cela, car il semble que je reçoive toujours un code resp. HTTP 401 chaque fois que j'utilise access_token pour effectuer un appel API de coffre-fort.

Tous les guides/conseils sur l'utilisation de voûte de clé azur avec python seraient grandement appréciés!

Répondre

1

Voici quelques choses que vous pouvez vérifier:

  1. Lorsque vous faites la demande pour le jeton au porteur, assurez-vous que vous incluez l'en-tête « ressource », et qu'il est réglé sur "https://vault.azure.net ". Si vous ne le faites pas, vous recevrez un jeton, mais vous ne pourrez pas accéder aux données du coffre-fort.
  2. Lorsque vous appelez l'URL vault.azure.net, assurez-vous d'inclure la "version api" correcte. Elle se trouve dans le API documentation. La valeur actuelle est "2015-02-01-preview".
  3. Bien sûr, vérifiez que la stratégie d'accès au coffre-fort est définie correctement pour le coffre auquel vous essayez d'accéder.
0

Lorsque le coffre-fort renvoie une réponse 401, il contient un en-tête www-authenticate contenant l'autorité et la ressource. Vous devez utiliser les deux pour obtenir un jeton de porteur valide. Ensuite, vous pouvez refaire votre requête avec ce jeton, et si vous utilisez le même jeton sur des requêtes ultérieures sur le même coffre-fort, il ne doit pas renvoyer de jeton 401 tant que le jeton n'a pas expiré.

Vous pouvez connaître l'autorité et la ressource à l'avance, mais il est généralement plus robuste de préparer votre code pour toujours gérer le 401, spécialement si vous utilisez plusieurs coffres.

Assurez-vous de ne faire confiance que sur une en-tête www-authenticate d'une connexion SSL, sinon vous risquez d'être victime d'usurpation d'identité!

5

Voici quelques étapes que vous devrez suivre avant que le code suivant ne fonctionne ... J'espère me souvenir de tout!

  1. Vous aurez besoin d'avoir une application en l'an avec au moins avoir accès

    Note: vous aurez besoin pour obtenir le CLIENT_ID et CLIENT_SECRET de toute façon puis exécutez:

    SEt- d'azur keyvault policy --vault-name 'VAULTNAME' --spn CLIENT_ID --perms-to-secrets '["get"]'

  2. Vous aurez également besoin des identifiants pour vos secrets, que vous pouvez obtenir avec Azure CLI utilisant:

    azur spectacle secret keyvault [voûte] [secrète]

    ou

    show secret, keyvault azur -h # si cela ne sait pas

  3. Copiez la clé (dernier argument dans l'URL)

ensuite le code suivant vous permettra d'interroger la voûte clé à l'aide 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

il semble que je ne peux pas se connecter et obtenir le access_token avec ce code. – Wizmann

+0

@Wizmann quelle réponse obtenez-vous? –

+0

@Peregrinus la réponse de "request.post" n'a pas de clé "access_token". c'est peut-être parce que je lie mon coffre-fort avec une AD non-par défaut. – Wizmann

0

J'ai écrit un simple wrapper python pour les API REST pour Azure Key Vault. Vous pouvez consulter ici AzureKeyVaultPythonSDK

Crust de la logique est ici

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")