Bearbeiten

Verwenden von systemseitig zugewiesenen verwalteten Identitäten für den Zugriff auf Azure Cosmos DB-Daten

GILT FÜR: NoSQL

In diesem Artikel richten Sie eine stabile, schlüsselrotationsunabhängige Lösung für den Zugriff auf Azure Cosmos DB-Schlüssel durch Verwendung verwalteter Identitäten und rollenbasierte Zugriffssteuerung auf der Datenebene ein. Im Beispiel in diesem Artikel wird Azure Functions verwendet, aber Sie können jeden beliebigen Dienst verwenden, der verwaltete Identitäten unterstützt.

Sie erfahren, wie Sie eine Funktions-App erstellen, die auf Azure Cosmos DB-Daten zugreifen kann, ohne Azure Cosmos DB-Schlüssel kopieren zu müssen. Die Funktions-App löst aus, wenn eine HTTP-Anforderung vorgenommen wird und dann werden alle vorhandenen Datenbanken aufgelistet.

Voraussetzungen

  • Ein Azure-Konto mit einem aktiven Abonnement. Sie können kostenlos ein Konto erstellen.

  • Ein vorhandenes Azure Cosmos DB API for NoSQL-Konto. Erstellen eines Azure Cosmos DB-API für NoSQL-Kontos

  • Eine vorhandene Azure Functions Funktions-App. Erstellen Ihrer ersten Funktion im Azure-Portal

  • Azure Functions Core Tools

  • Um die Schritte in diesem Artikel ausführen zu können, installieren Sie die Azure CLI, und melden Sie sich bei Azure an.

    Prüfen der Voraussetzungen

    1. Speichern Sie in einem Terminal- oder Befehlsfenster die Namen Ihrer Azure Functions Funktions-App, das Azure Cosmos DB-Konto und die Ressourcengruppe als Shellvariablen namens functionName, cosmosName und resourceGroupName.

      # Variable for function app name
      functionName="msdocs-function-app"
      
      # Variable for Azure Cosmos DB account name
      cosmosName="msdocs-cosmos-app"
      
      # Variable for resource group name
      resourceGroupName="msdocs-cosmos-functions-dotnet-identity"
      

      Hinweis

      Diese Variablen werden in späteren Schritten erneut verwendet. In diesem Beispiel wird davon ausgegangen, dass Ihr Azure Cosmos DB-Kontoname msdocs-cosmos-app ist, ihr Funktions-App-Name msdocs-function-app ist und Ihr Ressourcengruppenname msdocs-cosmos-functions-dotnet-identity lautet.

    2. Zeigen Sie die Eigenschaften der Funktions-App mit dem Befehl az functionapp show an.

      az functionapp show \
          --resource-group $resourceGroupName \
          --name $functionName
      
    3. Zeigen Sie die Eigenschaften der vom System zugewiesenen verwalteten Identität für Ihre Funktions-App mithilfe von az webapp identity show an.

      az webapp identity show \
          --resource-group $resourceGroupName \
          --name $functionName
      
    4. Zeigen Sie die Eigenschaften des Azure Cosmos DB-Kontos mithilfe von az cosmosdb show an.

      az cosmosdb show \
          --resource-group $resourceGroupName \
          --name $cosmosName
      

Erstellen der Azure Cosmos DB-API für NoSQL-Datenbanken

In diesem Schritt erstellen Sie zwei Datenbanken.

  1. Erstellen Sie mithilfe von az cosmosdb sql database create in einem Terminal- oder Befehlsfenster eine neue products-Datenbank.

    az cosmosdb sql database create \
        --resource-group $resourceGroupName \
        --name products \
        --account-name $cosmosName
    
  2. Erstellen Sie eine neue customers-Datenbank.

    az cosmosdb sql database create \
        --resource-group $resourceGroupName \
        --name customers \
        --account-name $cosmosName
    

Abrufen des Azure Cosmos DB-API für NoSQL-Endpunkts

