Używanie odwołań usługi Key Vault jako ustawień aplikacji w usłudze aplikacja systemu Azure i usłudze Azure Functions

W tym artykule pokazano, jak używać wpisów tajnych z usługi Azure Key Vault jako wartości ustawień aplikacji lub parametry połączenia w aplikacjach usługi App Service lub Azure Functions.

Azure Key Vault to usługa, która zapewnia scentralizowane zarządzanie wpisami tajnymi z pełną kontrolą nad zasadami dostępu i historią inspekcji. Jeśli ustawienie aplikacji lub parametry połączenia jest odwołaniem do magazynu kluczy, kod aplikacji może używać go jak dowolne inne ustawienie aplikacji lub parametry połączenia. Dzięki temu można przechowywać wpisy tajne poza konfiguracją aplikacji. Ustawienia aplikacji są bezpiecznie szyfrowane w spoczynku, ale jeśli potrzebujesz funkcji zarządzania wpisami tajnymi, powinny przejść do magazynu kluczy.

Udzielanie aplikacji dostępu do magazynu kluczy

Aby odczytywać wpisy tajne z magazynu kluczy, musisz mieć utworzony magazyn i udzielić aplikacji uprawnień dostępu do niego.

  1. Utwórz magazyn kluczy, postępując zgodnie z przewodnikiem Szybki start usługi Key Vault.

  2. Utwórz tożsamość zarządzaną dla aplikacji.

    Odwołania do magazynu kluczy domyślnie używają tożsamości przypisanej przez system aplikacji, ale można określić tożsamość przypisaną przez użytkownika.

  3. Autoryzowanie dostępu do odczytu do wpisów tajnych w magazynie kluczy dla utworzonej wcześniej tożsamości zarządzanej. Jak to zrobić, zależy od modelu uprawnień magazynu kluczy:

Uzyskiwanie dostępu do magazynów z ograniczeniami sieci

Jeśli magazyn jest skonfigurowany z ograniczeniami sieci, upewnij się, że aplikacja ma dostęp do sieci. Magazyny nie powinny zależeć od publicznych adresów IP wychodzących aplikacji, ponieważ źródłowy adres IP żądania wpisu tajnego może być inny. Zamiast tego magazyn powinien być skonfigurowany tak, aby akceptował ruch z sieci wirtualnej używanej przez aplikację.

  1. Upewnij się, że aplikacja ma skonfigurowane możliwości sieci wychodzącej zgodnie z opisem w temacie Funkcje sieciowe usługi App Service i opcje sieciowe usługi Azure Functions.

    Aplikacje systemu Linux łączące się z prywatnymi punktami końcowymi muszą być jawnie skonfigurowane do kierowania całego ruchu przez sieć wirtualną. To wymaganie zostanie usunięte w nadchodzącej aktualizacji. Aby skonfigurować to ustawienie, uruchom następujące polecenie:

    az webapp config set --subscription <sub> -g <group-name> -n <app-name> --generic-configurations '{"vnetRouteAllEnabled": true}'
    
  2. Upewnij się, że konfiguracja magazynu zezwala na dostęp do sieci lub podsieci używanej przez aplikację.

Uzyskiwanie dostępu do magazynów przy użyciu tożsamości przypisanej przez użytkownika

Niektóre aplikacje muszą odwoływać się do wpisów tajnych w czasie tworzenia, gdy tożsamość przypisana przez system nie jest jeszcze dostępna. W takich przypadkach można utworzyć tożsamość przypisaną przez użytkownika i uzyskać dostęp do magazynu z wyprzedzeniem.

Po udzieleniu uprawnień do tożsamości przypisanej przez użytkownika wykonaj następujące kroki:

  1. Przypisz tożsamość do aplikacji, jeśli jeszcze tego nie zrobiono.

  2. Skonfiguruj aplikację tak, aby korzystała z tej tożsamości dla operacji referencyjnych magazynu kluczy, ustawiając keyVaultReferenceIdentity właściwość na identyfikator zasobu tożsamości przypisanej przez użytkownika.

    identityResourceId=$(az identity show --resource-group <group-name> --name <identity-name> --query id -o tsv)
    az webapp update --resource-group <group-name> --name <app-name> --set keyVaultReferenceIdentity=${identityResourceId}
    

To ustawienie dotyczy wszystkich odwołań do magazynu kluczy dla aplikacji.

