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

Por Rick Anderson y Kirk Larkin

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

En este documento se explica cómo administrar datos confidenciales para una ASP.NET Core en una máquina de desarrollo. Nunca almacene contraseñas u otros datos confidenciales en el código fuente. Los secretos de producción no deben usarse para desarrollo ni pruebas. Los secretos no deben implementarse con la aplicación. En su lugar, se debe acceder a los secretos de producción a través de un medio controlado, como variables de entorno o Azure Key Vault. Puede almacenar y proteger sus secretos de producción y pruebas de Azure con el proveedor de configuración de Azure Key Vault.

Variables de entorno

Las variables de entorno se usan para evitar el almacenamiento de secretos de aplicación en 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 previamente.

Considere una aplicación ASP.NET Core web en la que la seguridad de cuentas de usuario individuales está habilitada. Se incluye una cadena de conexión de base de datos predeterminada en el archivo appsettings.json del proyecto 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, DefaultConnection el valor de clave se puede reemplazar por el valor de una variable de entorno. La variable de entorno puede almacenar la cadena de conexión completa con credenciales confidenciales.

Advertencia

Por lo general, las variables de entorno se almacenan en texto sin cifrar. Si la máquina o el proceso están en peligro, pueden acceder a las variables de entorno las partes que no sean de confianza. 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. __, el carácter de subrayado doble, tiene las siguientes características:

  • Es compatible con todas las plataformas. Por ejemplo, el separador : no es compatible con Bash, pero __ sí.
  • Se reemplaza automáticamente por un signo :.

Administrador de secretos

La herramienta Administrador de secretos almacena datos confidenciales durante el desarrollo de un ASP.NET Core proyecto. En este contexto, un fragmento de datos confidenciales es un secreto de aplicación. Los secretos de la 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 están registrados en el control de código fuente.

Advertencia

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

Funcionamiento de la herramienta Secret Manager

La herramienta Administrador de secretos 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 de acceso 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 especificado en el archivo de UserSecretsId proyecto.

No escriba 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 de secreto no están cifrados, pero podrían estar en el futuro.

Habilitación del almacenamiento de secretos

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

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

dotnet user-secrets init

El comando anterior agrega un UserSecretsId elemento dentro de un del archivo de PropertyGroup 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 Explorador de soluciones y seleccione Administrar secretos de usuario en el menú contextual. Este gesto agrega un UserSecretsId elemento, rellenado con un GUID, al archivo de proyecto.

Establecer un secreto

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

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

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

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

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

Aplanado de estructura JSON en Visual Studio

Visual Studio el gesto Administrar secretos de usuario abre un archivo secrets.json en el editor de texto. Reemplace el contenido de secrets.json por los pares clave-valor que se almacenarán. 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 las modificaciones a través dotnet user-secrets remove de o dotnet user-secrets set . Por ejemplo, al dotnet user-secrets remove "Movies:ConnectionString" ejecutar se contrae el Movies literal de objeto. El archivo modificado es similar al siguiente JSON:

{
  "Movies:ServiceApiKey": "12345"
}

Establecer varios secretos

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

Abra un shell de comandos y ejecute el siguiente comando:

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

Acceso a un secreto

Para acceder a un secreto, complete los pasos siguientes:

  1. Registro del origen de configuración de secretos de usuario
  2. Lee el secreto a través de Configuration API.

Registro del 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. Inicializado WebApplicationBuilder ( builder ) proporciona la configuración predeterminada y llama a cuando es AddUserSecrets EnvironmentName Development :

Lee el secreto a través de Configuration API.

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

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 Pages:

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 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.js la aplicación contiene los dos secretos siguientes:

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

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

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

Los Movies:ConnectionString Movies:ServiceApiKey secretos y se asignan a las propiedades respectivas de MovieSettings :

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

    public string ServiceApiKey { get; set; }
}

Reemplazo de cadenas por secretos

