Saltar al contenido

¿Cómo cifra una contraseña dentro de appsettings.json para ASP.net Core 2?

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 o IOptionsSnapshot donde T es la clase en la que se encuentra la sección appsettings.json está obligado a través de la services.Configure método (Ej. MyAppSettings). Alternativamente, si no desea vincularse a una clase, puede usar IConfiguration 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.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *