Använda systemtilldelade hanterade identiteter för att komma åt Azure Cosmos DB-data

GÄLLER FÖR: NoSQL

I den här artikeln konfigurerar du en robust, nyckelrotationsagnostisk lösning för åtkomst till Azure Cosmos DB-nycklar med hjälp av hanterade identiteter och rollbaserad åtkomstkontroll för dataplanet. Exemplet i den här artikeln använder Azure Functions, men du kan använda alla tjänster som stöder hanterade identiteter.

Du får lära dig hur du skapar en funktionsapp som kan komma åt Azure Cosmos DB-data utan att behöva kopiera några Azure Cosmos DB-nycklar. Funktionsappen utlöses när en HTTP-begäran görs och listar sedan alla befintliga databaser.

Förutsättningar

  • Ett Azure-konto med en aktiv prenumeration. Skapa ett konto utan kostnad.

  • Ett befintligt Azure Cosmos DB-API för NoSQL-konto. Skapa ett Azure Cosmos DB-API för NoSQL-konto

  • En befintlig Azure Functions-funktionsapp. Skapa din första funktion i Azure-portalen

  • Azure Functions Core Tools

  • Om du vill utföra stegen i den här artikeln installerar du Azure CLI och loggar in på Azure.

    Kravkontroll

    1. I ett terminal- eller kommandofönster lagrar du namnen på din Azure Functions-funktionsapp, Azure Cosmos DB-konto och resursgrupp som gränssnittsvariabler med namnet functionName, cosmosNameoch 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"
      

      Kommentar

      Dessa variabler kommer att återanvändas i senare steg. Det här exemplet förutsätter att ditt Azure Cosmos DB-kontonamn är msdocs-cosmos-app, funktionsappens namn är msdocs-function-app och resursgruppens namn är msdocs-cosmos-functions-dotnet-identity.

    2. Visa funktionsappens egenskaper med kommandot az functionapp show .

      az functionapp show \
          --resource-group $resourceGroupName \
          --name $functionName
      
    3. Visa egenskaperna för den systemtilldelade hanterade identiteten för funktionsappen med hjälp av az webapp identity show.

      az webapp identity show \
          --resource-group $resourceGroupName \
          --name $functionName
      
    4. Visa Azure Cosmos DB-kontots egenskaper med hjälp av az cosmosdb show.

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

Skapa Azure Cosmos DB API för NoSQL-databaser

I det här steget skapar du två databaser.

  1. I ett terminal- eller kommandofönster skapar du en ny products databas med hjälp av az cosmosdb sql database create.

    az cosmosdb sql database create \
        --resource-group $resourceGroupName \
        --name products \
        --account-name $cosmosName
    
  2. Skapa en ny customers databas.

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

Hämta Azure Cosmos DB API för NoSQL-slutpunkt

I det här steget frågar du dokumentslutpunkten för API:et för NoSQL-kontot.

  1. Använd az cosmosdb show med frågeparametern inställd på documentEndpoint. Registrera resultatet. Du använder det här värdet i ett senare steg.

    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
    

    Kommentar

    Den här variabeln kommer att återanvändas i ett senare steg.

Bevilja åtkomst till ditt Azure Cosmos DB-konto

I det här steget tilldelar du en roll till funktionsappens systemtilldelade hanterade identitet. Azure Cosmos DB har flera inbyggda roller som du kan tilldela till den hanterade identiteten för åtkomst till kontrollplan. För dataplansåtkomst skapar du en ny anpassad roll med åtkomst till läsmetadata.

Dricks

