Freigeben über


Authentifizieren und Autorisieren von App Service für eine Vektordatenbank

In diesem Artikel wird veranschaulicht, wie Sie die Verbindung zwischen Ihrer App Service-.NET-Anwendung und einer Vektordatenbanklösung verwalten. Er erläutert die Verwendung von verwalteten Microsoft Entra-Identitäten für unterstützte Dienste und das sichere Speichern von Verbindungszeichenfolgen für andere.

Indem Sie Ihrer Anwendung eine Vektordatenbank hinzufügen, können Sie semantische Erinnerungen für Ihre KI aktivieren. Mit dem Semantic Kernel SDK für .NET können Sie problemlos die Speicherung und den Abruf von Erinnerungen implementieren.

Voraussetzungen

Verwenden einer verwalteten Microsoft Entra-Identität für die Authentifizierung

Wenn ein Vektordatenbankdienst die Microsoft Entra-Authentifizierung unterstützt, können Sie eine verwaltete Identität mit Ihrer App Service-Instanz verwenden, um sicher auf Ihre Vektordatenbank zuzugreifen, ohne manuell Geheimnisse bereitstellen oder rotieren zu müssen. Eine Liste der Azure-Dienste, die die Microsoft Entra-Authentifizierung unterstützen, finden Sie unter Azure-Dienste, die die Microsoft Entra-Authentifizierung unterstützen.

Hinzufügen einer verwalteten Identität zu App Service

Ihrer Anwendung können zwei Arten von Identitäten zugewiesen werden:

  • Eine systemseitig zugewiesene Identität ist an Ihre Anwendung gebunden und wird gelöscht, wenn Ihre App gelöscht wird. Eine App kann nur eine systemseitig zugewiesene Identität haben.
  • Eine benutzerseitig zugewiesene Identität ist eine eigenständige Azure-Ressource, die Ihrer App zugewiesen werden kann. Eine App kann über mehrere benutzerseitig zugewiesene Identitäten verfügen.

Hinzufügen einer systemseitig zugewiesenen Identität

  1. Navigieren Sie im Azure-Portal zur Seite Ihrer App, und scrollen Sie dann nach unten zur Gruppe Einstellungen.
  2. Wählen Sie Identität aus.
  3. Schalten Sie auf der Registerkarte Systemseitig zugewiesen den Status auf Ein um, und wählen Sie dann Speichern aus.

Führen Sie den Befehl az webapp identity assign aus, um eine vom System zugewiesene Identität zu erstellen:

az webapp identity assign --name <appName> --resource-group <groupName>

Hinzufügen einer benutzerseitig zugewiesenen Identität

Um Ihrer App eine benutzerseitig zugewiesene Identität hinzuzufügen, erstellen Sie die Identität, und fügen Sie dann der App-Konfiguration den Ressourcenbezeichner hinzu.

  1. Erstellen Sie anhand dieser Anweisungen eine Ressource für eine benutzerseitig zugewiesene verwaltete Identität.

  2. Scrollen Sie im linken Navigationsbereich der App-Seite nach unten zur Gruppe Einstellungen.

  3. Wählen Sie Identität aus.

  4. Wählen Sie Benutzerseitig zugewiesen>Hinzufügen aus.

  5. Suchen Sie die Identität, die Sie zuvor erstellt haben, wählen Sie sie aus, und wählen Sie dann Hinzufügen aus.

    Wichtig

    Nach dem Auswählen von Hinzufügen wird die App neu gestartet.

  1. Erstellen einer benutzerseitig zugewiesenen Identität:

    az identity create --resource-group <groupName> --name <identityName>
    
  2. Zuweisen der Identität zu Ihrer App:

    az webapp identity assign --resource-group <groupName> --name <appName> --identities <identityId>
    

