Autentisera Python-appar till Azure-tjänster under lokal utveckling med hjälp av tjänstens huvudnamn

Utvecklare behöver ofta köra och testa sina appar lokalt när de skapar molnprogram. Även under den lokala utvecklingen måste programmet autentiseras mot alla Azure-tjänster som det interagerar med. Den här artikeln beskriver hur du konfigurerar dedikerade identiteter för tjänstens huvudnamn specifikt för användning under lokal utveckling.

Ett diagram som visar hur en app som körs i den lokala utvecklaren hämtar programtjänstens huvudnamn från en .env-fil och sedan använder den identiteten för att ansluta till Azure-resurser.

Dedikerade programtjänsthuvudnamn för lokal utveckling följer principen om lägsta behörighet. De beviljar endast åtkomst till de Azure-resurser som appen behöver under utvecklingen. Den här begränsade åtkomsten minskar risken för att oavsiktligt nå andra resurser. Det hjälper också till att förhindra behörighetsrelaterade buggar när du flyttar till produktion, där bredare behörigheter kan orsaka problem.

När du registrerar program för lokal utveckling i Azure:

  • Skapa separata appregistreringar för varje utvecklare: Den här metoden ger varje utvecklare ett eget huvudnamn för tjänsten, vilket undviker behovet av att dela autentiseringsuppgifter och aktivera mer detaljerad åtkomstkontroll.
  • Skapa separata appregistreringar för varje program: Den här metoden säkerställer att varje app bara har de behörigheter den behöver, vilket minskar den potentiella attackytan.

Om du vill aktivera autentisering under lokal utveckling anger du miljövariabler med autentiseringsuppgifterna för programtjänstens huvudnamn. Azure SDK för Python identifierar dessa variabler och använder dem för att autentisera begäranden till Azure-tjänster.

Registrera programmet i Azure

Huvudobjekt för programtjänsten skapas när du registrerar en app i Azure. Den här registreringen kan utföras med antingen Azure-portalen eller Azure CLI. Registreringsprocessen skapar en appregistrering i Microsoft Entra-ID och genererar ett tjänsthuvudnamn-objekt för appen. Tjänsthuvudobjektet används för att autentisera appen mot Azure-tjänster. Appregistreringsprocessen genererar också en klienthemlighet (lösenord) för appen. Den här hemligheten används för att autentisera appen till Azure-tjänster. Klienthemligheten lagras aldrig i källkontrollen, utan i stället i en .env fil i programkatalogen. Vid körning läser programmet filen .env och ställer in miljövariabler som Azure SDK för Python använder för att autentisera programmet.

Följande steg visar hur du registrerar en app i Azure och skapar ett huvudnamn för tjänsten för appen. Stegen visas för både Azure CLI och Azure-portalen.

Azure CLI-kommandon kan köras i Azure Cloud Shell eller på en arbetsstation med Azure CLI installerat.

Använd först kommandot az ad sp create-for-rbac för att skapa ett nytt huvudnamn för tjänsten för appen. Kommandot skapar även appregistreringen för appen samtidigt.

SERVICE_PRINCIPAL_NAME=<service-principal-name>
az ad sp create-for-rbac --name $SERVICE_PRINCIPAL_NAME

Utdata från det här kommandot liknar följande. Anteckna dessa värden eller håll det här fönstret öppet eftersom du behöver dessa värden i nästa steg och inte kan visa lösenordet (klienthemligheten) igen. Du kan dock lägga till ett nytt lösenord senare utan att ogiltigförklara tjänstens huvudnamn eller befintliga lösenord om det behövs.

{
  "appId": "00001111-aaaa-2222-bbbb-3333cccc4444",
  "displayName": "<service-principal-name>",
  "password": "Ee5Ff~6Gg7.-Hh8Ii9Jj0Kk1Ll2Mm3_Nn4Oo5Pp6",
  "tenant": "aaaabbbb-0000-cccc-1111-dddd2222eeee"
}

Därefter måste du hämta appID värdet och lagra det i en variabel. Det här värdet används för att ange miljövariabler i din lokala utvecklingsmiljö så att Azure SDK för Python kan autentisera till Azure med tjänstens huvudnamn.

