Uwierzytelnianie aplikacji języka Python w usługach platformy Azure podczas programowania lokalnego przy użyciu jednostek usługi

Podczas tworzenia aplikacji w chmurze deweloperzy muszą debugować i testować aplikacje na lokalnej stacji roboczej. Gdy aplikacja jest uruchamiana na stacji roboczej dewelopera podczas programowania lokalnego, nadal musi uwierzytelniać się w dowolnych usługach platformy Azure używanych przez aplikację. W tym artykule opisano sposób konfigurowania dedykowanych obiektów jednostki usługi aplikacji, które mają być używane podczas programowania lokalnego.

Diagram przedstawiający sposób, w jaki aplikacja uruchomiona w lokalnym deweloperze uzyskuje jednostkę usługi aplikacji z pliku env, a następnie używa tej tożsamości do łączenia się z zasobami platformy Azure.

Dedykowane jednostki usługi aplikacji na potrzeby tworzenia aplikacji lokalnych umożliwiają przestrzeganie zasady najniższych uprawnień podczas tworzenia aplikacji. Ponieważ uprawnienia są ograniczone do dokładnie tego, co jest potrzebne dla aplikacji podczas programowania, kod aplikacji nie może przypadkowo uzyskać dostępu do zasobu platformy Azure przeznaczonego do użytku przez inną aplikację. Zapobiega to również występowaniu usterek podczas przenoszenia aplikacji do środowiska produkcyjnego, ponieważ aplikacja została nadmiernie uprzywilejowana w środowisku deweloperskim.

Jednostka usługi aplikacji jest skonfigurowana dla aplikacji, gdy aplikacja jest zarejestrowana na platformie Azure. Podczas rejestrowania aplikacji na potrzeby programowania lokalnego zaleca się:

  • Utwórz oddzielne rejestracje aplikacji dla każdego dewelopera pracującego nad aplikacją. Spowoduje to utworzenie oddzielnych jednostek usługi aplikacji dla każdego dewelopera do użycia podczas programowania lokalnego i uniknięcie konieczności przez deweloperów udostępniania poświadczeń dla pojedynczej jednostki usługi aplikacji.
  • Utwórz oddzielne rejestracje aplikacji na aplikację. Obejmuje to uprawnienia aplikacji tylko do tego, co jest potrzebne przez aplikację.

Podczas programowania lokalnego zmienne środowiskowe są ustawiane przy użyciu tożsamości jednostki usługi aplikacji. Zestaw Azure SDK dla języka Python odczytuje te zmienne środowiskowe i używa tych informacji do uwierzytelniania aplikacji w potrzebnych zasobach platformy Azure.

1 — Rejestrowanie aplikacji na platformie Azure

Obiekty jednostki usługi aplikacji są tworzone przy użyciu rejestracji aplikacji na platformie Azure. Można to zrobić przy użyciu witryny Azure Portal lub interfejsu wiersza polecenia platformy Azure.

Polecenia interfejsu wiersza polecenia platformy Azure można uruchamiać w usłudze Azure Cloud Shell lub na stacji roboczej z zainstalowanym interfejsem wiersza polecenia platformy Azure.

Najpierw użyj polecenia az ad sp create-for-rbac , aby utworzyć nową jednostkę usługi dla aplikacji. Polecenie tworzy również rejestrację aplikacji dla aplikacji w tym samym czasie.

az ad sp create-for-rbac --name {service-principal-name}

Dane wyjściowe tego polecenia będą wyglądać następująco. Zanotuj te wartości lub pozostaw to okno otwarte, ponieważ te wartości będą potrzebne w następnych krokach i nie będą mogły ponownie wyświetlić wartości hasła (klucza tajnego klienta). Możesz jednak dodać nowe hasło później bez unieważnienia jednostki usługi lub istniejących haseł w razie potrzeby.

{
  "appId": "00000000-0000-0000-0000-000000000000",
  "displayName": "{service-principal-name}",
  "password": "abcdefghijklmnopqrstuvwxyz",
  "tenant": "33333333-3333-3333-3333-333333333333"
}

2 — Tworzenie grupy zabezpieczeń entra firmy Microsoft na potrzeby programowania lokalnego