Hinzufügen einer Azure-Rolle zu Ihrer verwalteten Identität

  1. Navigieren Sie im Azure Portal zu dem Bereich, auf den Sie Vektordatenbankzugriff gewähren möchten. Der Bereich kann eine Verwaltungsgruppe, ein Abonnement, eine Ressourcengruppe oder eine bestimmte Azure-Ressource sein.
  2. Wählen Sie im linken Navigationsbereich Zugriffssteuerung (IAM) aus.
  3. Wählen Sie Hinzufügen und dann Rollenzuweisung hinzufügen aus.
  4. Wählen Sie auf der Registerkarte Rolle die entsprechende Rolle aus, die Lesezugriff auf Ihre Vektordatenbank gewährt.
  5. Wählen Sie auf der Registerkarte Mitglieder die verwaltete Identität aus.
  6. Wählen Sie auf der Registerkarte Überprüfen und zuweisen die Option Überprüfen und zuweisen aus, um die Rolle zuzuweisen.

Ressourcenbereich

az role assignment create --assignee "<managedIdentityObjectID>" \
--role "<myVectorDbReaderRole>" \
--scope "/subscriptions/<subscriptionId>/resourcegroups/<resourceGroupName>/providers/<providerName>/<resourceType>/<resourceSubType>/<resourceName>"

Ressourcengruppenbereich

az role assignment create --assignee "<managedIdentityObjectID>" \
--role "<myVectorDbReaderRole>" \
--scope "/subscriptions/<subscriptionId>/resourcegroups/<resourceGroupName>"

Abonnementbereich

az role assignment create --assignee "<managedIdentityObjectID>" \
--role "<myVectorDbReaderRole>" \
--scope "/subscriptions/<subscriptionId>"

Verwaltungsgruppenbereich

az role assignment create --assignee "<managedIdentityObjectID>" \
--role "<myVectorDbReaderRole>" \
--scope "/providers/Microsoft.Management/managementGroups/<managementGroupName>"

Implementieren der tokenbasierten Authentifizierung mit der Vektordatenbank

Für die folgenden Codebeispiele sind diese zusätzlichen Bibliotheken erforderlich:

  1. Initialisieren Sie ein DefaultAzureCredential-Objekt, um die verwaltete Identität Ihrer App abzurufen:

    // Initialize a DefaultAzureCredential.
    // This credential type will try several authentication flows in order until one is available.
    // Will pickup Visual Studio or Azure CLI credentials in local environments.
    // Will pickup managed identity credentials in production deployments.
    TokenCredential credentials = new DefaultAzureCredential(
        new DefaultAzureCredentialOptions
        {
            // If using a user-assigned identity specify either:
            // ManagedIdentityClientId or ManagedIdentityResourceId.
            // e.g.: ManagedIdentityClientId = "myIdentityClientId".
        }
    );
    
  2. Initialisieren Sie ein IMemoryStore-Objekt für Ihre Vektordatenbank, und erstellen Sie dann damit ein ISemanticTextMemory-Element:

    // Retrieve the endpoint obtained from the Azure AI Search deployment.
    // Retrieve the endpoint and deployments obtained from the Azure OpenAI deployment.
    // Must use the deployment name not the underlying model name.
    IConfigurationRoot config = new ConfigurationBuilder().AddUserSecrets<Program>().Build();
    string searchEndpoint = config["AZURE_AISEARCH_ENDPOINT"]!;
    string openAiEndpoint = config["AZURE_OPENAI_ENDPOINT"]!;
    string embeddingModel = config["AZURE_OPENAI_EMBEDDING_NAME"]!;
    
    // The Semantic Kernel SDK provides a connector extension for Azure AI Search.
    // Initialize an AzureAISearchMemoryStore using your managed identity credentials.
    IMemoryStore memoryStore = new AzureAISearchMemoryStore(searchEndpoint, credentials);
    
    // Build a SemanticMemoryStore with Azure AI Search as the store.
    // Must also include a text embedding generation service.
    ISemanticTextMemory memory = new MemoryBuilder()
        .WithAzureOpenAITextEmbeddingGeneration(embeddingModel, openAiEndpoint, credentials)
        .WithMemoryStore(memoryStore)
        .Build();
    
  3. Erstellen Sie ein Kernel-Objekt, und importieren Sie dann das ISemanticTextMemory-Objekt mithilfe von TextMemoryPlugin:

    // Build a Kernel, include a chat completion service.
    string chatModel = config["AZURE_OPENAI_GPT_NAME"]!;
    Kernel kernel = Kernel
        .CreateBuilder()
        .AddAzureOpenAIChatCompletion(chatModel, openAiEndpoint, credentials)
        .Build();
    
    // Import the semantic memory store as a TextMemoryPlugin.
    // The TextMemoryPlugin enable recall via prompt expressions.
    kernel.ImportPluginFromObject(new TextMemoryPlugin(memory));
    
  4. Verwenden Sie das Kernel-Objekt, um eine Eingabeaufforderung aufzurufen, die den Abruf von Erinnerungen beinhaltet:

    // Must configure the memory collection, number of memories to recall, and relevance score.
    // The {{...}} syntax represents an expression to Semantic Kernel.
    // For more information on this syntax see:
    // https://learn.microsoft.com/semantic-kernel/prompts/prompt-template-syntax
    string memoryCollection = config["AZURE_OPENAI_MEMORY_NAME"]!;
    string? result = await kernel.InvokePromptAsync<string>(
        "{{recall 'where did I grow up?'}}",
        new()
        {
            [TextMemoryPlugin.CollectionParam] = memoryCollection,
            [TextMemoryPlugin.LimitParam] = "2",
            [TextMemoryPlugin.RelevanceParam] = "0.79",
        }
    );
    Console.WriteLine($"Output: {result}");
    

