Autenticación y autorización de App Service en una base de datos vectorial
En este artículo se muestra cómo administrar la conexión entre la aplicación .NET de App Service y una solución de base de datos vectorial. Abarca el uso de identidades administradas de Microsoft Entra para los servicios admitidos y el almacenamiento seguro de cadenas de conexión para otros usuarios.
Al agregar una base de datos de vectores a su aplicación, puede habilitar [memorias semánticas o almacenes de vectores] (almacenes de vectores) para su IA. El SDK de Semantic Kernel para .NET permite implementar fácilmente el almacenamiento de memoria y la recuperación mediante la solución de base de datos vectorial preferida.
Requisitos previos
- Una cuenta de Azure con una suscripción activa. Cree una cuenta gratuita.
- .NET SDK
- Paquete NuGet de
Microsoft.SemanticKernel
- Paquete NuGet de
Microsoft.SemanticKernel.Plugins.Memory
- Creación e implementación de una aplicación .NET en App Service
- Creación e implementación de una solución de base de datos vectorial
Uso de la identidad administrada de Microsoft Entra para la autenticación
Si un servicio de base de datos vectorial admite la autenticación de Microsoft Entra, puede usar una identidad administrada con App Service para acceder de forma segura a la base de datos vectorial sin tener que aprovisionar ni girar manualmente ningún secreto. Para obtener una lista de los servicios de Azure que admiten la autenticación de Microsoft Entra, consulte Servicios de Azure que admiten la autenticación de Microsoft Entra.
Adición de una identidad administrada a App Service
La aplicación puede tener dos tipos de identidades:
- Una identidad asignada por el sistema está asociada a la aplicación y se elimina si se elimina la aplicación. Una aplicación solo puede tener una identidad asignada por el sistema.
- Una identidad asignada por el usuario es un recurso de Azure independiente que puede asignarse a la aplicación. Una aplicación puede tener varias identidades asignadas por el usuario.
Adición de una identidad asignada por el sistema
- Vaya a la página de la aplicación en Azure Portal y desplácese hacia abajo hasta el grupo Configuración.
- Seleccione Identidad.
- En la pestaña Asignado por el sistema, cambie Estado a Activado y, a continuación, seleccione Guardar.
Ejecute el comando az webapp identity assign
para crear una identidad asignada por el sistema:
az webapp identity assign --name <appName> --resource-group <groupName>
Adición de una identidad asignada por el usuario
Para agregar una identidad asignada por el usuario a la aplicación, cree la identidad y, después, agregue su identificador de recurso a la configuración de la aplicación.
Cree un recurso de identidad administrada asignada por el usuario siguiendo estas instrucciones.
En el panel de navegación izquierdo de la página de la aplicación, desplácese hacia abajo hasta el grupo Configuración.
Seleccione Identidad.
Seleccione Asignado por el usuario>Agregar.
Busque la identidad que creó anteriormente, selecciónela y, a continuación, elija Agregar.
Importante
Después de seleccionar Agregar, la aplicación se reinicia.
Cree una identidad asignada por el usuario:
az identity create --resource-group <groupName> --name <identityName>
Asigne la identidad a la aplicación:
az webapp identity assign --resource-group <groupName> --name <appName> --identities <identityId>
Adición de un rol de usuario de Azure OpenAI a la identidad administrada
- En Azure Portal, vaya al ámbito al que desea conceder acceso de base de datos. El ámbito puede ser un grupo de administración, una suscripción, un grupo de recursos o un recurso específico de Azure.
- En el panel de navegación de la izquierda, seleccione Control de acceso (IAM).
- Seleccione Agregar y, luego, Agregar asignación de roles.
- En la pestaña Rol, seleccione el rol adecuado que concede acceso de lectura a la base de datos vectorial.
- En la pestaña Miembros, seleccione la identidad administrada.
- En la pestaña Revisión y asignación, seleccione Revisión y asignación para asignar el rol.
Ámbito del recurso
az role assignment create --assignee "<managedIdentityObjectID>" \
--role "<myVectorDbReaderRole>" \
--scope "/subscriptions/<subscriptionId>/resourcegroups/<resourceGroupName>/providers/<providerName>/<resourceType>/<resourceSubType>/<resourceName>"
Ámbito del grupo de recursos
az role assignment create --assignee "<managedIdentityObjectID>" \
--role "<myVectorDbReaderRole>" \
--scope "/subscriptions/<subscriptionId>/resourcegroups/<resourceGroupName>"
Ámbito de la suscripción
az role assignment create --assignee "<managedIdentityObjectID>" \
--role "<myVectorDbReaderRole>" \
--scope "/subscriptions/<subscriptionId>"
Ámbito del grupo de administración
az role assignment create --assignee "<managedIdentityObjectID>" \
--role "<myVectorDbReaderRole>" \
--scope "/providers/Microsoft.Management/managementGroups/<managementGroupName>"
Implementación de la autenticación basada en tokens con la base de datos vectorial
Los ejemplos de código siguientes requieren estas bibliotecas adicionales:
Inicialice un objeto
DefaultAzureCredential
para recoger la identidad administrada de la aplicación:// 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". } );
Inicialice un objeto
IMemoryStore
para la base de datos vectorial y, después, úselo para crear unISemanticTextMemory
:// 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();
Cree un objeto
Kernel
y, a continuación, importe el objetoISemanticTextMemory
medianteTextMemoryPlugin
:// 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 el objeto
Kernel
para invocar un símbolo del sistema que incluya la recuperación de memoria:// 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}");
Uso de Key Vault para almacenar secretos de conexión
Si una base de datos vectorial no admite la autenticación de Microsoft Entra, puede usar una instancia de Key Vault para almacenar los secretos de conexión y recuperarlos con la aplicación de App Service. Mediante el uso de Key Vault para almacenar los secretos de conexión, puede compartirlos con varias aplicaciones y controlar el acceso a secretos individuales por aplicación.
Antes de seguir estos pasos, recupere una cadena de conexión para la base de datos vectorial. Por ejemplo, consulte Uso de Azure Cache for Redis con una aplicación web de ASP.NET Core.
Adición de una cadena de conexión a Key Vault
Importante
Antes de seguir estos pasos, asegúrese de que ha creado una instancia de Key Vault mediante Azure Portal.
- Vaya al almacén de claves en Azure Portal.
- En el panel de navegación izquierdo de Key Vault, seleccione Objetos y, a continuación, seleccione Secretos.
- Seleccione + Generar/Importar.
- En la pantalla Crear un secreto, elija los siguientes valores:
- Opciones de carga:
Manual
. - Name: Escriba un nombre para el secreto. El nombre del secreto debe ser único en Key Vault.
- Valor: la cadena de conexión de la base de datos vectorial.
- Deje las restantes opciones con sus valores predeterminados. Seleccione Crear.
- Opciones de carga:
- Cuando reciba el mensaje que indica que el secreto se ha creado correctamente, está listo para usarse en la aplicación.
Importante
Antes de seguir estos pasos, asegúrese de que ha creado una instancia de Key Vault mediante la CLI de Azure.
Conceda permisos de cuenta de usuario al almacén de claves a través del control de acceso basado en rol (RBAC), asigne un rol mediante el comando
az role assignment create
de la CLI de Azure:az role assignment create \ --role "Key Vault Secrets User" \ --assignee "<yourEmailAddress>" \ --scope "/subscriptions/<subscriptionId>/resourceGroups/<resourceGroupName>/providers/Microsoft.KeyVault/vaults/<keyVaultName>"
Agregue la cadena de conexión a Key Vault mediante el comando
az keyvault secret set
de la CLI de Azure:az keyvault secret set \ --vault-name "<keyVaultName>" \ --name "<secretName>" \ --value "<connectionString>"
Concesión del acceso de App Service a Key Vault
- Asigne una identidad administrada a App Service.
- Agregue los roles
Key Vault Secrets User
yKey Vault Reader
a la identidad administrada.
Implementación de la recuperación de cadenas de conexión desde Key Vault
Para usar los ejemplos de código siguientes, necesita estas bibliotecas adicionales:
- Paquete NuGet de
Azure.Identity
- Paquete NuGet de
Azure.Extensions.AspNetCore.Configuration.Secrets
- Paquete NuGet de
Microsoft.Extensions.Configuration
Estos ejemplos de código usan una base de datos de Redis, pero puede aplicarlas a cualquier base de datos vectorial que admita cadenas de conexión.
Inicialice un objeto
DefaultAzureCredential
para recoger la identidad administrada de la aplicación:// 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". } );
Agregue Key Vault al crear la configuración; esto asignará los secretos de Key Vault al objeto
IConfigurationRoot
:// 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 la cadena de conexión de la base de datos vectorial de Key Vault para inicializar un objeto
IMemoryStore
y después úsela para crear unISemanticTextMemory
:// 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();
Cree un objeto
Kernel
y, a continuación, importe el objetoISemanticTextMemory
medianteTextMemoryPlugin
:// 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 el objeto
Kernel
para invocar un símbolo del sistema que incluya la recuperación de memoria:// 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}");
Uso de la configuración de la aplicación para almacenar secretos de conexión
Si una base de datos vectorial no admite la autenticación de Microsoft Entra, puede usar la configuración de la aplicación de App Service para almacenar los secretos de conexión. Mediante la configuración de la aplicación, puede almacenar los secretos de conexión sin aprovisionar recursos adicionales de Azure.
Antes de seguir estos pasos, recupere una cadena de conexión para la base de datos vectorial. Por ejemplo, consulte Uso de Azure Cache for Redis en .NET Framework.
Adición de una cadena de conexión a la configuración de la aplicación
- Vaya a la página de la aplicación en Azure Portal.
- En el menú izquierdo de la aplicación, haga clic en Configuración>Configuración de la aplicación.
- De forma predeterminada, los valores de la configuración de la aplicación están ocultos en el portal por seguridad.
- Para ver un valor oculto de una configuración de aplicación, seleccione su campo Valor.
- Seleccione Nuevo ajuste de conexión.
- En la pantalla Agregar o editar cadena de conexión, elija los valores siguientes:
- Nombre: escriba un nombre para la configuración. El nombre de la configuración HTTP debe ser único
- Valor: la cadena de conexión de la base de datos vectorial.
- Tipo: el tipo de conexión,
Custom
si no se aplica ninguna otra. - Deje las restantes opciones con sus valores predeterminados. Seleccione Aceptar.
- Seleccione Guardar de nuevo en la página Configuración.
Agregue o edite una configuración de aplicación con el comando az webapp config connection-string set
de la CLI de Azure:
az webapp config connection-string set \
--name "<appName>" \
--resource-group "<groupName>" \
--connection-string-type "<connectionType>" \
--settings <connectionName>='<connectionString>'
Implementación de la recuperación de cadenas de conexión desde la configuración de la aplicación
Para usar los ejemplos de código siguientes, necesita estas bibliotecas adicionales:
- Paquete NuGet de
Microsoft.Extensions.Configuration
- Paquete NuGet de
Microsoft.Extensions.Configuration.EnvironmentVariables
Estos ejemplos de código usan una base de datos de Redis, pero puede aplicarlas a cualquier base de datos vectorial que admita cadenas de conexión.
Agregue variables de entorno al crear la configuración; esto asignará las cadenas de conexión al objeto
IConfigurationRoot
:// 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 la cadena de conexión de la base de datos vectorial de la configuración de aplicación para inicializar un objeto
IMemoryStore
y después úsela para crear unISemanticTextMemory
:// 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();
Cree un objeto
Kernel
y, a continuación, importe el objetoISemanticTextMemory
medianteTextMemoryPlugin
:// 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 el objeto
Kernel
para invocar un símbolo del sistema que incluya la recuperación de memoria:// 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}");
Contenido relacionado
- [Uso de Redis para el almacenamiento en memoria con el SDK de Semantic Kernel]
- Cómo usar identidades administradas para App Service y Azure Functions
- Pasos para asignar un rol de Azure