APP_ID=$(az ad sp list \
  --all \
  --query "[?displayName=='$SERVICE_PRINCIPAL_NAME'].appId | [0]" \
  --output tsv)

Skapa en Microsoft Entra-säkerhetsgrupp för lokal utveckling

Eftersom flera utvecklare vanligtvis arbetar med samma program är det bättre att hantera behörigheter via en Microsoft Entra-säkerhetsgrupp. Skapa en säkerhetsgrupp som innehåller de roller som appen behöver för lokal utveckling, i stället för att tilldela roller till varje utvecklares tjänstens huvudprincip individuellt. Att använda en säkerhetsgrupp ger följande fördelar:

  • Varje utvecklare är säker på att ha samma roller tilldelade eftersom roller tilldelas på gruppnivå.
  • Om en ny roll behövs för appen behöver den bara läggas till i Microsoft Entra-gruppen för appen.
  • Om en ny utvecklare ansluter till teamet skapas ett nytt huvudnamn för programtjänsten för utvecklaren och läggs till i gruppen, vilket säkerställer att utvecklaren har rätt behörighet att arbeta med appen.

Kommandot az ad group create används för att skapa säkerhetsgrupper i Microsoft Entra-ID. Parametrarna --display-name och --main-nickname krävs. Namnet som ges till gruppen ska baseras på namnet på programmet. Det är också användbart att inkludera en fras som "local-dev" i gruppens namn för att ange syftet med gruppen.

GROUP_DISPLAY_NAME="<group-name>"
GROUP_MAIL_NICKNAME="<group-mail-nickname>"
GROUP_DESCRIPTION="<group-description>"
az ad group create \
  --display-name $GROUP_DISPLAY_NAME \
  --mail-nickname $GROUP_MAIL_NICKNAME \
  --description $GROUP_DESCRIPTION

Om du vill lägga till medlemmar i gruppen behöver du objekt-ID:t för programtjänstens huvudnamn, som skiljer sig från program-ID:t. Använd az ad sp list för att lista de tillgängliga tjänsteprincipalerna. Parameterkommandot --filter accepterar OData-formatfilter och kan användas för att filtrera listan som visas. Parametern --query begränsar kolumnerna till endast de som du är intresserad av.

SP_OBJECT_ID=$(az ad sp list \
  --filter "startswith(displayName,'$GROUP_DISPLAY_NAME')" \
  --query "[0].id" \
  --output tsv)

Kommandot az ad group member add kan sedan användas för att lägga till medlemmar i grupper.

az ad group member add \
    --group $GROUP_DISPLAY_NAME \
    --member-id $SP_OBJECT_ID

Kommentar

Som standard är skapandet av Microsoft Entra-säkerhetsgrupper begränsat till vissa privilegierade roller i en katalog. Om du inte kan skapa en grupp kontaktar du en administratör för din katalog. Om du inte kan lägga till medlemmar i en befintlig grupp kontaktar du gruppägaren eller en katalogadministratör. Mer information finns i Hantera Microsoft Entra-grupper och gruppmedlemskap.

Tilldela roller till programmet

Därefter måste du bestämma vilka roller (behörigheter) din app behöver på vilka resurser och tilldela dessa roller till din app. I det här exemplet tilldelas rollerna till den Microsoft Entra-grupp som skapades i steg 2. Roller kan tilldelas i ett resurs-, resursgrupps- eller prenumerationsomfång. Det här exemplet visar hur du tilldelar roller i resursgruppens omfång eftersom de flesta program grupperar alla sina Azure-resurser i en enda resursgrupp.

az role assignment create Använd kommandot för att tilldela en roll till en användare, grupp eller programtjänstens huvudnamn. Du kan ange en grupp med dess objekt-ID. Du kan ange ett huvudnamn för programtjänsten med dess appId.

RESOURCE_GROUP_NAME=<resource-group-name>
SUBSCRIPTION_ID=$(az account show --query id --output tsv)
ROLE_NAME=<role-name>
az role assignment create \
  --assignee "$APP_ID" \
  --scope "./subscriptions/$SUBSCRIPTION_ID/resourceGroups/$RESOURCE_GROUP_NAME" \
  --role "$ROLE_NAME"

![!OBS] För att förhindra att Git Bash behandlar /subscriptions/... som en filsökväg, lägg till i början ./ till strängen för parametern scope och använd dubbla citattecken runt hela strängen.

