Compartir a través de


Almacenamiento seguro de secretos de aplicación en el desarrollo en ASP.NET Core

Nota:

Esta no es la versión más reciente de este artículo. Para la versión actual, consulta la versión .NET 8 de este artículo.

Advertencia

Esta versión de ASP.NET Core ya no se admite. Para obtener más información, consulta la Directiva de soporte técnico de .NET y .NET Core. Para la versión actual, consulta la versión .NET 8 de este artículo.

Importante

Esta información hace referencia a un producto en versión preliminar, el cual puede sufrir importantes modificaciones antes de que se publique la versión comercial. Microsoft no proporciona ninguna garantía, expresa o implícita, con respecto a la información proporcionada aquí.

Para la versión actual, consulta la versión .NET 8 de este artículo.

Por Rick Anderson y Kirk Larkin

Vea o descargue el código de ejemplo (cómo descargarlo)

En este artículo se explica cómo administrar datos confidenciales para una aplicación ASP.NET Core en una máquina de desarrollo. Nunca almacene contraseñas u otros datos confidenciales en archivos de configuración o código fuente. Los secretos de producción no se deben usar para desarrollo o prueba. Los secretos no se deben implementar con la aplicación. Se debe acceder a los secretos de producción a través de un medio controlado, como Azure Key Vault. Los secretos de prueba y producción de Azure se pueden almacenar y proteger con el proveedor de configuración de Azure Key Vault.

Para obtener más información sobre la autenticación para aplicaciones de prueba y producción implementadas, consulta Flujos de autenticación seguros.

Para usar los secretos de usuario en una aplicación de consola de .NET, consulte este problema de GitHub.

Variables de entorno

Las variables de entorno se usan para evitar el almacenamiento de secretos de aplicación en el código o en archivos de configuración local. Las variables de entorno invalidan los valores de configuración de todos los orígenes de configuración especificados anteriormente.

Considere una aplicación web ASP.NET Core en la que está habilitada la seguridad delas cuentas de usuario individuales. En el archivo del proyecto appsettings.json se incluye una cadena de conexión de base de datos predeterminada con la clave DefaultConnection. La cadena de conexión predeterminada es para LocalDB, que se ejecuta en modo de usuario y no requiere una contraseña. Durante la implementación de la aplicación, el valor de clave DefaultConnection se puede invalidar con el valor de una variable de entorno. La variable de entorno puede almacenar la cadena de conexión completa con credenciales confidenciales.

Advertencia

Las variables de entorno se almacenan generalmente en texto sin formato y sin cifrar. Si la máquina o el proceso están en peligro, las partes que no son de confianza pueden acceder a las variables de entorno. Es posible que se requieran medidas adicionales para evitar la divulgación de secretos de usuario.

El separador : no funciona con claves jerárquicas de variables de entorno en todas las plataformas. Por ejemplo, el separador : no es compatible con Bash. El carácter de subrayado doble, __, tiene las siguientes características:

  • Es compatible con todas las plataformas.
  • Se reemplaza automáticamente por dos puntos, :.

Administrador de secretos

La herramienta Secret Manager almacena datos confidenciales durante el desarrollo de aplicaciones. En este contexto, un fragmento de datos confidenciales es un secreto de aplicación. Los secretos de aplicación se almacenan en una ubicación independiente del árbol del proyecto. Los secretos de la aplicación están asociados a un proyecto específico o se comparten entre varios proyectos. Los secretos de la aplicación no se comprueban en el control de código fuente.

Advertencia

La herramienta Secret Manager no cifra los secretos almacenados y no debe tratarse como un almacén de confianza. Tiene solo fines de desarrollo. Las claves y los valores se almacenan en un archivo de configuración JSON en el directorio del perfil de usuario.

Funcionamiento de la herramienta Secret Manager

La herramienta Secret Manager oculta los detalles de implementación, como dónde y cómo se almacenan los valores. Puede usar la herramienta sin conocer estos detalles de implementación. Los valores se almacenan en un archivo JSON en la carpeta de perfil de usuario de la máquina local:

Ruta del sistema de archivos:

%APPDATA%\Microsoft\UserSecrets\<user_secrets_id>\secrets.json

En las rutas de acceso de archivo anteriores, reemplace <user_secrets_id> por el valor UserSecretsId especificado en el archivo de proyecto.