Mer information om vikten av åtkomst med lägsta behörighet finns i artikeln Lägre exponering av privilegierade konton .

  1. Använd az cosmosdb show med frågeparametern inställd på id. Lagra resultatet i en gränssnittsvariabel med namnet scope.

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

    Kommentar

    Den här variabeln kommer att återanvändas i ett senare steg.

  2. Använd az webapp identity show med frågeparametern inställd på principalId. Lagra resultatet i en gränssnittsvariabel med namnet principal.

    principal=$(
        az webapp identity show \
            --resource-group $resourceGroupName \
            --name $functionName \
            --query principalId \
            --output tsv
    )
    
    echo $principal
    
  3. Skapa en ny JSON-fil med konfigurationen av den nya anpassade rollen.

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

    Dricks

    Du kan skapa en fil i Azure Cloud Shell med hjälp av antingen touch <filename> eller den inbyggda redigeraren (code .). Mer information finns i Azure Cloud Shell-redigeraren

  4. Använd az cosmosdb sql role definition create för att skapa en ny rolldefinition med namnet Read Azure Cosmos DB Metadata med det anpassade JSON-objektet.

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

    Kommentar

    I det här exemplet definieras rolldefinitionen i en fil med namnet definition.json.

  5. Använd az role assignment create för att tilldela Read Azure Cosmos DB Metadata rollen till den systemtilldelade hanterade identiteten.

    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
    

Programmatiskt åtkomst till Azure Cosmos DB-nycklar

Nu har vi en funktionsapp som har en systemtilldelad hanterad identitet med den anpassade rollen. Följande funktionsapp frågar Azure Cosmos DB-kontot om en lista över databaser.

  1. Skapa ett lokalt funktionsprojekt med parametern --dotnet i en mapp med namnet csmsfunc. Ändra gränssnittets katalog

    func init csmsfunc --dotnet
    
    cd csmsfunc
    
  2. Skapa en ny funktion med mallparametern inställd på httptrigger och namnet inställt på readdatabases.

    func new --template httptrigger --name readdatabases
    
  3. Azure.Identity Lägg till NuGet-paketet och Microsoft.Azure.Cosmos i .NET-projektet. Skapa projektet med hjälp av dotnet build.

    dotnet add package Azure.Identity
    
    dotnet add package Microsoft.Azure.Cosmos
    
    dotnet build
    
  4. Öppna funktionskoden i en integrerad utvecklarmiljö (IDE).

    Dricks

    Om du använder Azure CLI lokalt eller i Azure Cloud Shell kan du öppna Visual Studio Code.

    code .
    
  5. Ersätt koden i filen readdatabases.cs med den här exempelfunktionens implementering. Spara den uppdaterade filen.

    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);
            }
        }
    }
    

(Valfritt) Kör funktionen lokalt

I en lokal miljö DefaultAzureCredential använder klassen olika lokala autentiseringsuppgifter för att fastställa den aktuella identiteten. Även om det inte krävs att köra lokalt för instruktionen kan du utveckla lokalt med hjälp av din egen identitet eller ett huvudnamn för tjänsten.

  1. I filen local.settings.json lägger du till en ny inställning med namnet COSMOS_ENDPOINT i objektet Värden . Värdet för inställningen ska vara den dokumentslutpunkt som du registrerade tidigare i den här guiden.

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

    Kommentar

    Det här JSON-objektet har förkortats för korthet. Det här JSON-objektet innehåller också ett exempelvärde som förutsätter att ditt kontonamn är msdocs-cosmos-app.

  2. Kör funktionsappen

    func start
    

Distribuera till Azure

När den har publicerats DefaultAzureCredential använder klassen autentiseringsuppgifter från miljön eller en hanterad identitet. För den här guiden används den systemtilldelade hanterade identiteten CosmosClient som en autentiseringsuppgift för konstruktorn.

  1. Ange inställningen för COSMOS_ENDPOINT funktionsappen som redan har distribuerats i Azure.

    az functionapp config appsettings set \
        --resource-group $resourceGroupName \
        --name $functionName \
        --settings "COSMOS_ENDPOINT=$cosmosEndpoint"
    
  2. Distribuera funktionsappen till Azure genom att återanvända gränssnittsvariabeln functionName :

    func azure functionapp publish $functionName
    
  3. Testa din funktion i Azure-portalen.