Verwenden von Key Vault zum Speichern von Verbindungsgeheimnissen

Wenn eine Vektordatenbank die Microsoft Entra-Authentifizierung nicht unterstützt, können Sie Key Vault verwenden, um Ihre Verbindungsgeheimnisse zu speichern und mit Ihrer App Service-Anwendung abzurufen. Wenn Sie Key Vault zum Speichern Ihrer Verbindungsgeheimnisse verwenden, können Sie sie für mehrere Anwendungen freigeben und den Zugriff auf einzelne Geheimnisse pro Anwendung steuern.

Rufen Sie vor dem Ausführen dieser Schritte eine Verbindungszeichenfolge für Ihre Vektordatenbank ab. Siehe z. B. Verwenden von Azure Cache for Redis mit einer ASP.NET Core-Web-App.

Hinzufügen einer Verbindungszeichenfolge zu Key Vault

Wichtig

Stellen Sie vor dem Ausführen dieser Schritte sicher, dass Sie eine Key Vault-Instanz über das Azure-Portal erstellt haben.

  1. Navigieren Sie im Azure-Portal zu Ihrem Schlüsseltresor.
  2. Wählen Sie im linken Navigationsbereich von Key Vault Objekte und dann Geheimnisse aus.
  3. Wählen Sie die Option + Generieren/Importieren aus.
  4. Wählen Sie auf dem Bildschirm Geheimnis erstellen folgende Werte aus:
    • Uploadoptionen: Manual.
    • Name: Geben Sie einen Namen für das Geheimnis ein. Der Geheimnisname muss innerhalb einer Key Vault-Instanz eindeutig sein.
    • Wert: Die Verbindungszeichenfolge für die Vektordatenbank.
    • Behalten Sie bei den anderen Optionen die Standardwerte bei. Klicken Sie auf Erstellen.
  5. Wenn Sie die Nachricht erhalten, dass das Geheimnis erfolgreich erstellt wurde, kann es in Ihrer Anwendung verwendet werden.

Wichtig