No escriba un código que dependa de la ubicación o el formato de los datos guardados con la herramienta Administrador de secretos. Estos detalles de implementación pueden cambiar. Por ejemplo, los valores secretos no están cifrados.

Habilitación del almacenamiento de secretos

La herramienta Secret Manager funciona con las opciones de configuración específicas del proyecto almacenadas en el perfil de usuario.

Uso de la CLI

La herramienta Administrador de secretos incluye un comando init. Para usar los secretos de usuario, ejecute los siguientes comandos en el directorio del proyecto:

dotnet user-secrets init

El comando anterior agrega un elemento UserSecretsId con un PropertyGroup del archivo del proyecto. De forma predeterminada, el texto interno de UserSecretsId es un GUID. El texto interno es arbitrario, pero es único para el proyecto.

<PropertyGroup>
  <TargetFramework>netcoreapp3.1</TargetFramework>
  <UserSecretsId>79a3edd0-2092-40a2-a04d-dcb46d5ca9ed</UserSecretsId>
</PropertyGroup>

Usar Visual Studio

En Visual Studio, haga clic con el botón derecho en el proyecto en el Explorador de soluciones y seleccione Administrar secretos de usuario en el menú contextual. Este gesto agrega un elemento UserSecretsId, rellenado con un GUID, al archivo del proyecto.

Si GenerateAssemblyInfo es false

Si la generación de atributos de información de ensamblado está deshabilitada, agregue manualmente el UserSecretsIdAttribute en AssemblyInfo.cs. Por ejemplo:

[assembly: UserSecretsId("your_user_secrets_id")]

Al agregar manualmente el atributo UserSecretsId a AssemblyInfo.cs, el valor de UserSecretsId debe coincidir con el valor del archivo del proyecto.

Establecimiento de un secreto

Defina un secreto de aplicación que consta de una clave y su valor. El secreto está asociado al valor UserSecretsId del proyecto. Por ejemplo, ejecute el siguiente comando desde el directorio en el que existe el archivo del proyecto:

dotnet user-secrets set "Movies:ServiceApiKey" "12345"

En el ejemplo anterior, los dos puntos indican que Movies es un literal de objeto con una propiedad ServiceApiKey.

La herramienta Secret Manager también se puede usar desde otros directorios. Use la opción --project para proporcionar la ruta de acceso del sistema de archivos en la que existe el archivo del proyecto. Por ejemplo:

dotnet user-secrets set "Movies:ServiceApiKey" "12345" --project "C:\apps\WebApp1\src\WebApp1"

Aplanamiento de estructura JSON en Visual Studio

El gesto Administrar secretos de usuario de Visual Studio abre un archivo secrets.json en el editor de texto. Reemplace el contenido de secrets.json por los pares clave-valor que se van a almacenar. Por ejemplo:

{
  "Movies": {
    "ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
    "ServiceApiKey": "12345"
  }
}

La estructura JSON se aplana después de modificarse a través de dotnet user-secrets remove o dotnet user-secrets set. Por ejemplo, ejecutar dotnet user-secrets remove "Movies:ConnectionString" contrae el literal de objeto Movies. El archivo modificado es similar al siguiente JSON:

{
  "Movies:ServiceApiKey": "12345"
}

Establecimiento de varios secretos

Un lote de secretos se puede establecer mediante la canalización de JSON al comando set. En el ejemplo siguiente, el contenido del archivo input.json se canaliza al comando set.

Abra un shell de comandos y escriba el siguiente comando:

type .\input.json | dotnet user-secrets set

Acceder a un secreto

Para acceder a un secreto, complete los pasos siguientes:

  1. Registre el origen de configuración de los secretos de usuario
  2. Lea el secreto a través de la API de configuración

Registre el origen de configuración de secretos de usuario

El proveedor de configuración de secretos de usuario registra el origen de configuración adecuado con la API de configuración de .NET.

Las aplicaciones web de ASP.NET Core creadas con dotnet new o con Visual Studio generan el código siguiente:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

WebApplication.CreateBuilder inicializa una nueva instancia de la clase WebApplicationBuilder con valores predeterminados preconfigurados. El inicializado WebApplicationBuilder (builder) proporciona la configuración predeterminada y llama a AddUserSecrets cuando EnvironmentName es Development:

