2

Using the Azure Python SDK, I would like to return a KeyVaultClient using the get_client_from_auth_file method in order to get secrets from a KeyVault without going through a KeyVaultManagementClient.

According to the documentation, it appears to be possible to create a client from any SDK client class.

I am able to do this:

from azure.common.client_factory import get_client_from_auth_file
from azure.mgmt.keyvault import KeyVaultManagementClient
_kv_mgmt_client = get_client_from_auth_file(KeyVaultManagementClient)

but not this:

from azure.common.client_factory import get_client_from_auth_file
from azure.keyvault import KeyVaultClient
_kv_client = get_client_from_auth_file(KeyVaultClient)

This is the error message: TypeError: __init__() got an unexpected keyword argument 'base_url'

Update:

Upon review, get_client_from_auth_file returns several results including base_url, so the following helper function resolves the TypeError.

class KeyVaultClientHelper:
    def __init__(self, credentials, **kwargs):
        self._credentials = credentials

And the KeyVaultClient is successful until it tries to get a secret and it returns Unauthorized.

helper = get_client_from_auth_file(KeyVaultClientHelper)
client = KeyVaultClient(helper._credentials)
print(client.get_secret("http://my-vault-url...", "MY-KEY", '').value))

However, I am successful in getting secrets using a ServicePrincipalCredential with the same auth file.

Laurent Mazuel
  • 3,422
  • 13
  • 27
  • Hi Kristin, please open an issue https://github.com/Azure/azure-sdk-for-python/issues (I work at MS and wrote get_client_from_auth_file). I will investigate asap. Thank you. – Laurent Mazuel Jun 05 '19 at 16:57
  • Okay thanks @LaurentMazuel, just did! [link](https://github.com/Azure/azure-sdk-for-python/issues/5710) – Kristin Ottofy Jun 06 '19 at 17:11

2 Answers2

2

this was a bug in azure-common, fixed in 1.1.22: https://pypi.org/project/azure-common/1.1.22/

Thanks!

Laurent Mazuel
  • 3,422
  • 13
  • 27
-1

Kristin,

you can try something like below, it has a working sample for getting the keyvault client

import adal

from azure.keyvault import KeyVaultClient, KeyVaultAuthentication
from azure.common.credentials import ServicePrincipalCredentials
from msrestazure.azure_active_directory import AADTokenCredentials

client_id = '<client_id>'
client_secret = '<client_secret>'
tenant = '<tenant>'
vault_address = '<vault_address>'
secret_name = '<secret_name>'

resource_uri = 'https://vault.azure.net'

def auth_with_adal(server, resource, scope):
    authority_host_uri = 'https://login.windows.net'
    authority_uri = authority_host_uri + '/' + tenant

    context = adal.AuthenticationContext(authority_uri, api_version=None)
    mgmt_token = context.acquire_token_with_client_credentials(resource_uri, client_id, client_secret)
    credentials = AADTokenCredentials(mgmt_token, client_id)
    token = credentials.token
    return token['token_type'], token['access_token']

def auth_with_spc(server, resource, scope):
    credentials = ServicePrincipalCredentials(
        client_id = client_id,
        secret = client_secret,
        tenant = tenant,
        resource = resource_uri
    )
    token = credentials.token
    return token['token_type'], token['access_token']

try:
    client = KeyVaultClient(KeyVaultAuthentication(auth_with_adal))
    secret_bundle = client.get_secret(vault_address, secret_name, '')
    print('1) I got the secret using AADTokenCredentials!')
except Exception as e:
    print('1) Failed to get a secret!')
    print(e)

try:
    client = KeyVaultClient(KeyVaultAuthentication(auth_with_spc))
    secret_bundle = client.get_secret(vault_address, secret_name, '')
    print('2) I got the secret using ServicePrincipalCredentials!')
except Exception as e:
    print('2) Failed to get a secret!')
    print(e)

You can use below function to achieve it.

client = KeyVaultClient(KeyVaultAuthentication(auth_with_spc))

Hope it helps.

Mohit Verma
  • 5,140
  • 2
  • 12
  • 27
  • Thanks for the answer, @Mohit Verma - MSFT! However, I can't mark this as the answer as it doesn't use the function `get_client_from_auth_file`. – Kristin Ottofy Jun 04 '19 at 13:45