Teilen über


Verwenden von Key Vault-Verweisen als App-Einstellungen in Azure App Service und Azure Functions

In diesem Artikel erfahren Sie, wie Sie geheime Schlüssel aus Azure Key Vault als Werte von App-Einstellungen oder Verbindungszeichenfolgen in Ihren Azure App Service- oder Azure Functions-Apps verwenden.

Key Vault ist ein Dienst, der zentrale geheime Verwaltung bietet, mit voller Kontrolle über Zugriffsrichtlinien und Überwachungsverlauf. Wenn es sich bei einer App-Einstellung oder Verbindungszeichenfolge um einen Key Vault-Verweis handelt, kann Ihr Anwendungscode ihn wie jede andere App-Einstellung oder Verbindungszeichenfolge verwenden. Auf diese Weise können Sie Geheimnisse abgesehen von der Konfiguration Ihrer App getrennt verwalten. App-Einstellungen werden sicher im Ruhezustand verschlüsselt, aber wenn Sie Funktionen zum Verwalten von geheimen Schlüsseln benötigen, sollten sie in einen Schlüsseltresor wechseln.

Gewähren des Zugriffs auf einen Schlüsseltresor für Ihre App

Um geheime Schlüssel aus einem Schlüsseltresor zu lesen, müssen Sie zuerst einen Tresor erstellen und Ihrer App Die Berechtigung für den Zugriff darauf erteilen:

  1. Erstellen Sie einen Schlüsseltresor anhand dieser Key Vault-Schnellstartanleitung.

  2. Erstellen Sie eine verwaltete Identität für Ihre App.

    Key Vault-Verweise verwenden standardmäßig die systemseitig zugewiesene Identität der App, aber Sie können auch eine benutzerseitig zugewiesene Identität angeben.

  3. Autorisieren Sie den Lesezugriff auf Geheimnisse in Ihrem Schlüsseltresor für die zuvor erstellte verwaltete Identität. Wie Sie hierzu vorgehen, hängt vom Berechtigungsmodell Ihres Schlüsseltresors ab:

Zugriff auf Werte mit Netzwerkeinschränkungen

Wenn Ihr Tresor mit Netzwerkeinschränkungen konfiguriert ist, stellen Sie außerdem sicher, dass die Anwendung über Netzwerkzugriff verfügt. Tresore sollten nicht von den öffentlichen ausgehenden IP-Adressen der App abhängen, da die Ursprungs-IP-Adresse der geheimen Anforderung unterschiedlich sein könnte. Stattdessen sollte der Tresor so konfiguriert werden, dass er Datenverkehr aus einem virtuellen Netzwerk akzeptiert, das von der App verwendet wird.

  1. Stellen Sie sicher, dass die Anwendung ausgehende Netzwerkfunktionen konfiguriert hat, wie in app Service-Netzwerkfunktionen und Azure Functions-Netzwerkoptionen beschrieben.

    Derzeit müssen Linux-Anwendungen, die eine Verbindung mit privaten Endpunkten herstellen, explizit konfiguriert werden, um den gesamten Datenverkehr über das virtuelle Netzwerk weiterzuleiten. Um diese Einstellung zu konfigurieren, führen Sie den folgenden Befehl aus:

    az webapp config set --resource-group <group-name>  --subscription <subscription> --name <app-name> --generic-configurations '{"vnetRouteAllEnabled": true}'
    
  2. Stellen Sie sicher, dass die Konfiguration des Tresors das Netzwerk oder Subnetz zulässt, über das Ihre App darauf zugreift.

Beachten Sie, dass selbst wenn Sie den Tresor ordnungsgemäß so konfiguriert haben, dass der Datenverkehr aus Ihrem virtuellen Netzwerk akzeptiert wird, die Überwachungsprotokolle des Tresors möglicherweise immer noch ein fehlgeschlagenes SecretGet-Ereignis (403 - Verboten) von der öffentlichen ausgehenden IP-Adresse der App anzeigen. Auf dieses Ereignis folgt erwartbar ein erfolgreiches SecretGet-Ereignis über die private IP-Adresse der App.

Zugriff auf Tresore mit einer benutzerseitig zugewiesenen Identität

Einige Apps müssen zur Erstellungszeit auf geheime Schlüssel verweisen, wenn eine vom System zugewiesene Identität noch nicht verfügbar ist. Erstellen Sie in diesen Fällen eine benutzerseitig zugewiesene Identität, und gewähren Sie ihr im Voraus Zugriff auf den Tresor.

Nachdem Sie berechtigungen für die vom Benutzer zugewiesene Identität erteilt haben, führen Sie die folgenden Schritte aus:

  1. Weisen Sie der Anwendung die Identität zu.

  2. Konfigurieren Sie die App so, dass diese Identität für Key Vault-Referenzvorgänge verwendet wird, indem Sie die keyVaultReferenceIdentity Eigenschaft auf die Ressourcen-ID der vom Benutzer zugewiesenen Identität festlegen:

    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}
    