Lea el secreto a través de la API de configuración

Tenga en cuenta los ejemplos siguientes de lectura de la clave Movies:ServiceApiKey:

Archivo program.cs:

var builder = WebApplication.CreateBuilder(args);
var movieApiKey = builder.Configuration["Movies:ServiceApiKey"];

var app = builder.Build();

app.MapGet("/", () => movieApiKey);

app.Run();

Razor Modelo de página de páginas:

public class IndexModel : PageModel
{
    private readonly IConfiguration _config;

    public IndexModel(IConfiguration config)
    {
        _config = config;
    }

    public void OnGet()
    {
        var moviesApiKey = _config["Movies:ServiceApiKey"];

        // call Movies service with the API key
    }
}

Para más información, consulte Configuración en ASP.NET Core.

Asignación de secretos a un POCO

Asignar un literal de objeto completo a un POCO (una clase .NET simple con propiedades) es útil para agregar propiedades relacionadas.

Supongamos que el archivosecrets.json de la aplicación contiene los dos secretos siguientes:

{
  "Movies:ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
  "Movies:ServiceApiKey": "12345"
}

Para asignar los secretos anteriores a un POCO, use la característica de enlace de grafos de objetos de la API de configuración de .NET. El código siguiente se enlaza a un POCO personalizado MovieSettings y accede al valor de propiedad ServiceApiKey:

var moviesConfig = 
    Configuration.GetSection("Movies").Get<MovieSettings>();
_moviesApiKey = moviesConfig.ServiceApiKey;

Los secretos Movies:ConnectionString y Movies:ServiceApiKey son asignados a las respectivas propiedades en MovieSettings:

public class MovieSettings
{
    public string ConnectionString { get; set; }

    public string ServiceApiKey { get; set; }
}

Reemplazo de cadenas con secretos

El almacenamiento de contraseñas en texto sin formato no es seguro. Nunca almacene secretos en un archivo de configuración, como appsettings.json, que puede que se proteja en un repositorio de código fuente.

Por ejemplo, una base de datos cadena de conexión almacenada en appsettings.json no debe incluir una contraseña. En su lugar, almacene la contraseña como un secreto e incluya la contraseña en el cadena de conexión en tiempo de ejecución. Por ejemplo:

dotnet user-secrets set "DbPassword" "`<secret value>`"

Reemplace el <secret value> marcador de posición del ejemplo anterior por el valor de contraseña. Establezca el valor del secreto en la propiedad de Password un SqlConnectionStringBuilder objeto para incluirlo como valor de contraseña en el cadena de conexión:

using System.Data.SqlClient;

var builder = WebApplication.CreateBuilder(args);

var conStrBuilder = new SqlConnectionStringBuilder(
        builder.Configuration.GetConnectionString("Movies"));
conStrBuilder.Password = builder.Configuration["DbPassword"];
var connection = conStrBuilder.ConnectionString;

var app = builder.Build();

app.MapGet("/", () => connection);

app.Run();

Enumera los secretos

Supongamos que el archivosecrets.json de la aplicación contiene los dos secretos siguientes:

{
  "Movies:ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
  "Movies:ServiceApiKey": "12345"
}

Ejecute el siguiente comando desde el directorio en el que existe el archivo del proyecto:

dotnet user-secrets list

Se mostrará la siguiente salida:

Movies:ConnectionString = Server=(localdb)\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true
Movies:ServiceApiKey = 12345

En el ejemplo anterior, un signo de dos puntos en los nombres de las claves denota la jerarquía de objetos dentro de secrets.json.

Eliminación de un único secreto

Supongamos que el archivosecrets.json de la aplicación contiene los dos secretos siguientes:

{
  "Movies:ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
  "Movies:ServiceApiKey": "12345"
}

Ejecute el siguiente comando desde el directorio en el que existe el archivo del proyecto:

dotnet user-secrets remove "Movies:ConnectionString"

El archivo de la aplicación secrets.json se modificó para quitar el par clave-valor asociado a la clave Movies:ConnectionString:

{
  "Movies": {
    "ServiceApiKey": "12345"
  }
}

dotnet user-secrets list muestra el siguiente mensaje de advertencia:

Movies:ServiceApiKey = 12345

Eliminación de todos los secretos

Supongamos que el archivosecrets.json de la aplicación contiene los dos secretos siguientes:

{
  "Movies:ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
  "Movies:ServiceApiKey": "12345"
}

Ejecute el siguiente comando desde el directorio en el que existe el archivo del proyecto:

dotnet user-secrets clear

Todos los secretos de usuario de la aplicación se han eliminado del archivo secrets.json:

{}

Al ejecutar dotnet user-secrets list se muestra el siguiente mensaje de advertencia:

No secrets configured for this application.

Administración de secretos de usuario con Visual Studio

Para administrar secretos de usuario en Visual Studio, haga clic con el botón derecho en el proyecto en el explorador de soluciones y seleccione Administrar secretos de usuario:

Visual Studio mostrando la adiministración de los secretos de usuario

Migración de secretos de usuario de ASP.NET Framework a ASP.NET Core

Consulte este problema de GitHub.

Secretos de usuario en aplicaciones que no son web

Los proyectos que tienen como destino Microsoft.NET.Sdk.Web incluyen automáticamente compatibilidad con secretos de usuario. Para los proyectos que tienen como destino Microsoft.NET.Sdk, como las aplicaciones de consola, instale explícitamente los paquetes NuGet de extensión de configuración y secretos de usuario.

Mediante PowerShell:

Install-Package Microsoft.Extensions.Configuration
Install-Package Microsoft.Extensions.Configuration.UserSecrets

Mediante la CLI de .NET:

dotnet add package Microsoft.Extensions.Configuration
dotnet add package Microsoft.Extensions.Configuration.UserSecrets

Una vez instalados los paquetes, inicialice el proyecto y establezca secretos de la misma manera que para una aplicación web. En el siguiente ejemplo se muestra una aplicación de consola que recupera el valor de un secreto que se estableció con la clave "AppSecret":

using Microsoft.Extensions.Configuration;

namespace ConsoleApp;

class Program
{
    static void Main(string[] args)
    {
        IConfigurationRoot config = new ConfigurationBuilder()
            .AddUserSecrets<Program>()
            .Build();

        Console.WriteLine(config["AppSecret"]);
    }
}

Recursos adicionales

Por Rick Anderson, Kirk Larkin, Daniel Roth y Scott Addie

Vea o descargue el código de ejemplo (cómo descargarlo)

En este artículo se explica cómo administrar datos confidenciales para una aplicación ASP.NET Core en una máquina de desarrollo. Nunca almacene contraseñas u otros datos confidenciales en archivos de configuración o código fuente. Los secretos de producción no se deben usar para desarrollo o prueba. Los secretos no se deben implementar con la aplicación. Se debe acceder a los secretos de producción a través de un medio controlado, como Azure Key Vault. Los secretos de prueba y producción de Azure se pueden almacenar y proteger con el proveedor de configuración de Azure Key Vault.

Para más información sobre la autenticación para entornos de prueba y producción, consulte Flujos de autenticación seguros.

Variables de entorno

Las variables de entorno se usan para evitar el almacenamiento de secretos de aplicación en el código o en archivos de configuración local. Las variables de entorno invalidan los valores de configuración de todos los orígenes de configuración especificados anteriormente.

Considere una aplicación web ASP.NET Core en la que está habilitada la seguridad delas cuentas de usuario individuales. En el archivo del proyecto appsettings.json se incluye una cadena de conexión de base de datos predeterminada con la clave DefaultConnection. La cadena de conexión predeterminada es para LocalDB, que se ejecuta en modo de usuario y no requiere una contraseña. Durante la implementación de la aplicación, el valor de clave DefaultConnection se puede invalidar con el valor de una variable de entorno. La variable de entorno puede almacenar la cadena de conexión completa con credenciales confidenciales.

Advertencia

Las variables de entorno se almacenan generalmente en texto sin formato y sin cifrar. Si la máquina o el proceso están en peligro, las partes que no son de confianza pueden acceder a las variables de entorno. Es posible que se requieran medidas adicionales para evitar la divulgación de secretos de usuario.