In diesem Schritt werden Sie den Dokumentendpunkt für das „API für NoSQL“-Konto abfragen.

  1. Verwenden Sie az cosmosdb show, wobei der Abfrage-Parameter auf documentEndpoint gesetzt ist. Zeichnen Sie die Ergebnisse auf. Sie verwenden diesen Wert in einem späteren Schritt.

    az cosmosdb show \
        --resource-group $resourceGroupName \
        --name $cosmosName \
        --query documentEndpoint
    
    cosmosEndpoint=$(
        az cosmosdb show \
            --resource-group $resourceGroupName \
            --name $cosmosName \
            --query documentEndpoint \
            --output tsv
    )
    
    echo $cosmosEndpoint
    

    Hinweis

    Diese Variable wird in einem späteren Schritt erneut verwendet.

Gewähren des Zugriffs auf Ihr Azure Cosmos DB-Konto

In diesem Schritt weisen Sie der vom System zugewiesenen verwalteten Identität der Funktions-App eine Rolle zu. Azure Cosmos DB umfasst mehrere integrierte Rollen, die Sie der verwalteten Identität für den Zugriff auf der Steuerungsebene zuweisen können. Für den Zugriff auf der Datenebene erstellen Sie eine neue benutzerdefinierte Rolle mit Lesezugriff auf die Metadaten.

Tipp

Weitere Informationen zur Bedeutung des Zugriffs mit geringsten Rechten finden Sie im Artikel Senken der Gefährdung privilegierter Konten.

  1. Verwenden Sie az cosmosdb show, wobei der Abfrage-Parameter auf id gesetzt ist. Speichern Sie das Ergebnis in einer Shellvariable namens scope.

    scope=$(
        az cosmosdb show \
            --resource-group $resourceGroupName \
            --name $cosmosName \
            --query id \
            --output tsv
    )
    
    echo $scope
    

    Hinweis

    Diese Variable wird in einem späteren Schritt erneut verwendet.

  2. Verwenden Sie az webapp identity show, wobei der Abfrage-Parameter auf principalId gesetzt ist. Speichern Sie das Ergebnis in einer Shellvariable namens principal.

    principal=$(
        az webapp identity show \
            --resource-group $resourceGroupName \
            --name $functionName \
            --query principalId \
            --output tsv
    )
    
    echo $principal
    
  3. Erstellen Sie eine neue JSON-Datei mit der Konfiguration der neuen benutzerdefinierten Rolle.

    {
        "RoleName": "Read Azure Cosmos DB Metadata",
        "Type": "CustomRole",
        "AssignableScopes": ["/"],
        "Permissions": [{
            "DataActions": [
                "Microsoft.DocumentDB/databaseAccounts/readMetadata"
            ]
        }]
    }
    

    Tipp

    Sie können eine Datei in Azure Cloud Shell erstellen, indem Sie entweder touch <filename> oder den integrierten Editor (code .) verwenden. Weitere Informationen finden Sie unter Azure Cloud Shell-Editor.

  4. Verwenden Sie az cosmosdb sql role definition create zum Erstellen einer neuen Rollendefinition namens Read Azure Cosmos DB Metadata mit dem benutzerdefinierten JSON-Objekt.

    az cosmosdb sql role definition create \
        --resource-group $resourceGroupName \
        --account-name $cosmosName \
        --body @definition.json
    

    Hinweis

    In diesem Beispiel wird die Rollendefinition in einer Datei namens definition.json definiert.

  5. Verwenden Sie az role assignment create zum Zuweisen der Rolle Read Azure Cosmos DB Metadata zur vom System zugewiesenen verwalteten Identität.

    az cosmosdb sql role assignment create \
        --resource-group $resourceGroupName \
        --account-name $cosmosName \
        --role-definition-name "Read Azure Cosmos DB Metadata" \
        --principal-id $principal \
        --scope $scope
    

Programmgesteuerter Zugriff auf die Azure Cosmos DB-Schlüssel

