Dela via


Autentisera Go-applikationer mot Azure-tjänster under lokal utveckling med hjälp av tjänstehuvudnamn

När du skapar molnprogram måste utvecklare felsöka och testa program på sin lokala arbetsstation. När ett program körs på en utvecklares arbetsstation under den lokala utvecklingen måste det fortfarande autentiseras mot alla Azure-tjänster som används av appen. Den här artikeln beskriver hur du konfigurerar dedikerade programtjänstobjekt som ska användas 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.

Med dedikerade tjänsthuvudnycklar för applikationer för lokal utveckling kan du följa principen om minst privilegier under applikationsutveckling. Eftersom behörigheter är begränsade till exakt vad som behövs för appen under utvecklingen förhindras appkod från att oavsiktligt komma åt en Azure-resurs som är avsedd att användas av en annan app. Detta förhindrar också att buggar inträffar när appen flyttas till produktion eftersom appen överprivilegierades i utvecklingsmiljön.

Ett huvudnamn för programtjänsten konfigureras för appen när appen är registrerad i Azure. När du registrerar appar för lokal utveckling rekommenderar vi att du:

  • Skapa separata appregistreringar för varje utvecklare som arbetar med appen. Detta skapar separata huvudnamn för programtjänsten som varje utvecklare kan använda under lokal utveckling och undviker behovet av att utvecklare delar autentiseringsuppgifter för ett enda huvudnamn för programtjänsten.
  • Skapa separata appregistreringar per app. Detta begränsar appens behörigheter till enbart det som behövs av appen.

Under lokal utveckling anges miljövariabler med programtjänstens huvudnamns identitet. Azure SDK för Go läser dessa miljövariabler och använder den här informationen för att autentisera appen till de Azure-resurser den behöver.

1 – Registrera programmet i Azure

Huvudobjekt för programtjänsten skapas med en appregistrering i Azure. Detta kan göras med antingen Azure-portalen eller Azure CLI.

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

Börja med att använda kommandot az ad sp create-for-rbac för att skapa ett nytt tjänstehuvud för applikationen. Kommandot skapar även appregistreringen för appen samtidigt.

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

Utdata från det här kommandot ser ut så här. 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"
}

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

Eftersom det vanligtvis finns flera utvecklare som arbetar med ett program rekommenderar vi att du skapar en Microsoft Entra-säkerhetsgrupp för att kapsla in de roller (behörigheter) som appen behöver i lokal utveckling, i stället för att tilldela rollerna till enskilda objekt för tjänstens huvudnamn. Detta 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.

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

Kopiera värdet för egenskapen id i kommandots utdata. Det här är objekt-ID:t för gruppen. Du behöver det i senare steg. Du kan också använda kommandot az ad group show för att hämta den här egenskapen.

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 listan az ad sp för att visa en lista över tillgängliga tjänsthuvudnamn. Parameterkommandot --filter accepterar OData-formatfilter och kan användas för att filtrera listan som visas. Parametern --query begränsar till kolumner till endast de som är intressanta.

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

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-name> \
    --member-id <object-id>

Not

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.

3 – 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.

En användare, grupp eller tjänstens huvudprincip tilldelas en roll i Azure med hjälp av kommandot az role assignment create. Du kan ange en grupp med dess objekt-ID. Du kan ange ett huvudnamn för programtjänsten med dess appId.

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

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 principal med appId för 00001111-aaaa-2222-bbbb-3333cccc4444 att läsa, skriva och ta bort åtkomst till Azure Storage-blobcontainrar och data i alla lagringskonton i resursgruppen msdocs-go-sdk-auth-example i prenumerationen med ID aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e, tilldelar du programtjänstens principal 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-go-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-.

4 – Ange miljövariabler för lokal utveckling

Objektet DefaultAzureCredential kommer att söka efter informationen om tjänsteprincipal i en uppsättning miljövariabler vid körningstid. Eftersom de flesta utvecklare arbetar med flera program rekommenderar vi att du använder ett paket som godotenv för att komma åt miljön från en .env fil som lagras i programmets katalog under utvecklingen. Detta omfattar de miljövariabler som används för att autentisera programmet till Azure så att de bara kan användas av det här programmet.

Den .env filen checkas aldrig in i källkontrollen eftersom den innehåller programhemlighetsnyckeln för Azure. Standardfilen .gitignore för Go utesluter automatiskt .env-filen från incheckningen.

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

go get github.com/joho/godotenv

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 → Klientorganisations-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

I startkoden för ditt program använder du slutligen godotenv-biblioteket för att läsa miljövariablerna från .env-filen vid start.

// Imports of fmt, log, and os omitted for brevity 
import "github.com/joho/godotenv"

environment := os.Getenv("ENVIRONMENT")

if environment == "development" {
    fmt.Println("Loading environment variables from .env file")
    
    // Load the .env file
    err := godotenv.Load(".env")
    if err != nil {
        log.Fatalf("Error loading .env file: %v", err)
    }
}

5 – Implementera DefaultAzureCredential i ditt program

För att autentisera Azure SDK-klientobjekt till Azure bör ditt program använda klassen DefaultAzureCredential från azidentity-paketet. I det här scenariot identifierar DefaultAzureCredential miljövariablerna AZURE_CLIENT_ID, AZURE_TENANT_IDoch AZURE_CLIENT_SECRET anges och läser dessa variabler för att få information om programtjänstens huvudnamn att ansluta till Azure med.

Lägg först till azidentity-paketet i ditt program.

go get github.com/Azure/azure-sdk-for-go/sdk/azidentity

För alla Go-kod som skapar ett Azure SDK-klientobjekt i din app vill du sedan:

  1. Importera azidentity-paketet.
  2. Skapa en instans av typ DefaultAzureCredential.
  3. Skicka instansen av DefaultAzureCredential typ till Azure SDK-klientkonstruktorn.

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

import (
	"context"

	"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
	"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
)

const (
	account       = "https://<replace_with_your_storage_account_name>.blob.core.windows.net/"
	containerName = "sample-container"
	blobName      = "sample-blob"
	sampleFile    = "path/to/sample/file"
)

func main() {
    // create a credential
    cred, err := azidentity.NewDefaultAzureCredential(nil)
    if err != nil {
      // TODO: handle error
    }
    
    // create a client for the specified storage account
    client, err := azblob.NewClient(account, cred, nil)
    if err != nil {
      // TODO: handle error
    }
    
    // TODO: perform some action with the azblob Client
    // _, err = client.DownloadFile(context.TODO(), <containerName>, <blobName>, <target_file>, <DownloadFileOptions>)
}