El separador : no funciona con claves jerárquicas de variables de entorno en todas las plataformas. Por ejemplo, el separador : no es compatible con Bash. El carácter de subrayado doble, __, tiene las siguientes características:

  • Es compatible con todas las plataformas.
  • Se reemplaza automáticamente por dos puntos, :.

Administrador de secretos

La herramienta Secret Manager almacena datos confidenciales durante el desarrollo de aplicaciones. En este contexto, un fragmento de datos confidenciales es un secreto de aplicación. Los secretos de aplicación se almacenan en una ubicación independiente del árbol del proyecto. Los secretos de la aplicación están asociados a un proyecto específico o se comparten entre varios proyectos. Los secretos de la aplicación no se comprueban en el control de código fuente.

Advertencia

La herramienta Secret Manager no cifra los secretos almacenados y no debe tratarse como un almacén de confianza. Tiene solo fines de desarrollo. Las claves y los valores se almacenan en un archivo de configuración JSON en el directorio del perfil de usuario.

Funcionamiento de la herramienta Secret Manager

La herramienta Secret Manager oculta los detalles de implementación, como dónde y cómo se almacenan los valores. Puede usar la herramienta sin conocer estos detalles de implementación. Los valores se almacenan en un archivo JSON en la carpeta de perfil de usuario de la máquina local:

Ruta del sistema de archivos:

%APPDATA%\Microsoft\UserSecrets\<user_secrets_id>\secrets.json

En las rutas de acceso de archivo anteriores, reemplace <user_secrets_id> por el valor UserSecretsId especificado en el archivo de proyecto.

No escriba un código que dependa de la ubicación o el formato de los datos guardados con la herramienta Administrador de secretos. Estos detalles de implementación pueden cambiar. Por ejemplo, los valores secretos no están cifrados, pero podrían estarlo en el futuro.

Habilitación del almacenamiento de secretos

La herramienta Secret Manager funciona con las opciones de configuración específicas del proyecto almacenadas en el perfil de usuario.

La herramienta Administrador de secretos incluye un comando init en el SDK de .NET Core 3.0.100 o posterior. Para usar los secretos de usuario, ejecute los siguientes comandos en el directorio del proyecto:

dotnet user-secrets init

El comando anterior agrega un elemento UserSecretsId con un PropertyGroup del archivo del proyecto. De forma predeterminada, el texto interno de UserSecretsId es un GUID. El texto interno es arbitrario, pero es único para el proyecto.

<PropertyGroup>
  <TargetFramework>netcoreapp3.1</TargetFramework>
  <UserSecretsId>79a3edd0-2092-40a2-a04d-dcb46d5ca9ed</UserSecretsId>
</PropertyGroup>

En Visual Studio, haga clic con el botón derecho en el proyecto en el Explorador de soluciones y seleccione Administrar secretos de usuario en el menú contextual. Este gesto agrega un elemento UserSecretsId, rellenado con un GUID, al archivo del proyecto.

Establecimiento de un secreto

Defina un secreto de aplicación que consta de una clave y su valor. El secreto está asociado al valor UserSecretsId del proyecto. Por ejemplo, ejecute el siguiente comando desde el directorio en el que existe el archivo del proyecto:

dotnet user-secrets set "Movies:ServiceApiKey" "12345"

En el ejemplo anterior, los dos puntos indican que Movies es un literal de objeto con una propiedad ServiceApiKey.

La herramienta Secret Manager también se puede usar desde otros directorios. Use la opción --project para proporcionar la ruta de acceso del sistema de archivos en la que existe el archivo del proyecto. Por ejemplo:

dotnet user-secrets set "Movies:ServiceApiKey" "12345" --project "C:\apps\WebApp1\src\WebApp1"

Aplanamiento de estructura JSON en Visual Studio

El gesto Administrar secretos de usuario de Visual Studio abre un archivo secrets.json en el editor de texto. Reemplace el contenido de secrets.json por los pares clave-valor que se van a almacenar. Por ejemplo:

{
  "Movies": {
    "ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
    "ServiceApiKey": "12345"
  }
}

La estructura JSON se aplana después de modificarse a través de dotnet user-secrets remove o dotnet user-secrets set. Por ejemplo, ejecutar dotnet user-secrets remove "Movies:ConnectionString" contrae el literal de objeto Movies. El archivo modificado es similar al siguiente JSON:

{
  "Movies:ServiceApiKey": "12345"
}