Wymiana

Jeśli wersja wpisu tajnego nie jest określona w odwołaniu, aplikacja używa najnowszej wersji, która istnieje w magazynie kluczy. Gdy nowsze wersje staną się dostępne, na przykład ze zdarzeniem rotacji, aplikacja zostanie automatycznie zaktualizowana i rozpocznie korzystanie z najnowszej wersji w ciągu 24 godzin. Opóźnienie jest spowodowane tym, że usługa App Service buforuje wartości odwołań do magazynu kluczy i pobiera je ponownie co 24 godziny. Każda zmiana konfiguracji w aplikacji powoduje ponowne uruchomienie aplikacji i natychmiastowe ponowne pobranie wszystkich odwołanych wpisów tajnych.

Ustawienia aplikacji źródłowej z magazynu kluczy

Aby użyć odwołania do magazynu kluczy, ustaw odwołanie jako wartość ustawienia. Aplikacja może odwoływać się do wpisu tajnego za pomocą klucza w zwykły sposób. Nie są wymagane żadne zmiany kodu.

Napiwek

Większość ustawień aplikacji korzystających z odwołań magazynu kluczy powinna być oznaczona jako ustawienia miejsca, ponieważ dla każdego środowiska powinny istnieć oddzielne magazyny.

Odwołanie do magazynu kluczy ma postać @Microsoft.KeyVault({referenceString}), gdzie {referenceString} znajduje się w jednym z następujących formatów:

Ciąg odwołania opis
SecretUri=secretUri Identyfikator SecretUri powinien być pełnym identyfikatorem URI płaszczyzny danych wpisu tajnego w magazynie, opcjonalnie zawierającym wersję, np. https://myvault.vault.azure.net/secrets/mysecret/ lub https://myvault.vault.azure.net/secrets/mysecret/ec96f02080254f109c51a1f14cdb1931
VaultName=vaultName; SecretName=secretName; SecretVersion=secretVersion Nazwa magazynu jest wymagana i jest nazwą magazynu. Nazwa_wpisu tajnego jest wymagana i jest nazwą wpisu tajnego. Funkcja SecretVersion jest opcjonalna, ale jeśli istnieje wskazuje wersję wpisu tajnego do użycia.

Na przykład pełne odwołanie będzie wyglądać podobnie do następującego ciągu:

@Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/mysecret/)

Inna możliwość:

@Microsoft.KeyVault(VaultName=myvault;SecretName=mysecret)

Zagadnienia dotyczące instalowania usługi Azure Files

Aplikacje mogą używać WEBSITE_CONTENTAZUREFILECONNECTIONSTRING ustawienia aplikacji do instalowania usługi Azure Files jako systemu plików. To ustawienie ma sprawdzanie poprawności, aby upewnić się, że aplikacja może być poprawnie uruchomiona. Platforma korzysta z udziału zawartości w usłudze Azure Files i zakłada domyślną nazwę, chyba że zostanie określona za pośrednictwem WEBSITE_CONTENTSHARE ustawienia. W przypadku żądań modyfikujących te ustawienia platforma sprawdza, czy ten udział zawartości istnieje, i próbuje go utworzyć, jeśli nie. Jeśli nie może zlokalizować ani utworzyć udziału zawartości, blokuje żądanie.

Jeśli używasz odwołań do magazynu kluczy w tym ustawieniu, sprawdzanie poprawności domyślnie kończy się niepowodzeniem, ponieważ sam wpis tajny nie może zostać rozwiązany podczas przetwarzania żądania przychodzącego. Aby uniknąć tego problemu, możesz pominąć walidację, ustawiając wartość WEBSITE_SKIP_CONTENTSHARE_VALIDATION "1". To ustawienie informuje usługę App Service o pomijaniu wszystkich testów i nie tworzy udziału zawartości. Upewnij się, że został utworzony z wyprzedzeniem.

Uwaga

Jeśli pominiesz walidację i parametry połączenia lub udział zawartości są nieprawidłowe, aplikacja nie będzie mogła uruchomić poprawnie i będzie obsługiwać tylko błędy HTTP 500.