Stellen Sie vor dem Ausführen dieser Schritte sicher, dass Sie eine Key Vault-Instanz über die Azure CLI erstellt haben.

  1. Gewähren Sie Ihrem Benutzerkonto Berechtigungen für Ihren Schlüsseltresor über die rollenbasierte Zugriffssteuerung (Role-Based Access Control, RBAC), und weisen Sie eine Rolle mithilfe des Azure CLI-Befehls az role assignment create zu:

    az role assignment create \
    --role "Key Vault Secrets User" \
    --assignee "<yourEmailAddress>" \
    --scope "/subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/providers/Microsoft.KeyVault/vaults/<keyVaultName>"
    
  2. Fügen Sie die Verbindungszeichenfolge mithilfe des Azure CLI-Befehls az keyvault secret set zur Key Vault-Instanz hinzu:

    az keyvault secret set \
    --vault-name "<keyVaultName>" \
    --name "<secretName>" \
    --value "<connectionString>"
    

Gewähren des Zugriffs auf Key Vault für App Service

  1. Weisen Sie App Service eine verwaltete Identität zu.
  2. Fügen Sie Ihrer verwalteten Identität die Rollen Key Vault Secrets User und Key Vault Reader hinzu.

Implementieren des Abrufs von Verbindungszeichenfolgen aus Key Vault

Zur Verwendung der folgenden Codebeispiele sind diese zusätzlichen Bibliotheken erforderlich:

In diesen Codebeispielen wird eine Redis-Datenbank verwendet. Sie können sie jedoch auf jede Vektordatenbank anwenden, die Verbindungszeichenfolgen unterstützt.

  1. Initialisieren Sie ein DefaultAzureCredential-Objekt, um die verwaltete Identität Ihrer App abzurufen:

    // Initialize a DefaultAzureCredential.
    // This credential type will try several authentication flows in order until one is available.
    // Will pickup Visual Studio or Azure CLI credentials in local environments.
    // Will pickup managed identity credentials in production deployments.
    TokenCredential credentials = new DefaultAzureCredential(
        new DefaultAzureCredentialOptions
        {
            // If using a user-assigned identity specify either:
            // ManagedIdentityClientId or ManagedIdentityResourceId.
            // e.g.: ManagedIdentityClientId = "myIdentityClientId".
        }
    );
    
  2. Fügen Sie Key Vault hinzu, wenn Sie Ihre Konfiguration erstellen. Dadurch werden Ihre Key Vault-Geheimnisse dem IConfigurationRoot-Objekt zugeordnet:

    // User secrets let you provide connection strings when testing locally
    // For more info see: https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets
    IConfigurationRoot config = new ConfigurationBuilder()
        .AddUserSecrets<Program>()
        .AddAzureKeyVault(new Uri("{vaultURI}"), credentials)
        .Build();
    
    // Retrieve the Redis connection string obtained from the Key Vault.
    string redisConnectionString = config["AZURE_REDIS_CONNECT_STRING"]!;
    
  3. Verwenden Sie die Verbindungszeichenfolge Ihrer Vektordatenbank aus Key Vault, um ein IMemoryStore-Objekt zu initialisieren und dann ein ISemanticTextMemory-Element zu erstellen:

    // Use the connection string to connect to the database
    IDatabase database = (
        await ConnectionMultiplexer.ConnectAsync(redisConnectionString)
    ).GetDatabase();
    
    // The Semantic Kernel SDK provides a connector extension for Redis.
    // Initialize an RedisMemoryStore using your managed identity credentials.
    IMemoryStore memoryStore = new RedisMemoryStore(database);
    
    // Retrieve the endpoint and deployments obtained from the Azure OpenAI deployment.
    // Must use the deployment name not the underlying model name.
    string openAiEndpoint = config["AZURE_OPENAI_ENDPOINT"]!;
    string embeddingModel = config["AZURE_OPENAI_EMBEDDING_NAME"]!;
    
    // Build a SemanticMemoryStore with Azure AI Search as the store.
    // Must also include a text embedding generation service.
    ISemanticTextMemory memory = new MemoryBuilder()
        .WithAzureOpenAITextEmbeddingGeneration(embeddingModel, openAiEndpoint, credentials)
        .WithMemoryStore(memoryStore)
        .Build();
    
  4. Erstellen Sie ein Kernel-Objekt, und importieren Sie dann das ISemanticTextMemory-Objekt mithilfe von TextMemoryPlugin:

    // Build a Kernel, include a chat completion service.
    string chatModel = config["AZURE_OPENAI_GPT_NAME"]!;
    Kernel kernel = Kernel
        .CreateBuilder()
        .AddAzureOpenAIChatCompletion(chatModel, openAiEndpoint, credentials)
        .Build();
    
    // Import the semantic memory store as a TextMemoryPlugin.
    // The TextMemoryPlugin enable recall via prompt expressions.
    kernel.ImportPluginFromObject(new TextMemoryPlugin(memory));
    
  5. Verwenden Sie das Kernel-Objekt, um eine Eingabeaufforderung aufzurufen, die den Abruf von Erinnerungen beinhaltet:

    // Must configure the memory collection, number of memories to recall, and relevance score.
    // The {{...}} syntax represents an expression to Semantic Kernel.
    // For more information on this syntax see:
    // https://learn.microsoft.com/semantic-kernel/prompts/prompt-template-syntax
    string memoryCollection = config["AZURE_OPENAI_MEMORY_NAME"]!;
    string? result = await kernel.InvokePromptAsync<string>(
        "{{recall 'where did I grow up?'}}",
        new()
        {
            [TextMemoryPlugin.CollectionParam] = memoryCollection,
            [TextMemoryPlugin.LimitParam] = "2",
            [TextMemoryPlugin.RelevanceParam] = "0.79",
        }
    );
    Console.WriteLine($"Output: {result}");
    

