Skip to content

Latest commit

 

History

History
125 lines (99 loc) · 5.67 KB

migration_guide.md

File metadata and controls

125 lines (99 loc) · 5.67 KB

Guide for migrating to azure-identity from azure-common

The newest Azure SDK libraries (the "client" and "management" libraries listed here) use credentials from azure-identity to authenticate requests. Older versions of these libraries typically used credentials from azure-common. Credential types from these two libraries have different APIs, causing clients to raise AttributeError when given a credential from the wrong library. For example, a client expecting an azure-identity credential will raise an error like 'ServicePrincipalCredentials' object has no attribute 'get_token' when given a credential from azure-common. A client expecting an azure-common credential will raise an error like 'ClientSecretCredential' object has no attribute 'signed_session' when given an azure-identity credential.

This document shows common authentication code using azure-common, and its equivalent using azure-identity.

Service principal authentication

azure-common uses ServicePrincipalCredentials to authenticate a service principal:

from azure.common.credentials import ServicePrincipalCredentials

credential = ServicePrincipalCredentials(client_id, client_secret, tenant=tenant_id)

azure-identity uses ClientSecretCredential :

from azure.identity import ClientSecretCredential

credential = ClientSecretCredential(tenant_id, client_id, client_secret)

Authenticating through the Azure CLI

azure-common provides the get_client_from_cli_profile function to integrate with the Azure CLI for authentication. This code works with older versions of azure-mgmt-resource such as 10.0.0:

from azure.common.client_factory import get_client_from_cli_profile
from azure.mgmt.resource import SubscriptionClient

subscription_client = get_client_from_cli_profile(SubscriptionClient)

azure-identity integrates with the Azure CLI through its AzureCliCredential. This code works with newer versions of azure-mgmt-resource, starting with 15.0.0:

from azure.identity import AzureCliCredential
from azure.mgmt.resource import SubscriptionClient

credential = AzureCliCredential()
subscription_client = SubscriptionClient(credential)

JSON- and file-based authentication

To encourage best security practices, azure-identity does not support JSON- and file-based authentication in the same way as azure-common. azure-common provided factory methods like get_client_from_json_dict and get_client_from_auth_file that are no longer available in azure-identity.

In azure-common you could provide credentials in a JSON dictionary, or from a JSON file:

from azure.common.client_factory import get_client_from_json_dict, get_client_from_auth_file
from azure.mgmt.keyvault import KeyVaultManagementClient
# Provide credentials in JSON:
json_dict = {
    "clientId": "...",
    "clientSecret": "...",
    "subscriptionId": "...",
    "tenantId": "...",
    "activeDirectoryEndpointUrl": "https://login.microsoftonline.com",
    "resourceManagerEndpointUrl": "https://management.azure.com"
}
client = get_client_from_json_dict(KeyVaultManagementClient, json_dict)
# Or, provide credentials from a JSON file:
client = get_client_from_auth_file(KeyVaultManagementClient, "credentials.json")

If it's not possible to immediately migrate from file-based authentication, you can still use azure-identity. With a JSON file containing your credentials, you can use json.load to authenticate a service principal with a ClientSecretCredential:

import json
from azure.identity import ClientSecretCredential
from azure.mgmt.keyvault import KeyVaultManagementClient

with open("credentials.json") as json_file:
    json_dict = json.load(json_file)

credential = ClientSecretCredential(
    tenant_id=json_dict["tenantId"],
    client_id=json_dict["clientId"],
    client_secret=json_dict["clientSecret"],
    authority=json_dict["activeDirectoryEndpointUrl"]
)
client = KeyVaultManagementClient(
    credential,
    json_dict["subscriptionId"],
    base_url=json_dict["resourceManagerEndpointUrl"],
    credential_scopes=["{}/.default".format(json_dict["resourceManagerEndpointUrl"])]
)

If storing credentials in a file, be sure to protect access to this file. Make certain that it's excluded by version control -- for example, by adding the credential file name to your project's .gitignore file.

The global documentation for authenticating Python apps on Azure is available here.

Impressions