Diese Einstellung gilt für alle Key Vault-Verweise für die App.

Verständnis der Rotation

Wenn die Geheimnisversion nicht im Verweis angegeben ist, verwendet die App die neueste Version, die im Schlüsseltresor vorhanden ist. Wenn neuere Versionen verfügbar werden, z. B. mit Drehung, wird die App automatisch aktualisiert und beginnt innerhalb von 24 Stunden mit der verwendung der neuesten Version.

Die Verzögerung liegt daran, dass der App-Dienst die Werte der Key Vault-Verweise zwischenspeichert und sie alle 24 Stunden zurückweckt. Alle Konfigurationsänderungen an der App verursachen einen Neustart sowie eine sofortige Neuabfrage aller Geheimnisse, auf die verwiesen wird.

Um die Auflösung der Key Vault-Verweise Ihrer App zu erzwingen, erstellen Sie eine authentifizierte POST-Anforderung an den API-Endpunkt https://management.azure.com/[Resource ID]/config/configreferences/appsettings/refresh?api-version=2022-03-01.

Grundlegendes zu den Quell-App-Einstellungen aus Key Vault

Um einen Key Vault-Verweis zu verwenden, legen Sie den Verweis als Wert der Einstellung fest. Ihre App kann wie gewohnt durch seinen Schlüssel auf das Geheimnis verweisen. Es sind keine Codeänderungen erforderlich.

Tipp

Da Sie für jede Umgebung über separate Tresore verfügen sollten, sollten die meisten App-Einstellungen, die Key Vault-Verweise verwenden, als Sloteinstellungen gekennzeichnet werden.

Ein Key Vault-Verweis hat die Form @Microsoft.KeyVault({referenceString}), wobei {referenceString} eines der folgenden Formate aufweist:

Verweiszeichenfolge BESCHREIBUNG
SecretUri=<secretUri> Das SecretUri sollte der vollständige Datenebenen-URI eines geheimen Schlüssels im Tresor sein. Beispiel: https://myvault.vault.azure.net/secrets/mysecret. Schließen Sie optional eine Version ein (z. B. https://myvault.vault.azure.net/secrets/mysecret/ec96f02080254f109c51a1f14cdb1931).
VaultName=<vaultName>;SecretName=<secretName>;SecretVersion=<secretVersion> Der VaultName-Wert ist erforderlich und der Tresorname. Der SecretName Wert ist erforderlich und ist der geheime Name. Der SecretVersion Wert ist optional, gibt aber, falls vorhanden, die Version des zu verwendenden Schlüssels an.

Ein vollständiger Verweis ohne spezifische Version sieht beispielsweise wie folgt aus:

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

Alternativ:

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

Überlegungen zum Einbinden von Azure Files

Apps können die WEBSITE_CONTENTAZUREFILECONNECTIONSTRING-Anwendungseinstellung verwenden, um Azure Files als Dateisystem einzubinden. Diese Einstellung verfügt über Überprüfungen, um sicherzustellen, dass die App ordnungsgemäß gestartet werden kann.

Die Plattform basiert auf einer Inhaltsfreigabe in Azure Files. Die Plattform verwendet einen Standardnamen, es sei denn, ein Name wird über die WEBSITE_CONTENTSHARE Einstellung angegeben. Bei Anforderungen, die diese Einstellungen ändern, überprüft die Plattform, ob diese Inhaltsfreigabe vorhanden ist. Wenn das Content-Sharing nicht existiert, versucht die Plattform, es zu erstellen. Wenn die Plattform die Inhaltsfreigabe nicht finden oder erstellen kann, blockiert sie die Anforderung.

Wenn Sie Key Vault-Verweise in dieser Einstellung verwenden, schlägt die Überprüfung standardmäßig fehl, da der geheime Schlüssel während der Verarbeitung der eingehenden Anforderung nicht aufgelöst werden kann. Um dieses Problem zu vermeiden, können Sie die Überprüfung überspringen, indem Sie die Einstellung WEBSITE_SKIP_CONTENTSHARE_VALIDATION auf 1. Diese Einstellung weist App Service an, sämtliche Überprüfungen zu umgehen und die Inhaltsfreigabe nicht zu erstellen. Sie sollten im Voraus sicherstellen, dass die Inhaltsfreigabe erstellt wird.

Achtung

Wenn Sie die Überprüfung überspringen und entweder die Verbindungszeichenfolge oder die Inhaltsfreigabe ungültig ist, wird die App nicht ordnungsgemäß gestartet und HTTP 500-Fehler erstellt.

Im Rahmen der Erstellung der App kann der Einbindungsversuch der Inhaltsfreigabe fehlschlagen, wenn Berechtigungen für verwaltete Identitäten nicht verteilt oder die VNet-Integration nicht eingerichtet wurde. Sie können das Einrichten von Azure Files bis zu einem späteren Zeitpunkt in der Bereitstellungsvorlage zurückstellen, um dieses Verhalten zu berücksichtigen. Weitere Informationen finden Sie weiter unten in diesem Artikel unter Azure Resource Manager-Bereitstellung .