El almacenamiento de contraseñas en texto sin formato no es seguro. Por ejemplo, una cadena de conexión de base de datos almacenada appsettings.json en puede incluir una contraseña para el usuario especificado:

{
  "ConnectionStrings": {
    "Movies": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;User Id=johndoe;Password=pass123;MultipleActiveResultSets=true"
  }
}

Un enfoque más seguro es almacenar la contraseña como un secreto. Por ejemplo:

dotnet user-secrets set "DbPassword" "pass123"

Quite el Password par clave-valor de la cadena de conexión en appsettings.json . Por ejemplo:

{
  "ConnectionStrings": {
    "Movies": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;User Id=johndoe;MultipleActiveResultSets=true"
  }
}

El valor del secreto se puede establecer en la SqlConnectionStringBuilder propiedad de un objeto para completar la cadena de Password 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();

Enumeración de los secretos

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

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

Ejecute el siguiente comando desde el directorio en el que existe el archivo de 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, dos puntos en los nombres de clave denota la jerarquía de objetos dentro de secrets.json.

Eliminación de un único secreto

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

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

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

dotnet user-secrets remove "Movies:ConnectionString"

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

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

dotnet user-secrets list muestra el mensaje siguiente:

Movies:ServiceApiKey = 12345

Eliminación de todos los secretos

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

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

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

dotnet user-secrets clear

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

{}

La dotnet user-secrets list ejecución muestra el mensaje siguiente:

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 muestra Administrar secretos de usuario

Recursos adicionales

Por Rick Anderson, Kirk Larkin, Daniel Rothy Scott Addie

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

En este documento se explica cómo administrar datos confidenciales para una ASP.NET Core en una máquina de desarrollo. Nunca almacene contraseñas u otros datos confidenciales en el código fuente. Los secretos de producción no deben usarse para desarrollo ni pruebas. Los secretos no deben implementarse con la aplicación. En su lugar, se debe acceder a los secretos de producción a través de un medio controlado, como variables de entorno o Azure Key Vault. Puede almacenar y proteger sus secretos de producción y pruebas de Azure con el proveedor de configuración de Azure Key Vault.

Variables de entorno

Las variables de entorno se usan para evitar el almacenamiento de secretos de aplicación en 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 ASP.NET Core web en la que la seguridad de cuentas de usuario individuales está habilitada. Se incluye una cadena de conexión de base de datos predeterminada en el archivo del appsettings.json proyecto 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 DefaultConnection aplicación, el valor de clave se puede invalidar por 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 generalmente se almacenan en texto sin cifrar sin cifrar. Si la máquina o el proceso están en peligro, las entidades 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. __, el carácter de subrayado doble, tiene las siguientes características:

  • Es compatible con todas las plataformas. Por ejemplo, el separador : no es compatible con Bash, pero __ sí.
  • Se reemplaza automáticamente por un signo :.

Administrador de secretos

La herramienta Administrador de secretos almacena información confidencial durante el desarrollo de un ASP.NET Core proyecto. En este contexto, un fragmento de datos confidenciales es un secreto de aplicación. Los secretos de la 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 están registrados en el control de código fuente.

Advertencia

La herramienta Administrador de secretos no cifra los secretos almacenados y no debe tratarse como un almacén de confianza. Solo para 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 Administrador de secretos 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 de acceso 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 especificado en el archivo del UserSecretsId proyecto.

No escriba 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 estar en el futuro.

Habilitación del almacenamiento de secretos

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

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

dotnet user-secrets init

El comando anterior agrega un UserSecretsId elemento dentro de un del archivo de PropertyGroup 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 Explorador de soluciones y seleccione Administrar secretos de usuario en el menú contextual. Este gesto agrega un UserSecretsId elemento, rellenado con un GUID, al archivo del proyecto.

Establecer un secreto

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

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

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

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

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

Aplanación de la estructura JSON en Visual Studio