Ponieważ zazwyczaj istnieje wielu deweloperów, którzy pracują nad aplikacją, zaleca się utworzenie grupy zabezpieczeń firmy Microsoft Entra w celu hermetyzacji ról (uprawnień) wymaganych przez aplikację w środowisku lokalnym, zamiast przypisywania ról do poszczególnych obiektów jednostki usługi. Zapewnia to następujące korzyści:

  • Każdy deweloper ma przypisane te same role, ponieważ role są przypisywane na poziomie grupy.
  • Jeśli dla aplikacji jest potrzebna nowa rola, należy ją dodać tylko do grupy Microsoft Entra dla aplikacji.
  • Jeśli nowy deweloper dołączy do zespołu, zostanie utworzona nowa jednostka usługi aplikacji dla dewelopera i dodana do grupy, zapewniając deweloperowi odpowiednie uprawnienia do pracy nad aplikacją.

Polecenie az ad group create służy do tworzenia grup zabezpieczeń w identyfikatorze Entra firmy Microsoft. Parametry --display-name i --main-nickname są wymagane. Nazwa nadana grupie powinna być oparta na nazwie aplikacji. Warto również uwzględnić frazę taką jak "local-dev" w nazwie grupy, aby wskazać cel grupy.

az ad group create \
    --display-name MyDisplay \
    --mail-nickname MyDisplay  \
    --description "<group-description>"

Skopiuj wartość id właściwości w danych wyjściowych polecenia . Jest to identyfikator obiektu dla grupy. Będzie ona potrzebna w kolejnych krokach. Możesz również użyć polecenia az ad group show , aby pobrać tę właściwość.

Aby dodać członków do grupy, potrzebny jest identyfikator obiektu jednostki usługi aplikacji, który różni się od identyfikatora aplikacji. Użyj listy az ad sp, aby wyświetlić listę dostępnych jednostek usługi. Polecenie --filter parametru akceptuje filtry stylu OData i może służyć do filtrowania listy, jak pokazano. Parametr --query ogranicza kolumny tylko do tych, które cię interesują.

az ad sp list \
    --filter "startswith(displayName, 'msdocs')" \
    --query "[].{objectId:id, displayName:displayName}" \
    --output table

Polecenie az ad group member add można następnie użyć do dodawania członków do grup.

az ad group member add \
    --group <group-name> \
    --member-id <object-id>

Uwaga

Domyślnie tworzenie grup zabezpieczeń firmy Microsoft Entra jest ograniczone do niektórych ról uprzywilejowanych w katalogu. Jeśli nie możesz utworzyć grupy, skontaktuj się z administratorem katalogu. Jeśli nie możesz dodać członków do istniejącej grupy, skontaktuj się z właścicielem grupy lub administratorem katalogu. Aby dowiedzieć się więcej, zobacz Zarządzanie grupami i członkostwem w grupach firmy Microsoft.

3 — Przypisywanie ról do aplikacji

Następnie należy określić, jakich ról (uprawnień) potrzebuje twoja aplikacja na temat zasobów i przypisać te role do aplikacji. W tym przykładzie role są przypisywane do grupy Microsoft Entra utworzonej w kroku 2. Role można przypisywać w zakresie zasobu, grupy zasobów lub subskrypcji. W tym przykładzie pokazano, jak przypisywać role w zakresie grupy zasobów, ponieważ większość aplikacji grupuje wszystkie zasoby platformy Azure w jedną grupę zasobów.

Jednostka usługi użytkownika, grupy lub aplikacji ma przypisaną rolę na platformie Azure przy użyciu polecenia az role assignment create . Możesz określić grupę z jej identyfikatorem obiektu. Jednostkę usługi aplikacji można określić przy użyciu jej identyfikatora appId.

az role assignment create --assignee {appId or objectId} \
    --scope /subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName} \
    --role "{roleName}" 

Aby uzyskać nazwy ról, które można przypisać, użyj polecenia az role definition list .

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