Establecimiento de varios secretos

Un lote de secretos se puede establecer mediante la canalización de JSON al comando set. En el ejemplo siguiente, el contenido del archivo input.json se canaliza al comando set.

Abra un shell de comandos y escriba el siguiente comando:

type .\input.json | dotnet user-secrets set

Acceder a un secreto

Para acceder a un secreto, complete los pasos siguientes:

  1. Registre el origen de configuración de los secretos de usuario
  2. Lea el secreto a través de la API de configuración

Registre el origen de configuración de secretos de usuario

El proveedor de configuración de secretos de usuario registra el origen de configuración adecuado con la API de configuración de .NET.

El origen de configuración de los secretos de usuario se agrega automáticamente en modo de desarrollo cuando el proyecto llama a CreateDefaultBuilder. CreateDefaultBuilder llama a AddUserSecrets cuando EnvironmentName es Development:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

Cuando no se llama a CreateDefaultBuilder, agregue el origen de configuración de los secretos de usuario explícitamente mediante una llamada a AddUserSecrets en ConfigureAppConfiguration. Llame a AddUserSecrets solo cuando la aplicación se ejecute en el entorno de desarrollo, como se muestra en el ejemplo siguiente:

public class Program
{
    public static void Main(string[] args)
    {
        var host = new HostBuilder()
            .ConfigureAppConfiguration((hostContext, builder) =>
            {
                // Add other providers for JSON, etc.

                if (hostContext.HostingEnvironment.IsDevelopment())
                {
                    builder.AddUserSecrets<Program>();
                }
            })
            .Build();
        
        host.Run();
    }
}

Lea el secreto a través de la API de configuración

Si el origen de configuración de secretos de usuario está registrado, la API de configuración .NET puede leer los secretos. La inserción de constructores se puede usar para obtener acceso a la API de configuración .NET. Tenga en cuenta los ejemplos siguientes de lectura de la clave Movies:ServiceApiKey:

Clase Startup:

public class Startup
{
    private string _moviesApiKey = null;

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        _moviesApiKey = Configuration["Movies:ServiceApiKey"];
    }

    public void Configure(IApplicationBuilder app)
    {
        app.Run(async (context) =>
        {
            var result = string.IsNullOrEmpty(_moviesApiKey) ? "Null" : "Not Null";
            await context.Response.WriteAsync($"Secret is {result}");
        });
    }
}

Razor Modelo de página de páginas:

public class IndexModel : PageModel
{
    private readonly IConfiguration _config;

    public IndexModel(IConfiguration config)
    {
        _config = config;
    }

    public void OnGet()
    {
        var moviesApiKey = _config["Movies:ServiceApiKey"];

        // call Movies service with the API key
    }
}

Para obtener más información, consulte Configuración de acceso en Startup y Configuración de acceso en páginas Razor.

Asignación de secretos a un POCO

Asignar un literal de objeto completo a un POCO (una clase .NET simple con propiedades) es útil para agregar propiedades relacionadas.

Supongamos que el archivosecrets.json de la aplicación contiene los dos secretos siguientes:

{
  "Movies:ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
  "Movies:ServiceApiKey": "12345"
}

Para asignar los secretos anteriores a un POCO, use la característica de enlace de grafos de objetos de la API de configuración de .NET. El código siguiente se enlaza a un POCO personalizado MovieSettings y accede al valor de propiedad ServiceApiKey:

var moviesConfig = 
    Configuration.GetSection("Movies").Get<MovieSettings>();
_moviesApiKey = moviesConfig.ServiceApiKey;

Los secretos Movies:ConnectionString y Movies:ServiceApiKey son asignados a las respectivas propiedades en MovieSettings:

public class MovieSettings
{
    public string ConnectionString { get; set; }

    public string ServiceApiKey { get; set; }
}

Reemplazo de cadenas con secretos

El almacenamiento de contraseñas en texto sin formato no es seguro. Nunca almacene secretos en un archivo de configuración, como appsettings.json, que puede que se proteja en un repositorio de código fuente.

Por ejemplo, una base de datos cadena de conexión almacenada en appsettings.json no debe incluir una contraseña. En su lugar, almacene la contraseña como un secreto e incluya la contraseña en el cadena de conexión en tiempo de ejecución. Por ejemplo:

dotnet user-secrets set "DbPassword" "<secret value>"

Reemplace el <secret value> marcador de posición del ejemplo anterior por el valor de contraseña. Establezca el valor del secreto en la propiedad de Password un SqlConnectionStringBuilder objeto para incluirlo como valor de contraseña en el cadena de conexión:

using System.Data.SqlClient;

var builder = WebApplication.CreateBuilder(args);

var conStrBuilder = new SqlConnectionStringBuilder(
        builder.Configuration.GetConnectionString("Movies"));
conStrBuilder.Password = builder.Configuration["DbPassword"];
var connection = conStrBuilder.ConnectionString;

var app = builder.Build();

app.MapGet("/", () => connection);

app.Run();

Enumera los secretos

Supongamos que el archivosecrets.json de la aplicación contiene los dos secretos siguientes:

{
  "Movies:ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
  "Movies:ServiceApiKey": "12345"
}

Ejecute el siguiente comando desde el directorio en el que existe el archivo del proyecto:

dotnet user-secrets list

Se mostrará la siguiente salida:

Movies:ConnectionString = Server=(localdb)\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true
Movies:ServiceApiKey = 12345

En el ejemplo anterior, un signo de dos puntos en los nombres de las claves denota la jerarquía de objetos dentro de secrets.json.

Eliminación de un único secreto

Supongamos que el archivosecrets.json de la aplicación contiene los dos secretos siguientes:

{
  "Movies:ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
  "Movies:ServiceApiKey": "12345"
}

Ejecute el siguiente comando desde el directorio en el que existe el archivo del proyecto:

dotnet user-secrets remove "Movies:ConnectionString"

El archivo de la aplicación secrets.json se modificó para quitar el par clave-valor asociado a la clave MoviesConnectionString:

{
  "Movies": {
    "ServiceApiKey": "12345"
  }
}

dotnet user-secrets list muestra el siguiente mensaje de advertencia:

Movies:ServiceApiKey = 12345

Eliminación de todos los secretos

Supongamos que el archivosecrets.json de la aplicación contiene los dos secretos siguientes:

{
  "Movies:ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;Trusted_Connection=True;MultipleActiveResultSets=true",
  "Movies:ServiceApiKey": "12345"
}

Ejecute el siguiente comando desde el directorio en el que existe el archivo del proyecto:

dotnet user-secrets clear

Todos los secretos de usuario de la aplicación se han eliminado del archivo secrets.json:

{}

Al ejecutar dotnet user-secrets list se muestra el siguiente mensaje de advertencia:

No secrets configured for this application.

Administración de secretos de usuario con Visual Studio

Para administrar secretos de usuario en Visual Studio, haga clic con el botón derecho en el proyecto en el explorador de soluciones y seleccione Administrar secretos de usuario:

Visual Studio mostrando la adiministración de los secretos de usuario

Migración de secretos de usuario de ASP.NET Framework a ASP.NET Core

Consulte este problema de GitHub.

Secretos de usuario en aplicaciones que no son web

Los proyectos que tienen como destino Microsoft.NET.Sdk.Web incluyen automáticamente compatibilidad con secretos de usuario. Para los proyectos que tienen como destino Microsoft.NET.Sdk, como las aplicaciones de consola, instale explícitamente los paquetes NuGet de extensión de configuración y secretos de usuario.

Mediante PowerShell:

Install-Package Microsoft.Extensions.Configuration
Install-Package Microsoft.Extensions.Configuration.UserSecrets

Mediante la CLI de .NET:

dotnet add package Microsoft.Extensions.Configuration
dotnet add package Microsoft.Extensions.Configuration.UserSecrets

Una vez instalados los paquetes, inicialice el proyecto y establezca secretos de la misma manera que para una aplicación web. En el siguiente ejemplo se muestra una aplicación de consola que recupera el valor de un secreto que se estableció con la clave "AppSecret":

using Microsoft.Extensions.Configuration;

namespace ConsoleApp;

class Program
{
    static void Main(string[] args)
    {
        IConfigurationRoot config = new ConfigurationBuilder()
            .AddUserSecrets<Program>()
            .Build();

        Console.WriteLine(config["AppSecret"]);
    }
}

Recursos adicionales