Verwenden von Anwendungseinstellungen zum Speichern von Verbindungsgeheimnissen

Wenn eine Vektordatenbank die Microsoft Entra-Authentifizierung nicht unterstützt, können Sie die App Service-Anwendungseinstellungen verwenden, um Ihre Verbindungsgeheimnisse zu speichern. Mithilfe von Anwendungseinstellungen können Sie Ihre Verbindungsgeheimnisse speichern, ohne zusätzliche Azure-Ressourcen bereitzustellen.

Rufen Sie vor dem Ausführen dieser Schritte eine Verbindungszeichenfolge für Ihre Vektordatenbank ab. Siehe beispielsweise Verwenden von Azure Cache for Redis in .NET Framework.

Hinzufügen einer Verbindungszeichenfolge zu Anwendungseinstellungen

  1. Navigieren Sie im Azure-Portal zur Seite Ihrer App.
  2. Wählen Sie im linken Menü der App Konfiguration>Anwendungseinstellungen aus.
    • Aus Sicherheitsgründen werden Werte für Anwendungseinstellungen im Portal standardmäßig ausgeblendet.
    • Um einen ausgeblendeten Wert einer Anwendungseinstellung anzuzeigen, wählen Sie dessen Feld „Wert“ aus.
  3. Wählen Sie Neue Verbindungseinstellung aus.
  4. Wählen Sie auf dem Bildschirm Verbindungszeichenfolge hinzufügen/bearbeiten die folgenden Werte aus:
    • Name: Geben Sie einen Namen für die Einstellung ein. Der Name der Einstellung muss eindeutig sein.
    • Wert: Die Verbindungszeichenfolge für die Vektordatenbank.
    • Wert: Der Verbindungstyp. Custom, wenn keine anderen Werte gelten.
    • Behalten Sie bei den anderen Optionen die Standardwerte bei. Wählen Sie OK aus.
  5. Wählen Sie auf der Seite „Konfiguration“ die Option Speichern aus.

Mit dem Azure CLI-Befehl az webapp config connection-string set können Sie eine App-Einstellung hinzufügen oder bearbeiten:

az webapp config connection-string set \
--name "<appName>" \
--resource-group "<groupName>" \
--connection-string-type "<connectionType>" \
--settings <connectionName>='<connectionString>'

Implementieren des Abrufs von Verbindungszeichenfolgen aus App-Einstellungen