Om du vill hämta de rollnamn som kan tilldelas använder du kommandot az role definition list .

az role definition list \
    --query "sort_by([].{roleName:roleName, description:description}, &roleName)" \
    --output table

Om du till exempel vill tillåta programtjänstens huvudnamn med appId för läs-, skriv- och borttagningsåtkomst 00001111-aaaa-2222-bbbb-3333cccc4444 till Azure Storage-blobcontainrar och data i alla lagringskonton i resursgruppen msdocs-python-sdk-auth-example i prenumerationen med ID aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e, tilldelar du programtjänstens huvudnamn till rollen Storage Blob Data Contributor med hjälp av följande kommando.

az role assignment create --assignee 00001111-aaaa-2222-bbbb-3333cccc4444 \
    --scope "./subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e/resourceGroups/msdocs-python-sdk-auth-example" \
    --role "Storage Blob Data Contributor"

Information om hur du tilldelar behörigheter på resurs- eller prenumerationsnivå med hjälp av Azure CLI finns i artikeln Tilldela Azure-roller med Hjälp av Azure CLI.

Ange miljövariabler för lokal utveckling

Objektet DefaultAzureCredential söker efter informationen om tjänstens huvudnamn i en uppsättning miljövariabler vid körning. Eftersom de flesta utvecklare arbetar med flera applikationer bör du använda ett verktyg som python-dotenv för att komma åt miljödata från en .env fil lagrad i applikationens katalog under utveckling. Den här konfigurationen omfattar miljövariablerna så att endast det här programmet kan använda dem för att autentisera till Azure.

Filen .env checkas aldrig in i källkontrollen eftersom den innehåller programhemlighetsnyckeln för Azure. Standardfilen .gitignore för Python undantar .env automatiskt filen från incheckningen.

Om du vill använda python-dotenv-paketet installerar du först paketet i ditt program.

pip install python-dotenv

Skapa sedan en .env fil i programmets rotkatalog. Ange miljövariabelvärdena med värden som hämtats från appregistreringsprocessen enligt följande:

  • AZURE_CLIENT_ID → App-ID-värdet.
  • AZURE_TENANT_ID → Hyresgäst-ID-värdet.
  • AZURE_CLIENT_SECRET → Lösenordet/autentiseringsuppgifterna som genereras för appen.
AZURE_CLIENT_ID=00001111-aaaa-2222-bbbb-3333cccc4444
AZURE_TENANT_ID=aaaabbbb-0000-cccc-1111-dddd2222eeee
AZURE_CLIENT_SECRET=Ee5Ff~6Gg7.-Hh8Ii9Jj0Kk1Ll2Mm3_Nn4Oo5Pp6

Slutligen, använd python-dotenv-biblioteket för att läsa miljövariablerna från .env-filen i startkoden för ditt program.

from dotenv import load_dotenv

if ( os.environ['ENVIRONMENT'] == 'development'):
    print("Loading environment variables from .env file")
    load_dotenv(".env")

Implementera DefaultAzureCredential i ditt program

Om du vill autentisera DefaultAzureCredential Azure SDK-klientobjekt till Azure bör ditt program använda klassen från azure.identity paketet. I det här scenariot DefaultAzureCredential identifierar miljövariablerna AZURE_CLIENT_ID, AZURE_TENANT_IDoch AZURE_CLIENT_SECRET anges och läser dessa variabler för att hämta programtjänstens huvudnamnsinformation för att ansluta till Azure med.

Börja med att lägga till paketet azure.identity i ditt program.

pip install azure-identity

För alla Python-kod som skapar ett Azure SDK-klientobjekt i din app:

  1. DefaultAzureCredential Importera klassen från modulenazure.identity.
  2. Skapa ett DefaultAzureCredential objekt.
  3. Skicka objektet DefaultAzureCredential till Azure SDK-klientobjektkonstruktorn.

Ett exempel på detta visas i följande kodsegment.

from azure.identity import DefaultAzureCredential
from azure.storage.blob import BlobServiceClient

# Acquire a credential object
token_credential = DefaultAzureCredential()

blob_service_client = BlobServiceClient(
        account_url="https://<my_account_name>.blob.core.windows.net",
        credential=token_credential)