In diesem Fall verwendet App Service ein Standarddateisystem, bis Azure Files eingerichtet ist, und es werden keine Dateien kopiert. Sie müssen sicherstellen, dass in der Zwischenzeit vor der Einbindung von Azure Files keine Bereitstellungsversuche unternommen werden.

Überlegungen zur Application Insights-Instrumentierung

Apps können die APPINSIGHTS_INSTRUMENTATIONKEY- oder APPLICATIONINSIGHTS_CONNECTION_STRING-Anwendungseinstellungen zur Integration mit Application Insights verwenden.

Für App Service und Azure Functions verwendet das Azure-Portal diese Einstellungen auch, um Telemetriedaten aus der Ressource anzuzeigen. Wenn auf diese Werte über Key Vault verwiesen wird, ist dieser Ansatz nicht verfügbar. Stattdessen müssen Sie direkt mit der Application Insights-Ressource arbeiten, um die Telemetrie anzuzeigen. Diese Werte gelten jedoch nicht als geheime Schlüssel, daher können Sie diese direkt konfigurieren, anstatt Key Vault-Verweise zu verwenden.

Azure Resource Manager-Bereitstellung

Wenn Sie Ressourcenbereitstellungen über Azure Resource Manager-Vorlagen automatisieren, müssen Sie Ihre Abhängigkeiten möglicherweise in einer bestimmten Reihenfolge sequenzieren. Stellen Sie sicher, dass Sie Ihre Anwendungseinstellungen als eine eigene Ressource definieren, anstatt eine siteConfig-Eigenschaft in der App-Definition zu verwenden. Die App muss zuerst definiert werden, sodass die vom System zugewiesene Identität angelegt und in der Zugriffsrichtlinie verwendet werden kann.

Die folgende Pseudovorlage ist ein Beispiel dafür, wie eine Funktions-App aussehen könnte:

{
    //...
    "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]"
                    }
                }
            ]
        }
    ]
}

Hinweis

In diesem Beispiel hängt die Bereitstellung der Quellcodeverwaltung von den Anwendungseinstellungen ab. Diese Abhängigkeit ist normalerweise unsicher, da sich das Update der App-Einstellung asynchron verhält. Da Sie jedoch die WEBSITE_ENABLE_SYNC_UPDATE_SITE Anwendungseinstellung eingeschlossen haben, ist das Update synchron. Die Bereitstellung der Quellcodeverwaltung beginnt erst, nachdem die Anwendungseinstellungen vollständig aktualisiert wurden. Weitere App-Einstellungen finden Sie unter Umgebungsvariablen und App-Einstellungen in Azure App Service.

Fehlerbehebung bei Key Vault-Referenzen

Wenn ein Verweis nicht ordnungsgemäß aufgelöst wird, wird die Referenzzeichenfolge stattdessen verwendet, z. B. @Microsoft.KeyVault(...). Diese Situation kann dazu führen, dass die Anwendung Fehler auslöst, da sie einen geheimen Schlüssel eines anderen Werts erwartet.

Für Auflösungsfehler ist die Ursache meist eine fehlerhafte Konfiguration der Key Vault-Zugriffsrichtlinie. Der Grund könnte jedoch auch sein, dass ein Geheimschlüssel nicht mehr vorhanden ist oder der Verweis einen Syntaxfehler enthält.

Wenn die Syntax korrekt ist, können Sie andere Ursachen für einen Fehler anzeigen, indem Sie den aktuellen Auflösungsstatus im Azure-Portal überprüfen. Wechseln Sie zu "Anwendungseinstellungen" , und wählen Sie "Bearbeiten" für den betreffenden Verweis aus. Im Dialogfeld „Bearbeiten“ werden Statusinformationen angezeigt, einschließlich aller Fehler. Wenn die Statusmeldung nicht angezeigt wird, bedeutet dies, dass die Syntax ungültig und nicht als Key Vault-Verweis erkannt wird.

Sie können auch einen der integrierten Detektoren verwenden, um weitere Informationen zu erhalten.

So verwenden Sie den Detektor für App Service:

  1. Wechseln Sie im Azure-Portal zu Ihrer App.
  2. Wählen Sie Probleme diagnostizieren und beheben aus.
  3. Wählen Sie Verfügbarkeit und Leistung>Web App nicht aktiv aus.
  4. Suchen Sie im Suchfeld nach Key Vault-Anwendungseinstellungsdiagnose, und wählen Sie sie aus.

So verwenden Sie den Detektor für Azure Functions:

  1. Wechseln Sie im Azure-Portal zu Ihrer App.
  2. Wechseln Sie zu Plattformfeatures.
  3. Wählen Sie Probleme diagnostizieren und beheben aus.
  4. Wählen Sie die Verfügbarkeit und Leistung>Funktions-App ist ausgefallen oder meldet Fehler.
  5. Wählen Sie Key Vault-Anwendungseinstellungsdiagnose aus.