Zur Verwendung der folgenden Codebeispiele sind diese zusätzlichen Bibliotheken erforderlich:

In diesen Codebeispielen wird eine Redis-Datenbank verwendet. Sie können sie jedoch auf jede Vektordatenbank anwenden, die Verbindungszeichenfolgen unterstützt.

  1. Fügen Sie beim Erstellen der Konfiguration Umgebungsvariablen hinzu. Dadurch werden die Verbindungszeichenfolgen dem IConfigurationRoot-Objekt zugeordnet:

    // User secrets let you provide connection strings when testing locally
    // For more info see: https://learn.microsoft.com/en-us/aspnet/core/security/app-secrets
    IConfigurationRoot config = new ConfigurationBuilder()
        .AddUserSecrets<Program>()
        .AddEnvironmentVariables()
        .Build();
    
    // Retrieve the Redis connection string obtained from the app settings.
    // The connection string name should match the entry in application settings
    string redisConnectionString = config.GetConnectionString("AZURE_REDIS")!;
    
  2. Verwenden Sie die Verbindungszeichenfolge Ihrer Vektordatenbank aus den App-Einstellungen, um ein IMemoryStore-Objekt zu initialisieren und dann ein ISemanticTextMemory-Element zu erstellen:

    // Use the connection string to connect to the database
    IDatabase database = (
        await ConnectionMultiplexer.ConnectAsync(redisConnectionString)
    ).GetDatabase();
    
    // The Semantic Kernel SDK provides a connector extension for Redis.
    // Initialize an RedisMemoryStore using your managed identity credentials.
    IMemoryStore memoryStore = new RedisMemoryStore(database);
    
    // Retrieve the endpoint and deployments obtained from the Azure OpenAI deployment.
    // Must use the deployment name not the underlying model name.
    string openAiEndpoint = config["AZURE_OPENAI_ENDPOINT"]!;
    string embeddingModel = config["AZURE_OPENAI_EMBEDDING_NAME"]!;
    
    // Build a SemanticMemoryStore with Azure AI Search as the store.
    // Must also include a text embedding generation service.
    ISemanticTextMemory memory = new MemoryBuilder()
        .WithAzureOpenAITextEmbeddingGeneration(embeddingModel, openAiEndpoint, credentials)
        .WithMemoryStore(memoryStore)
        .Build();
    
  3. Erstellen Sie ein Kernel-Objekt, und importieren Sie dann das ISemanticTextMemory-Objekt mithilfe von TextMemoryPlugin:

    // Build a Kernel, include a chat completion service.
    string chatModel = config["AZURE_OPENAI_GPT_NAME"]!;
    Kernel kernel = Kernel
        .CreateBuilder()
        .AddAzureOpenAIChatCompletion(chatModel, openAiEndpoint, credentials)
        .Build();
    
    // Import the semantic memory store as a TextMemoryPlugin.
    // The TextMemoryPlugin enable recall via prompt expressions.
    kernel.ImportPluginFromObject(new TextMemoryPlugin(memory));
    
  4. Verwenden Sie das Kernel-Objekt, um eine Eingabeaufforderung aufzurufen, die den Abruf von Erinnerungen beinhaltet:

    // Must configure the memory collection, number of memories to recall, and relevance score.
    // The {{...}} syntax represents an expression to Semantic Kernel.
    // For more information on this syntax see:
    // https://learn.microsoft.com/semantic-kernel/prompts/prompt-template-syntax
    string memoryCollection = config["AZURE_OPENAI_MEMORY_NAME"]!;
    string? result = await kernel.InvokePromptAsync<string>(
        "{{recall 'where did I grow up?'}}",
        new()
        {
            [TextMemoryPlugin.CollectionParam] = memoryCollection,
            [TextMemoryPlugin.LimitParam] = "2",
            [TextMemoryPlugin.RelevanceParam] = "0.79",
        }
    );
    Console.WriteLine($"Output: {result}");