Aby na przykład zezwolić jednostce usługi aplikacji z identyfikatorem appId 00000000-0000-0000-0000-000000000000 odczytu, zapisu i usuwania do kontenerów obiektów blob usługi Azure Storage i danych we wszystkich kontach magazynu w grupie zasobów msdocs-python-sdk-auth-example w subskrypcji o identyfikatorze 11111111-1111-1111-1111-111111111111, należy przypisać jednostkę usługi aplikacji do roli Współautor danych obiektu blob usługi Storage przy użyciu następującego polecenia.

az role assignment create --assignee 00000000-0000-0000-0000-000000000000 \
    --scope /subscriptions/11111111-1111-1111-1111-111111111111/resourceGroups/msdocs-python-sdk-auth-example \
    --role "Storage Blob Data Contributor"

Aby uzyskać informacje na temat przypisywania uprawnień na poziomie zasobu lub subskrypcji przy użyciu interfejsu wiersza polecenia platformy Azure, zobacz artykuł Przypisywanie ról platformy Azure przy użyciu interfejsu wiersza polecenia platformy Azure.

4 — Ustawianie lokalnych zmiennych środowiskowych programowania

Obiekt DefaultAzureCredential będzie szukać informacji o jednostce usługi w zestawie zmiennych środowiskowych w czasie wykonywania. Ponieważ większość deweloperów pracuje nad wieloma aplikacjami, zaleca się użycie pakietu takiego jak python-dotenv w celu uzyskania dostępu do środowiska z pliku przechowywanego .env w katalogu aplikacji podczas programowania. Obejmuje to zmienne środowiskowe używane do uwierzytelniania aplikacji na platformie Azure, tak aby mogły być używane tylko przez tę aplikację.

Plik .env nigdy nie jest ewidencjony w kontroli źródła, ponieważ zawiera klucz tajny aplikacji dla platformy Azure. Standardowy plik .gitignore dla języka Python automatycznie wyklucza .env plik z ewidencjonowania.

Aby użyć pakietu python-dotenv, najpierw zainstaluj pakiet w aplikacji.

pip install python-dotenv

Następnie utwórz .env plik w katalogu głównym aplikacji. Ustaw wartości zmiennych środowiskowych z wartościami uzyskanymi z procesu rejestracji aplikacji w następujący sposób:

  • AZURE_CLIENT_ID → wartość identyfikatora aplikacji.
  • AZURE_TENANT_ID → wartość identyfikatora dzierżawy.
  • AZURE_CLIENT_SECRET → hasło/poświadczenia wygenerowane dla aplikacji.
AZURE_CLIENT_ID=00000000-0000-0000-0000-000000000000
AZURE_TENANT_ID=11111111-1111-1111-1111-111111111111
AZURE_CLIENT_SECRET=abcdefghijklmnopqrstuvwxyz

Na koniec w kodzie uruchamiania aplikacji użyj python-dotenv biblioteki, aby odczytać zmienne środowiskowe z pliku podczas uruchamiania .env .

from dotenv import load_dotenv

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

5 — Implementowanie wartości domyślnejAzureCredential w aplikacji

Aby uwierzytelnić obiekty klienta zestawu Azure SDK na platformie Azure, aplikacja powinna używać DefaultAzureCredential klasy z azure.identity pakietu. W tym scenariuszu DefaultAzureCredential program wykryje zmienne środowiskowe AZURE_CLIENT_ID, AZURE_TENANT_IDi AZURE_CLIENT_SECRET zostanie ustawiony i odczytuje te zmienne, aby uzyskać informacje o jednostce usługi aplikacji w celu nawiązania połączenia z platformą Azure za pomocą polecenia .

Zacznij od dodania pakietu azure.identity do aplikacji.

pip install azure-identity

Następnie w przypadku dowolnego kodu w języku Python, który tworzy obiekt klienta zestawu Azure SDK w aplikacji, należy wykonać następujące czynności:

  1. Zaimportuj klasę DefaultAzureCredential z modułu azure.identity .
  2. Utwórz DefaultAzureCredential obiekt.
  3. Przekaż obiekt do konstruktora DefaultAzureCredential obiektu klienta zestawu Azure SDK.

Przykład jest pokazany w następującym segmencie kodu.

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)