Sie verfügen jetzt über eine Funktions-App mit einer systemseitig zugewiesenen verwalteten Identität und der benutzerdefinierten Rolle. Die folgende Funktions-App wird das Azure Cosmos DB-Konto für eine Liste von Datenbanken abfragen.

  1. Erstellen Sie in einem Ordner namens csmsfunc ein lokales Funktionsprojekt mit dem Parameter --dotnet. Ändern des Verzeichnisses ihrer Shell

    func init csmsfunc --dotnet
    
    cd csmsfunc
    
  2. Erstellen Sie eine neue Funktion, bei der der Vorlage-Parameter auf httptrigger und der Name auf readdatabases gesetzt ist.

    func new --template httptrigger --name readdatabases
    
  3. Fügen Sie die NuGet-Pakete Azure.Identity und Microsoft.Azure.Cosmos dem .NET-Projekt hinzu. Erstellen Sie das Projekt mithilfe von dotnet build.

    dotnet add package Azure.Identity
    
    dotnet add package Microsoft.Azure.Cosmos
    
    dotnet build
    
  4. Öffnen Sie den Funktionscode in einer integrierten Entwicklerumgebung (IDE).

    Tipp

    Wenn Sie die Azure CLI lokal oder in der Azure Cloud Shell verwenden, können Sie Visual Studio Code öffnen.

    code .
    
  5. Ersetzen Sie den Code in der Datei readdatabases.cs durch diese beispielhafte Funktionsimplementierung. Speichern Sie die aktualisierte Datei.

    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    using Azure.Identity;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Azure.Cosmos;
    using Microsoft.Azure.WebJobs;
    using Microsoft.Azure.WebJobs.Extensions.Http;
    using Microsoft.AspNetCore.Http;
    using Microsoft.Extensions.Logging;
    
    namespace csmsfunc
    {
        public static class readdatabases
        {
            [FunctionName("readdatabases")]
            public static async Task<IActionResult> Run(
                [HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequest req,
                ILogger log)
            {
                log.LogTrace("Start function");
    
                CosmosClient client = new CosmosClient(
                    accountEndpoint: Environment.GetEnvironmentVariable("COSMOS_ENDPOINT", EnvironmentVariableTarget.Process),
                    new DefaultAzureCredential()
                );
    
                using FeedIterator<DatabaseProperties> iterator = client.GetDatabaseQueryIterator<DatabaseProperties>();
    
                List<(string name, string uri)> databases = new();
                while(iterator.HasMoreResults)
                {
                    foreach(DatabaseProperties database in await iterator.ReadNextAsync())
                    {
                        log.LogTrace($"[Database Found]\t{database.Id}");
                        databases.Add((database.Id, database.SelfLink));
                    }
                }
    
                return new OkObjectResult(databases);
            }
        }
    }
    

(Optional) Lokale Ausführung der Funktion

In einer lokalen Umgebung verwendet die DefaultAzureCredential-Klasse verschiedene lokale Anmeldeinformationen, um die aktuelle Identität zu bestimmen. Für die Anleitung ist eine lokale Ausführung zwar nicht erforderlich, aber Sie können mit Ihrer eigenen Identität oder einem Dienstprinzipal lokal entwickeln.

  1. Fügen Sie in der Datei local.settings.json im Objekt Werte eine neue Einstellung namens COSMOS_ENDPOINT hinzu. Der Wert der Einstellung sollte der Dokumentendpunkt sein, den Sie zuvor in dieser Schrittanleitung aufgezeichnet haben.

    ...
    "Values": {
        ...
        "COSMOS_ENDPOINT": "https://msdocs-cosmos-app.documents.azure.com:443/",
        ...
    }
    ...
    

    Hinweis

    Dieses JSON-Objekt ist aus Platzgründen gekürzt worden. Dieses JSON-Objekt enthält auch einen Beispielwert, der davon ausgeht, dass Ihr Kontoname msdocs-cosmos-app lautet.

  2. Ausführen der Funktions-App

    func start
    

Bereitstellen in Azure

Nach der Veröffentlichung verwendet die DefaultAzureCredential-Klasse Anmeldeinformationen aus der Umgebung oder einer verwalteten Identität. Für diese Anleitung wird die vom System zugewiesene verwaltete Identität als Anmeldeinformationen für den CosmosClient-Konstruktor verwendet.

  1. Legen Sie die Einstellung COSMOS_ENDPOINT für die Funktions-App fest, die bereits in Azure bereitgestellt wurde.

    az functionapp config appsettings set \
        --resource-group $resourceGroupName \
        --name $functionName \
        --settings "COSMOS_ENDPOINT=$cosmosEndpoint"
    
  2. Stellen Sie Ihre Funktions-App in Azure bereit, indem Sie die Shellvariable functionName erneut verwenden:

    func azure functionapp publish $functionName
    
  3. Testen Ihrer Funktion im Azure-Portal.