Luego de tanto trabajar ya encontramos el arreglo de este asunto que muchos de nuestros lectores de esta web han tenido. Si tienes algo que aportar no dejes de dejar tu conocimiento.
Solución:
Recuerda no guardes secretos en la principal appsettings.json
que está en el sitio web y generalmente se mantiene en el control de código fuente. Utilice un proveedor de archivos para ubicar el archivo en alguna otra ubicación en otro lugar del servidor.
Si tiene acceso a Azure, puede almacenar el secreto en Azure Key Vault en lugar de appsettings.json
.
Con eso en mente, si desea usar un archivo JSON, puede usar un puente o una clase de proxy para manejar el descifrado de valores.
Primero necesitará una clase para descifrar los valores. Para abreviar, no entraré en los detalles de la clase de descifrado aquí y solo supondré que una clase llamada SettingsDecryptor
ha sido escrito e implementa una interfaz llamada ISettingsDecryptor
con un solo método Decrypt que descifra un string valor.
La clase de puente toma dos parámetros de constructor.
- El primero es un
IOptions
oIOptionsSnapshot
donde T es la clase en la que se encuentra la secciónappsettings.json
está obligado a través de laservices.Configure
método (Ej.MyAppSettings
). Alternativamente, si no desea vincularse a una clase, puede usarIConfiguration
en su lugar y leer directamente desde la configuración. - La segunda es la clase de descifrado que implementa
ISettingsDecryptor
.
En la clase de puente, cada propiedad que requiere descifrado debe usar la clase de descifrado para descifrar el valor cifrado en la configuración.
public class MyAppSettingsBridge : IAppSettings
private readonly IOptions _appSettings;
private readonly ISettingsDecrypt _decryptor;
public MyAppSettingsBridge(IOptionsSnapshot appSettings, ISettingsDecrypt decryptor)
_appSettings = appSettings ?? throw new ArgumentNullException(nameof(appSettings));
_decryptor = decryptor ?? throw new ArgumentException(nameof(decryptor));
public string ApplicationName => _appSettings.Value.ApplicationName;
public string SqlConnectionSting => _decryptor.Decrypt(_appSettings.Value.Sql);
public string OracleConnectionSting => _decryptor.Decrypt(_appSettings.Value.Oracle);
El contenedor DI debe configurarse de la siguiente manera:
public void ConfigureServices(IServiceCollection services)
services.AddMvc();
services.AddOptions();
services.Configure(Configuration.GetSection("MyAppSettings"));
services.AddSingleton(Configuration);
services.AddSingleton();
services.AddScoped();
El controlador puede entonces tener un constructor que tome el puente como un IAppSettings
para acceder a la configuración descifrada.
La respuesta anterior es un breve resumen de la solución general, ya que se requiere bastante código.
La explicación completa y detallada se puede ver en la publicación de mi blog Hiding Secrets in appsettings.json
– Uso de un puente en su configuración principal de ASP.Net (Parte 4), donde describo el uso de un patrón de puente en detalle. También hay un ejemplo completo (que incluye una clase de descifrado) en Github en https://github.com/configureappio/ConfiguarationBridgeCrypto
El proveedor de configuración JSON no admite el cifrado. Actualmente, el único proveedor listo para usar que admite la configuración cifrada es Azure KeyVault. Puede usar KeyVault independientemente de que su aplicación esté alojada en Azure o no, y aunque no es gratis, las asignaciones son tales que probablemente solo cueste centavos en la mayoría de los escenarios.
Dicho esto, parte de la belleza de Core es que es completamente modular. Siempre puede crear su(s) propio(s) proveedor(es) de configuración e implementar lo que quiera. Por ejemplo, podría escribir un proveedor JSON que realmente lo hace Admite encriptación, si así es como quieres ir.
Para ASP.NET Core, la mejor solución es realizar cualquier transformación de los valores de configuración, como descifrado o string reemplazos, cuando se inicia la aplicación. Esta es la razón por la que existe el proveedor de configuración.
Los proveedores de configuración se pueden encadenar. En el código fuente de Microsoft.Extensions.Configuration hay una clase llamada ChainedConfigurationProvider que se puede usar como ejemplo.
public static IHostBuilder CreateHostBuilder(string[] args)
return new HostBuilder()
.ConfigureAppConfiguration((host, config) =>
var jsonFile = new ConfigurationBuilder();
jsonFile.AddJsonFile("appsettings.json");
// the json file is the source for the new configuration provider.
config.AddConfiguration(jsonFile.Build());
);
Si usa Docker Swarm o Kubernetes, no tiene que cifrar la contraseña en el archivo appsettings.json. Puede usar el proveedor de configuración de clave por archivo integrado o el proveedor de configuración personalizado para leer la contraseña de un secreto de Docker y asignarla a un valor de configuración.
En mi publicación de blog Cómo administrar contraseñas en los archivos de configuración de ASP.NET Core, explico en detalle cómo crear un proveedor de configuración personalizado que le permita mantener solo la contraseña como un secreto y actualizar la configuración. string en tiempo de ejecución. Además, el código fuente completo de este artículo está alojado en github.com/gabihodoroaga/blog-app-secrets.
Sección de Reseñas y Valoraciones
Recuerda que puedes mostrar este artículo si si solucionó tu problema.