Visual Studio el gesto Administrar secretos de usuario abre un archivo secrets.json en el editor de texto. Reemplace el contenido de secrets.json por los pares clave-valor que se almacenarán. 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 modificaciones a través dotnet user-secrets remove de o dotnet user-secrets set . Por ejemplo, al dotnet user-secrets remove "Movies:ConnectionString" ejecutar se contrae el Movies literal de objeto. El archivo modificado es similar al siguiente JSON:

{
  "Movies:ServiceApiKey": "12345"
}

Establecer varios secretos

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

Abra un shell de comandos y ejecute el siguiente comando:

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

Acceso a un secreto

Para acceder a un secreto, complete los pasos siguientes:

  1. Registro del origen de configuración de secretos de usuario
  2. Leer el secreto a través de Configuration API

Registro del 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 secretos de usuario se agrega automáticamente en modo de desarrollo cuando el proyecto llama a CreateDefaultBuilder . CreateDefaultBuilder llama AddUserSecrets a cuando es EnvironmentName Development :

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

Cuando no se llama a , agregue explícitamente el origen de configuración de secretos de CreateDefaultBuilder usuario mediante una llamada a en AddUserSecrets ConfigureAppConfiguration . Llame 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();
    }
}

Leer el secreto a través de Configuration API

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

Clase de inicio:

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 Pages:

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, vea Configuración de acceso en Configuración de inicio y acceso en Razor Pages.

Asignación de secretos a un POCO

La asignación de un literal de objeto completo a poco (una clase .NET simple con propiedades) es útil para agregar propiedades relacionadas.

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

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

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

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

Los Movies:ConnectionString Movies:ServiceApiKey secretos y se asignan a las propiedades respectivas en MovieSettings :

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

    public string ServiceApiKey { get; set; }
}

Reemplazo de cadenas por secretos

El almacenamiento de contraseñas en texto sin formato no es seguro. Por ejemplo, una cadena de conexión de base de datos almacenada appsettings.json en puede incluir una contraseña para el usuario especificado:

{
  "ConnectionStrings": {
    "Movies": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;User Id=johndoe;Password=pass123;MultipleActiveResultSets=true"
  }
}

Un enfoque más seguro es almacenar la contraseña como secreto. Por ejemplo:

dotnet user-secrets set "DbPassword" "pass123"

Quite el Password par clave-valor de la cadena de conexión en appsettings.json . Por ejemplo:

{
  "ConnectionStrings": {
    "Movies": "Server=(localdb)\\mssqllocaldb;Database=Movie-1;User Id=johndoe;MultipleActiveResultSets=true"
  }
}

El valor del secreto se puede establecer en la SqlConnectionStringBuilder propiedad de un objeto para completar la cadena de Password conexión:

public class Startup
{
    private string _connection = null;

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

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        var builder = new SqlConnectionStringBuilder(
            Configuration.GetConnectionString("Movies"));
        builder.Password = Configuration["DbPassword"];
        _connection = builder.ConnectionString;

        // code omitted for brevity
    }

    public void Configure(IApplicationBuilder app)
    {
        app.Run(async (context) =>
        {
            await context.Response.WriteAsync($"DB Connection: {_connection}");
        });
    }
}

Enumeración de los secretos

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

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

Ejecute el siguiente comando desde el directorio en el que existe el archivo de 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, dos puntos en los nombres de clave denota la jerarquía de objetos dentro de secrets.json.

Eliminación de un único secreto

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

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

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

dotnet user-secrets remove "Movies:ConnectionString"

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

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

dotnet user-secrets list muestra el mensaje siguiente:

Movies:ServiceApiKey = 12345

Eliminación de todos los secretos

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

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

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

dotnet user-secrets clear

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

{}

La dotnet user-secrets list ejecución muestra el mensaje siguiente:

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 muestra Administrar secretos de usuario

Recursos adicionales