W ramach tworzenia aplikacji próba instalowania udziału zawartości może zakończyć się niepowodzeniem z powodu braku propagacji uprawnień tożsamości zarządzanej lub nie skonfigurowano integracji sieci wirtualnej. Możesz odroczyć konfigurowanie usługi Azure Files do późniejszego użycia w szablonie wdrożenia, aby go uwzględnić. Aby dowiedzieć się więcej, zobacz Wdrażanie usługi Azure Resource Manager. W takim przypadku usługa App Service używa domyślnego systemu plików do momentu skonfigurowania usługi Azure Files, a pliki nie są kopiowane. Przed zainstalowaniem usługi Azure Files nie ma żadnych prób wdrożenia.

Zagadnienia dotyczące instrumentacji Szczegółowe informacje aplikacji

Aplikacje mogą używać APPINSIGHTS_INSTRUMENTATIONKEY ustawień aplikacji lub APPLICATIONINSIGHTS_CONNECTION_STRING do integracji z aplikacją Szczegółowe informacje. Środowiska portalu dla usług App Service i Azure Functions używają również tych ustawień do przedstawiania danych telemetrycznych z zasobu. Jeśli te wartości są przywołyne z usługi Key Vault, te środowiska nie są dostępne i zamiast tego należy pracować bezpośrednio z zasobem Application Szczegółowe informacje, aby wyświetlić dane telemetryczne. Te wartości nie są jednak uznawane za wpisy tajne, więc możesz też rozważyć ich bezpośrednie skonfigurowanie zamiast używania odwołań do magazynu kluczy.

Wdrożenie usługi Azure Resource Manager

Podczas automatyzowania wdrożeń zasobów za pomocą szablonów usługi Azure Resource Manager może być konieczne sekwencjonowanie zależności w określonej kolejności, aby ta funkcja działała. Pamiętaj, aby zdefiniować ustawienia aplikacji jako własny zasób, zamiast używać siteConfig właściwości w definicji aplikacji. Jest to spowodowane tym, że aplikacja musi być najpierw zdefiniowana, aby tożsamość przypisana przez system została utworzona za jej pomocą i może być używana w zasadach dostępu.

Poniższy pseudo-szablon jest przykładem tego, jak może wyglądać aplikacja funkcji:

{
    //...
    "resources": [
        {
            "type": "Microsoft.Storage/storageAccounts",
            "name": "[variables('storageAccountName')]",
            //...
        },
        {
            "type": "Microsoft.Insights/components",
            "name": "[variables('appInsightsName')]",
            //...
        },
        {
            "type": "Microsoft.Web/sites",
            "name": "[variables('functionAppName')]",
            "identity": {
                "type": "SystemAssigned"
            },
            //...
            "resources": [
                {
                    "type": "config",
                    "name": "appsettings",
                    //...
                    "dependsOn": [
                        "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]",
                        "[resourceId('Microsoft.KeyVault/vaults/', variables('keyVaultName'))]",
                        "[resourceId('Microsoft.KeyVault/vaults/secrets', variables('keyVaultName'), variables('storageConnectionStringName'))]",
                        "[resourceId('Microsoft.KeyVault/vaults/secrets', variables('keyVaultName'), variables('appInsightsKeyName'))]"
                    ],
                    "properties": {
                        "AzureWebJobsStorage": "[concat('@Microsoft.KeyVault(SecretUri=', reference(variables('storageConnectionStringName')).secretUriWithVersion, ')')]",
                        "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "[concat('@Microsoft.KeyVault(SecretUri=', reference(variables('storageConnectionStringName')).secretUriWithVersion, ')')]",
                        "APPINSIGHTS_INSTRUMENTATIONKEY": "[concat('@Microsoft.KeyVault(SecretUri=', reference(variables('appInsightsKeyName')).secretUriWithVersion, ')')]",
                        "WEBSITE_ENABLE_SYNC_UPDATE_SITE": "true"
                        //...
                    }
                },
                {
                    "type": "sourcecontrols",
                    "name": "web",
                    //...
                    "dependsOn": [
                        "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]",
                        "[resourceId('Microsoft.Web/sites/config', variables('functionAppName'), 'appsettings')]"
                    ],
                }
            ]
        },
        {
            "type": "Microsoft.KeyVault/vaults",
            "name": "[variables('keyVaultName')]",
            //...
            "dependsOn": [
                "[resourceId('Microsoft.Web/sites', variables('functionAppName'))]"
            ],
            "properties": {
                //...
                "accessPolicies": [
                    {
                        "tenantId": "[reference(resourceId('Microsoft.Web/sites/', variables('functionAppName')), '2020-12-01', 'Full').identity.tenantId]",
                        "objectId": "[reference(resourceId('Microsoft.Web/sites/', variables('functionAppName')), '2020-12-01', 'Full').identity.principalId]",
                        "permissions": {
                            "secrets": [ "get" ]
                        }
                    }
                ]
            },
            "resources": [
                {
                    "type": "secrets",
                    "name": "[variables('storageConnectionStringName')]",
                    //...
                    "dependsOn": [
                        "[resourceId('Microsoft.KeyVault/vaults/', variables('keyVaultName'))]",
                        "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]"
                    ],
                    "properties": {
                        "value": "[concat('DefaultEndpointsProtocol=https;AccountName=', variables('storageAccountName'), ';AccountKey=', listKeys(variables('storageAccountResourceId'),'2019-09-01').key1)]"
                    }
                },
                {
                    "type": "secrets",
                    "name": "[variables('appInsightsKeyName')]",
                    //...
                    "dependsOn": [
                        "[resourceId('Microsoft.KeyVault/vaults/', variables('keyVaultName'))]",
                        "[resourceId('Microsoft.Insights/components', variables('appInsightsName'))]"
                    ],
                    "properties": {
                        "value": "[reference(resourceId('microsoft.insights/components/', variables('appInsightsName')), '2019-09-01').InstrumentationKey]"
                    }
                }
            ]
        }
    ]
}

