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:
- Registre el origen de configuración de los secretos de usuario
- 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:
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
- Vea esta incidencia y esta incidencia para obtener información sobre el acceso a secretos de usuario desde IIS.
- Configuración en ASP.NET Core
- Proveedor de configuración de Azure Key Vault en ASP.NET Core
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:
- Registre el origen de configuración de los secretos de usuario
- 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:
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
- Vea esta incidencia y esta incidencia para obtener información sobre el acceso a secretos de usuario desde IIS.
- Configuración en ASP.NET Core
- Proveedor de configuración de Azure Key Vault en ASP.NET Core