Autenticar e autorizar o Serviço de Aplicativo em um banco de dados vetorial
Este artigo demonstra como gerenciar a conexão entre seu aplicativo .NET do Serviço de Aplicativo e uma solução de banco de dados vetorial. Ele abrange o uso de identidades gerenciadas do Microsoft Entra para serviços suportados e o armazenamento seguro de cadeias de conexão para outros.
Ao adicionar um banco de dados vetorial ao seu aplicativo, você pode habilitar [memórias semânticas ou repositórios vetoriais] (repositórios vetoriais) para sua IA. O SDK do Kernel Semântico para .NET permite que você implemente facilmente o armazenamento e a recuperação de memória usando sua solução de banco de dados vetorial preferida.
Pré-requisitos
- Uma conta do Azure com uma subscrição ativa. Crie uma conta gratuitamente.
- SDK do .NET
Microsoft.SemanticKernel
Pacote NuGetMicrosoft.SemanticKernel.Plugins.Memory
Pacote NuGet- Criar e implantar um aplicativo .NET no Serviço de Aplicativo
- Criar e implantar uma solução de banco de dados vetorial
Usar a identidade gerenciada do Microsoft Entra para autenticação
Se um serviço de banco de dados vetorial oferecer suporte à autenticação do Microsoft Entra, você poderá usar uma identidade gerenciada com seu Serviço de Aplicativo para acessar com segurança seu banco de dados vetorial sem precisar provisionar ou girar manualmente quaisquer segredos. Para obter uma lista dos serviços do Azure que suportam a autenticação do Microsoft Entra, consulte Serviços do Azure que suportam a autenticação do Microsoft Entra.
Adicionar uma identidade gerenciada ao Serviço de Aplicativo
Pode conceder dois tipos de identidades à aplicação:
- Uma identidade atribuída pelo sistema está associada à aplicação e será eliminada se a aplicação for eliminada. Um aplicativo pode ter apenas uma identidade atribuída ao sistema.
- Uma identidade atribuída pelo utilizador é um recurso autónomo do Azure que pode ser atribuído à aplicação. Uma aplicação pode ter várias identidades atribuídas pelo utilizador.
Adicionar uma identidade atribuída ao sistema
- Navegue até a página do seu aplicativo no portal do Azure e role para baixo até o grupo Configurações.
- Selecione a Identidade.
- Na guia Sistema atribuído, alterne Status para Ativado e selecione Salvar.
Execute o comando para criar uma identidade atribuída ao az webapp identity assign
sistema:
az webapp identity assign --name <appName> --resource-group <groupName>
Adicionar uma identidade atribuída pelo usuário
Para adicionar uma identidade atribuída pelo usuário ao seu aplicativo, crie a identidade e adicione seu identificador de recurso à configuração do aplicativo.
Crie um recurso de identidade gerenciado atribuído pelo usuário seguindo estas instruções.
No painel de navegação esquerdo da página da sua aplicação, desloque-se para baixo até ao grupo Definições .
Selecione a Identidade.
Selecione Adicionar atribuído ao> usuário.
Localize a identidade que criou anteriormente, selecione-a e, em seguida, selecione Adicionar.
Importante
Depois de selecionar Adicionar, o aplicativo é reiniciado.
Crie uma identidade atribuída pelo usuário:
az identity create --resource-group <groupName> --name <identityName>
Atribua a identidade ao seu aplicativo:
az webapp identity assign --resource-group <groupName> --name <appName> --identities <identityId>
Adicionar uma função do Azure à sua identidade gerenciada
- No Portal do Azure, navegue até o escopo ao qual você deseja conceder acesso ao banco de dados vetorial. O escopo pode ser um grupo de Gerenciamento, Assinatura, Grupo de Recursos ou um recurso específico do Azure.
- No painel de navegação esquerdo, selecione Controle de acesso (IAM).
- Selecione Adicionar e, em seguida, selecione Adicionar atribuição de função.
- Na guia Função, selecione a função apropriada que concede acesso de leitura ao seu banco de dados vetorial.
- Na guia Membros, selecione a identidade gerenciada.
- No separador Rever + atribuir, selecione Rever + atribuir para atribuir a função.
Âmbito do recurso
az role assignment create --assignee "<managedIdentityObjectID>" \
--role "<myVectorDbReaderRole>" \
--scope "/subscriptions/<subscriptionId>/resourcegroups/<resourceGroupName>/providers/<providerName>/<resourceType>/<resourceSubType>/<resourceName>"
Âmbito do grupo de recursos
az role assignment create --assignee "<managedIdentityObjectID>" \
--role "<myVectorDbReaderRole>" \
--scope "/subscriptions/<subscriptionId>/resourcegroups/<resourceGroupName>"
Âmbito da subscrição
az role assignment create --assignee "<managedIdentityObjectID>" \
--role "<myVectorDbReaderRole>" \
--scope "/subscriptions/<subscriptionId>"
Âmbito do grupo de gestão
az role assignment create --assignee "<managedIdentityObjectID>" \
--role "<myVectorDbReaderRole>" \
--scope "/providers/Microsoft.Management/managementGroups/<managementGroupName>"
Implementar autenticação baseada em token com o banco de dados vetorial
Os exemplos de código a seguir exigem essas bibliotecas adicionais:
Inicialize um
DefaultAzureCredential
objeto para pegar a identidade gerenciada do seu aplicativo:// 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". } );
Inicialize um
IMemoryStore
objeto para seu banco de dados vetorial e use-o para criar umISemanticTextMemory
:// 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() .WithOpenAITextEmbeddingGeneration(embeddingModel, openAiEndpoint) .WithMemoryStore(memoryStore) .Build();
Crie um
Kernel
objeto e, em seguida, importe-oISemanticTextMemory
usando oTextMemoryPlugin
:// 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));
Use o objeto para invocar um prompt que inclua a
Kernel
recuperação de memória:// 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}");
Usar o Cofre da Chave para armazenar segredos de conexão
Se um banco de dados vetorial não oferecer suporte à autenticação do Microsoft Entra, você poderá usar um Cofre da Chave para armazenar seus segredos de conexão e recuperá-los com seu aplicativo do Serviço de Aplicativo. Usando um Cofre de Chaves para armazenar seus segredos de conexão, você pode compartilhá-los com vários aplicativos e controlar o acesso a segredos individuais por aplicativo.
Antes de seguir essas etapas, recupere uma cadeia de conexão para seu banco de dados vetorial. Por exemplo, consulte Usar o Cache do Azure para Redis com um aplicativo Web ASP.NET Core.
Adicionar uma cadeia de conexão ao Cofre da Chave
Importante
Antes de seguir estas etapas, verifique se você criou um Cofre da Chave usando o Portal do Azure.
- Navegue até o cofre da chave no Portal do Azure.
- Na navegação à esquerda do Cofre da Chave, selecione Objetos e, em seguida, selecione Segredos.
- Selecione + Gerar/Importar.
- Na tela Criar um segredo, escolha os seguintes valores:
- Opções de upload:
Manual
. - Nome: escreva um nome para o segredo. O nome do segredo tem de ser exclusivo dentro de um Key Vault.
- Valor: A cadeia de conexão para seu banco de dados vetorial.
- Deixe as outras opções com os valores predefinidos. Selecione Criar.
- Opções de upload:
- Quando você receber a mensagem de que o segredo foi criado com êxito, ele estará pronto para ser usado em seu aplicativo.
Importante
Antes de seguir estas etapas, verifique se você criou um Cofre da Chave usando a CLI do Azure.
Conceda permissões à sua conta de utilizador para o seu cofre de chaves através do Controlo de Acesso Baseado em Funções (RBAC), atribua uma função utilizando o comando
az role assignment create
da CLI do Azure :az role assignment create \ --role "Key Vault Secrets User" \ --assignee "<yourEmailAddress>" \ --scope "/subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/providers/Microsoft.KeyVault/vaults/<keyVaultName>"
Adicione a cadeia de conexão ao Cofre da Chave usando o comando
az keyvault secret set
da CLI do Azure :az keyvault secret set \ --vault-name "<keyVaultName>" \ --name "<secretName>" \ --value "<connectionString>"
Conceda ao seu Serviço de Aplicativo acesso ao Cofre da Chave
- Atribua uma identidade gerenciada ao seu Serviço de Aplicativo.
- Adicione as
Key Vault Secrets User
funções eKey Vault Reader
à sua identidade gerenciada.
Implementar a recuperação da cadeia de conexão do Cofre da Chave
Para usar os seguintes exemplos de código, você precisa destas bibliotecas adicionais:
Azure.Identity
Pacote NuGetAzure.Extensions.AspNetCore.Configuration.Secrets
Pacote NuGetMicrosoft.Extensions.Configuration
Pacote NuGet
Esses exemplos de código usam um banco de dados Redis, mas você pode aplicá-los a qualquer banco de dados vetorial que ofereça suporte a cadeias de conexão.
Inicialize um
DefaultAzureCredential
objeto para pegar a identidade gerenciada do seu aplicativo:// 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". } );
Adicione o Cofre da Chave ao criar sua configuração, isso mapeará seus segredos do Cofre da Chave para o
IConfigurationRoot
objeto:// User secrets let you provide connection strings when testing locally // For more info see: https://learn.microsoft.com/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"]!;
Use sua cadeia de conexão de banco de dados vetorial do Cofre da Chave para inicializar um
IMemoryStore
objeto e, em seguida, use-a para criar umISemanticTextMemory
:// 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() .WithOpenAITextEmbeddingGeneration(embeddingModel, openAiEndpoint) .WithMemoryStore(memoryStore) .Build();
Crie um
Kernel
objeto e, em seguida, importe-oISemanticTextMemory
usando oTextMemoryPlugin
:// 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));
Use o objeto para invocar um prompt que inclua a
Kernel
recuperação de memória:// 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}");
Usar as configurações do aplicativo para armazenar segredos de conexão
Se um banco de dados vetorial não oferecer suporte à autenticação do Microsoft Entra, você poderá usar as configurações do aplicativo do Serviço de Aplicativo para armazenar seus segredos de conexão. Usando as configurações do aplicativo, você pode armazenar seus segredos de conexão sem provisionar recursos adicionais do Azure.
Antes de seguir essas etapas, recupere uma cadeia de conexão para seu banco de dados vetorial. Por exemplo, consulte Usar o Cache do Azure para Redis no .NET Framework.
Adicionar uma cadeia de conexão às configurações do aplicativo
- Navegue até a página do seu aplicativo no Portal do Azure.
- No menu esquerdo do aplicativo, selecione Configurações>do aplicativo.
- Por padrão, os valores para as configurações do aplicativo ficam ocultos no portal para segurança.
- Para ver um valor oculto de uma configuração de aplicativo, selecione seu campo Valor.
- Selecione Nova configuração de conexão.
- Na tela Adicionar/Editar cadeia de conexão, escolha os seguintes valores:
- Nome: digite um nome para a configuração. O nome da configuração deve ser exclusivo.
- Valor: A cadeia de conexão para seu banco de dados vetorial.
- Tipo: O tipo de conexão,
Custom
se nenhuma outra se aplicar. - Deixe as outras opções com os valores predefinidos. Selecione OK.
- Selecione Salvar novamente na página Configuração.
Adicione ou edite uma configuração de aplicativo com o comando az webapp config connection-string set
CLI do Azure :
az webapp config connection-string set \
--name "<appName>" \
--resource-group "<groupName>" \
--connection-string-type "<connectionType>" \
--settings <connectionName>='<connectionString>'
Implementar a recuperação da cadeia de conexão a partir das configurações do aplicativo
Para usar os seguintes exemplos de código, você precisa destas bibliotecas adicionais:
Microsoft.Extensions.Configuration
Pacote NuGetMicrosoft.Extensions.Configuration.EnvironmentVariables
Pacote NuGet
Esses exemplos de código usam um banco de dados Redis, mas você pode aplicá-los a qualquer banco de dados vetorial que ofereça suporte a cadeias de conexão.
Adicione variáveis de ambiente ao criar sua configuração, isso mapeará suas cadeias de conexão para o
IConfigurationRoot
objeto:// 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")!;
Use sua cadeia de conexão de banco de dados vetorial das configurações do aplicativo para inicializar um
IMemoryStore
objeto e, em seguida, use-a para criar umISemanticTextMemory
:// 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() .WithOpenAITextEmbeddingGeneration(embeddingModel, openAiEndpoint) .WithMemoryStore(memoryStore) .Build();
Crie um
Kernel
objeto e, em seguida, importe-oISemanticTextMemory
usando oTextMemoryPlugin
:// 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));
Use o objeto para invocar um prompt que inclua a
Kernel
recuperação de memória:// 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}");
Conteúdos relacionados
- [Use o Redis para armazenamento de memória com o SDK do kernel semântico]
- Como usar identidades gerenciadas para o Serviço de Aplicativo e o Azure Functions
- Etapas para atribuir uma função do Azure