Uwaga

W tym przykładzie wdrożenie kontroli źródła zależy od ustawień aplikacji. Jest to zwykle niebezpieczne zachowanie, ponieważ aktualizacja ustawień aplikacji zachowuje się asynchronicznie. Jednak ponieważ uwzględniliśmy WEBSITE_ENABLE_SYNC_UPDATE_SITE ustawienie aplikacji, aktualizacja jest synchroniczna. Oznacza to, że wdrożenie kontroli źródła rozpocznie się dopiero po pełnej aktualizacji ustawień aplikacji. Aby uzyskać więcej ustawień aplikacji, zobacz Zmienne środowiskowe i ustawienia aplikacji w usłudze aplikacja systemu Azure Service.

Rozwiązywanie problemów z odwołaniami do magazynu kluczy

Jeśli odwołanie nie zostanie poprawnie rozpoznane, zamiast tego zostanie użyty ciąg odwołania (na przykład @Microsoft.KeyVault(...)). Może to spowodować, że aplikacja zgłasza błędy, ponieważ oczekuje wpisu tajnego innej wartości.

Błąd rozwiązania jest często spowodowany błędną konfiguracją zasad dostępu usługi Key Vault. Może to być jednak spowodowane tym, że wpis tajny już nie istnieje lub błąd składniowy w samym odwołaniu.

Jeśli składnia jest poprawna, możesz wyświetlić inne przyczyny błędu, sprawdzając bieżący stan rozwiązania w portalu. Przejdź do pozycji Aplikacja Ustawienia i wybierz pozycję "Edytuj", aby uzyskać odwołanie. W oknie dialogowym edycji są wyświetlane informacje o stanie, w tym wszelkie błędy. Jeśli nie widzisz komunikatu o stanie, oznacza to, że składnia jest nieprawidłowa i nie jest rozpoznawana jako odwołanie do magazynu kluczy.

Możesz również użyć jednego z wbudowanych detektorów, aby uzyskać dodatkowe informacje.

Korzystanie z narzędzia do wykrywania dla usługi App Service

  1. W portalu przejdź do aplikacji.
  2. Kliknij pozycję Diagnozowanie i rozwiązywanie problemów.
  3. Wybierz pozycję Dostępność i wydajność , a następnie wybierz pozycję Aplikacja internetowa w dół.
  4. W polu wyszukiwania wyszukaj i wybierz pozycję Aplikacja usługi Key Vault Ustawienia Diagnostyka.

Korzystanie z narzędzia do wykrywania dla usługi Azure Functions

  1. W portalu przejdź do aplikacji.
  2. Przejdź do pozycji Funkcje platformy.
  3. Kliknij pozycję Diagnozowanie i rozwiązywanie problemów.
  4. Wybierz pozycję Dostępność i wydajność , a następnie wybierz pozycję Aplikacja funkcji nie działa lub zgłasza błędy.
  5. Wybierz pozycję Diagnostyka Ustawienia aplikacji usługi Key Vault.