Cadenas de conexión y archivos de configuración (ADO.NET)

La incrustación de cadenas de conexión en el código de la aplicación puede producir vulnerabilidades en la seguridad y problemas de mantenimiento. Las cadenas de conexión sin cifrar compiladas en el código fuente de una aplicación se pueden ver con la herramienta Ildasm.exe (Desensamblador de MSIL). Además, si la cadena de conexión cambia en algún momento, será necesario compilar de nuevo la aplicación. Por estas razones, se recomienda almacenar las cadenas de conexión en un archivo de configuración de la aplicación.

Trabajar con archivos de configuración de la aplicación

Los archivos de configuración de la aplicación contienen valores específicos de una aplicación determinada. Por ejemplo, una aplicación de ASP.NET puede tener uno o varios archivos web.config y una aplicación Windows puede tener un archivo app.config opcional. Los archivos de configuración comparten elementos comunes, aunque su nombre y ubicación varían en función del host de la aplicación.

Sección connectionStrings

Las cadenas de conexión se pueden almacenar como pares clave-valor en la sección connectionStrings del elemento configuration en el archivo de configuración de una aplicación. Los elementos secundarios incluyen add, clear y remove.

El siguiente fragmento del archivo de configuración muestra el esquema y la sintaxis para almacenar una cadena de conexión. El atributo name es un nombre que se proporciona para identificar de forma única una cadena de conexión, de forma que se pueda recuperar en tiempo de ejecución. providerName es el nombre invariable del proveedor de datos .NET Framework registrado en el archivo machine.config.

<?xml version='1.0' encoding='utf-8'?>
  <configuration>
    <connectionStrings>
      <clear />
      <add name="Name" 
       providerName="System.Data.ProviderName" 
       connectionString="Valid Connection String;" />
    </connectionStrings>
  </configuration>
NotaNota

Puede guardar parte de la cadena de conexión en un archivo de configuración y usar la clase DbConnectionStringBuilder para completarla en tiempo de ejecución.Esto resulta útil en escenarios en los que no se conocen los elementos de la cadena de conexión por anticipado o cuando no desea guardar información confidencial en un archivo de configuración.Para obtener más información, vea Compiladores de cadenas de conexión (ADO.NET).

Uso de archivos de configuración externos

Los archivos de configuración externos son archivos independientes que contienen un fragmento de un archivo de configuración compuesto de una sola sección. El archivo de configuración principal hace referencia al archivo de configuración externo. El almacenamiento de la sección connectionStrings en un archivo físicamente independiente resulta útil en situaciones en las que es posible que se edite la cadena de conexión después de implementar la aplicación. Por ejemplo, si se modifican los archivos de configuración, ASP.NET reinicia de forma predeterminada el dominio de la aplicación, lo que provoca la pérdida de la información de estado. Sin embargo, la modificación de un archivo de configuración externo no provoca el reinicio de la aplicación. Los archivos de configuración externos no se limitan a ASP.NET; también se pueden utilizar en aplicaciones Windows. Además, la seguridad y permisos de acceso a los archivos se pueden usar para restringir el acceso a los archivos de configuración externos. El trabajo con archivos de configuración externos en tiempo de ejecución es transparente y no requiere código especial.

Para almacenar cadenas de conexión en un archivo de configuración externo, cree un archivo independiente que contenga únicamente la sección connectionStrings. No incluya elementos, secciones ni atributos adicionales. En este ejemplo se muestra la sintaxis de un archivo de configuración externo.

  <connectionStrings>
    <add name="Name" 
     providerName="System.Data.ProviderName" 
     connectionString="Valid Connection String;" />
  </connectionStrings>

En el archivo de configuración principal de la aplicación, use el atributo configSource para especificar el nombre completo y la ubicación del archivo externo. En este ejemplo se hace referencia a un archivo de configuración externo denominado connections.config.

<?xml version='1.0' encoding='utf-8'?>
<configuration>
    <connectionStrings configSource="connections.config"/>
</configuration>

Recuperar cadenas de conexión en tiempo de ejecución

.NET Framework 2.0 incorpora nuevas clases en el espacio de nombres System.Configuration para simplificar la recuperación de las cadenas de conexión de los archivos de configuración en tiempo de ejecución. La cadena de conexión se puede recuperar mediante programación con el nombre de la cadena o el nombre de proveedor.

NotaNota

El archivo machine.config también contiene una sección connectionStrings, donde se encuentran las cadenas de conexión que usa Visual Studio.Al recuperar cadenas de conexión mediante el nombre del proveedor del archivo app.config en una aplicación Windows, primero se cargan las cadenas de conexión del archivo machine.config y, a continuación, las entradas de app.config.Si se agrega clear inmediatamente después del elemento connectionStrings, se quitarán todas las referencias heredadas de la estructura de datos en memoria, de forma que solo se tendrán en cuenta las cadenas de conexión definidas en el archivo app.config local.

Trabajar con clases de configuración

A partir de .NET Framework 2.0, se usa el elemento ConfigurationManager al trabajar con archivos de configuración en el equipo local, reemplazando al elemento desusado ConfigurationSettings. WebConfigurationManager se usa para trabajar con archivos de configuración de ASP.NET. Esta característica se ha diseñado para trabajar con archivos de configuración en un servidor web y permite el acceso mediante programación a secciones del archivo de configuración como system.web.

NotaNota

El acceso a los archivos de configuración en tiempo de ejecución requiere la concesión de permisos al llamador; los permisos necesarios dependen del tipo de aplicación, del archivo de configuración y de la ubicación.Para obtener más información, vea Utilizar las clases Configuration y WebConfigurationManager para aplicaciones de ASP.NET o ConfigurationManager para aplicaciones Windows.

Puede usar ConnectionStringSettingsCollection para recuperar cadenas de conexión de archivos de configuración de aplicación. Esta clase contiene una colección de objetos ConnectionStringSettings, cada uno de los cuales representa una única entrada en la sección connectionStrings. Sus propiedades se asignan a los atributos de cadenas de conexión, lo que permite recuperar una cadena de conexión mediante la especificación de su nombre o del nombre del proveedor.

Propiedad

Descripción

Name

Nombre de la cadena de conexión. Se asigna al atributo name.

ProviderName

Nombre completo del proveedor. Se asigna al atributo providerName.

ConnectionString

Cadena de conexión. Se asigna al atributo connectionString.

Ejemplo: mostrar todas las cadenas de conexión

Este ejemplo recorre en iteración la colección ConnectionStringSettings y muestra las propiedades Name, ProviderName y ConnectionString en la ventana de la consola.

NotaNota

System.Configuration.dll no se incluye en todos los tipos de proyectos y es posible que deba establecer una referencia a este elemento para usar las clases de configuración.El nombre y la ubicación de un archivo de configuración de aplicación determinado varían en función del tipo de aplicación y del proceso de hospedaje.

Imports System.Configuration

Class Program
    Shared Sub Main()
        GetConnectionStrings()
        Console.ReadLine()
    End Sub

    Private Shared Sub GetConnectionStrings()

        Dim settings As ConnectionStringSettingsCollection = _
            ConfigurationManager.ConnectionStrings

        If Not settings Is Nothing Then
            For Each cs As ConnectionStringSettings In settings
                Console.WriteLine(cs.Name)
                Console.WriteLine(cs.ProviderName)
                Console.WriteLine(cs.ConnectionString)
            Next
        End If
    End Sub
End Class
using System.Configuration;

class Program
{
    static void Main()
    {
        GetConnectionStrings();
        Console.ReadLine();
    }

    static void GetConnectionStrings()
    {
        ConnectionStringSettingsCollection settings =
            ConfigurationManager.ConnectionStrings;

        if (settings != null)
        {
            foreach(ConnectionStringSettings cs in settings)
            {
                Console.WriteLine(cs.Name);
                Console.WriteLine(cs.ProviderName);
                Console.WriteLine(cs.ConnectionString);
            }
        }
    }
}

Ejemplo: recuperar una cadena de conexión por su nombre

El siguiente ejemplo muestra cómo recuperar una cadena de conexión de un archivo de configuración mediante la especificación del nombre. El código crea un objeto ConnectionStringSettings, de forma que el parámetro de entrada proporcionado coincida con el nombre de ConnectionStrings. Si no se encuentra una coincidencia de nombre, la función devuelve null (Nothing en Visual Basic).

' Retrieves a connection string by name.
' Returns Nothing if the name is not found.
Private Shared Function GetConnectionStringByName( _
    ByVal name As String) As String

    ' Assume failure
    Dim returnValue As String = Nothing

    ' Look for the name in the connectionStrings section.
    Dim settings As ConnectionStringSettings = _
       ConfigurationManager.ConnectionStrings(name)

    ' If found, return the connection string.
    If Not settings Is Nothing Then
        returnValue = settings.ConnectionString
    End If

    Return returnValue
End Function
// Retrieves a connection string by name.
// Returns null if the name is not found.
static string GetConnectionStringByName(string name)
{
    // Assume failure.
    string returnValue = null;

    // Look for the name in the connectionStrings section.
    ConnectionStringSettings settings =
        ConfigurationManager.ConnectionStrings[name];

    // If found, return the connection string.
    if (settings != null)
        returnValue = settings.ConnectionString;

    return returnValue;
}

Ejemplo: recuperar una cadena de conexión por el nombre de proveedor

En este ejemplo se muestra cómo recuperar una cadena de conexión mediante la especificación del nombre invariable de proveedor con el formato System.Data.ProviderName. El código recorre en iteración ConnectionStringSettingsCollection y devuelve la cadena de conexión del primer valor de ProviderName encontrado. Si no se encuentra el nombre del proveedor, la función devuelve null (Nothing en Visual Basic).

' Retrieve a connection string by specifying the providerName.
' Assumes one connection string per provider in the config file.
Private Shared Function GetConnectionStringByProvider( _
    ByVal providerName As String) As String

    'Return Nothing on failure.
    Dim returnValue As String = Nothing

    ' Get the collection of connection strings.
    Dim settings As ConnectionStringSettingsCollection = _
        ConfigurationManager.ConnectionStrings

    ' Walk through the collection and return the first 
    ' connection string matching the providerName.
    If Not settings Is Nothing Then
        For Each cs As ConnectionStringSettings In settings
            If cs.ProviderName = providerName Then
                returnValue = cs.ConnectionString
                Exit For
            End If
        Next
    End If

    Return returnValue
End Function
// Retrieve a connection string by specifying the providerName.
// Assumes one connection string per provider in the config file.
static string GetConnectionStringByProvider(string providerName)
{
    // Return null on failure.
    string returnValue = null;

    // Get the collection of connection strings.
    ConnectionStringSettingsCollection settings =
        ConfigurationManager.ConnectionStrings;

    // Walk through the collection and return the first 
    // connection string matching the providerName.
    if (settings != null)
    {
        foreach (ConnectionStringSettings cs in settings)
        {
            if (cs.ProviderName == providerName)
                returnValue = cs.ConnectionString;
            break;
        }
    }
    return returnValue;
}

Cifrar secciones del archivo de configuración mediante una configuración protegida

ASP.NET 2.0 incorpora una nueva característica denominada configuración protegida, que permite cifrar información confidencial en un archivo de configuración. Si bien se ha diseñado principalmente para ASP.NET, la configuración protegida también se puede usar para cifrar secciones del archivo de configuración en aplicaciones Windows. Para obtener una descripción detallada de las posibilidades de la nueva configuración protegida, vea Cifrar la información de configuración mediante una configuración protegida.

El siguiente fragmento de un archivo de configuración muestra la sección connectionStrings a continuación de su cifrado. La sección configProtectionProvider especifica el proveedor de configuración protegida que se usa para cifrar y descifrar las cadenas de conexión. La sección EncryptedData contiene el texto cifrado.

<connectionStrings configProtectionProvider="DataProtectionConfigurationProvider">
  <EncryptedData>
    <CipherData>
      <CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAH2... </CipherValue>
    </CipherData>
  </EncryptedData>
</connectionStrings>

Cuando se recupera la cadena de conexión cifrada en tiempo de ejecución, .NET Framework usa el proveedor especificado para descifrar el nodo CipherValue y que así esté disponible para la aplicación. No es necesario escribir ningún código adicional para administrar el proceso de descifrado.

Proveedores de configuración protegida

Los proveedores de configuración protegida se registran en la sección configProtectedData del archivo machine.config en el equipo local, tal como se muestra en el siguiente fragmento, donde se pueden ver los dos proveedores de configuración protegida que proporciona .NET Framework. Los valores que se muestran se han truncado para facilitar la lectura.

<configProtectedData defaultProvider="RsaProtectedConfigurationProvider">
  <providers>
    <add name="RsaProtectedConfigurationProvider" 
      type="System.Configuration.RsaProtectedConfigurationProvider, ... />
    <add name="DataProtectionConfigurationProvider" 
      type="System.Configuration.DpapiProtectedConfigurationProvider, ... />
  </providers>
</configProtectedData>

Puede configurar otros proveedores de configuración protegida si los agrega al archivo machine.config. Asimismo, puede crear su propio proveedor de configuración protegida heredando de la clase base abstracta ProtectedConfigurationProvider. En la tabla siguiente se describen los dos archivos de configuración incluidos en .NET Framework.

Proveedor

Descripción

RSAProtectedConfigurationProvider

Usa el algoritmo de cifrado RSA para cifrar y descifrar datos. Los algoritmos RSA se pueden usar para el cifrado de clave pública y para firmas digitales. También se conoce como cifrado de "clave pública" o asimétrico, ya que usa dos claves diferentes. Puede usar la herramienta Herramienta Registro de IIS en ASP.NET (Aspnet_regiis.exe) para cifrar secciones de un archivo Web.config y administrar las claves de cifrado. ASP.NET descifra el archivo de configuración cuando lo procesa. La identidad de la aplicación ASP.NET debe tener acceso de lectura a la clave de cifrado utilizada para cifrar y descifrar las secciones cifradas.

DPAPIProtectedConfigurationProvider

Usa la API de protección de datos (DPAPI) de Windows para cifrar y descifrar las secciones de configuración. Usa los servicios criptográficos integrados de Windows y se puede configurar para la protección específica de equipo o para la protección específica de cuenta de usuario. La protección específica de equipo resulta útil cuando varias aplicaciones del mismo servidor deben compartir información. La protección específica de cuenta de usuario se puede utilizar para los servicios que se ejecutan con una identidad de usuario concreta, como un entorno de hospedaje compartido. Cada aplicación se ejecuta con una identidad independiente que limita el acceso a recursos como los archivos y las bases de datos.

Ambos proveedores proporcionan cifrado de datos de alta seguridad. No obstante, si prevé usar el mismo archivo de configuración de cifrado en varios servidores como, por ejemplo, una granja de servidores web, solo RsaProtectedConfigurationProvider permite exportar las claves de cifrado usadas para cifrar los datos e importarlas a otro servidor. Para obtener más información, vea Importar y exportar contenedores de claves RSA con configuración protegida.

Uso de clases de configuración

El espacio de nombres System.Configuration proporciona clases para trabajar con valores de configuración mediante programación. La clase ConfigurationManager proporciona acceso a los archivos de configuración de equipo, aplicación y usuario. Si crea una aplicación ASP.NET, puede usar la clase WebConfigurationManager, que proporciona las mismas funciones a la vez que permite tener acceso a configuración única de las aplicaciones ASP.NET, como la que se encuentra en <system.web>.

NotaNota

El espacio de nombres System.Security.Cryptography contiene clases que proporcionan opciones adicionales para cifrar y descifrar datos.Use estas clases si requiere servicios criptográficos que no están disponibles cuando se usa la configuración protegida.Algunas de estas clases son contenedores de Microsoft CryptoAPI no administrado, mientras que otras son simplemente implementaciones administradas.Para obtener más información, vea Cryptographic Services.

Ejemplo de App.config

En este ejemplo se muestra cómo alternar el cifrado de la sección connectionStrings de un archivo app.config para una aplicación Windows. En este ejemplo, el procedimiento recibe el nombre de la aplicación como argumento, por ejemplo, "MyApplication.exe". A continuación, el archivo app.config se cifra y se copia en la carpeta que contiene el ejecutable con el nombre "MyApplication.exe.config".

NotaNota

La cadena de conexión solo se puede descifrar en el equipo donde se ha cifrado.

El código usa el método OpenExeConfiguration para abrir el archivo app.config y editarlo; el método GetSection devuelve la sección connectionStrings. A continuación, el código comprueba la propiedad IsProtected y llama a ProtectSection para cifrar la sección si no está cifrada. Para descifrar la sección se llama al método UnProtectSection(). El método Save completa la operación y guarda los cambios.

NotaNota

Para ejecutar el código, debe establecer una referencia al archivo System.Configuration.dll del proyecto.

Shared Sub ToggleConfigEncryption(ByVal exeConfigName As String)
    ' Takes the executable file name without the
    ' .config extension.
    Try
        ' Open the configuration file and retrieve 
        ' the connectionStrings section.
        Dim config As Configuration = ConfigurationManager. _
            OpenExeConfiguration(exeConfigName)

        Dim section As ConnectionStringsSection = DirectCast( _
            config.GetSection("connectionStrings"), _
            ConnectionStringsSection)

        If section.SectionInformation.IsProtected Then
            ' Remove encryption.
            section.SectionInformation.UnprotectSection()
        Else
            ' Encrypt the section.
            section.SectionInformation.ProtectSection( _
              "DataProtectionConfigurationProvider")
        End If

        ' Save the current configuration.
        config.Save()

        Console.WriteLine("Protected={0}", _
        section.SectionInformation.IsProtected)

    Catch ex As Exception
        Console.WriteLine(ex.Message)
    End Try
End Sub
static void ToggleConfigEncryption(string exeConfigName)
{
    // Takes the executable file name without the
    // .config extension.
    try
    {
        // Open the configuration file and retrieve 
        // the connectionStrings section.
        Configuration config = ConfigurationManager.
            OpenExeConfiguration(exeConfigName);

        ConnectionStringsSection section =
            config.GetSection("connectionStrings")
            as ConnectionStringsSection;

        if (section.SectionInformation.IsProtected)
        {
            // Remove encryption.
            section.SectionInformation.UnprotectSection();
        }
        else
        {
            // Encrypt the section.
            section.SectionInformation.ProtectSection(
                "DataProtectionConfigurationProvider");
        }
        // Save the current configuration.
        config.Save();

        Console.WriteLine("Protected={0}",
            section.SectionInformation.IsProtected);
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

Ejemplo de Web.config

Este ejemplo usa el método OpenWebConfiguration de WebConfigurationManager. Observe que en este caso puede indicar la ruta de acceso relativa al archivo Web.config mediante una tilde. El código requiere una referencia a la clase System.Web.Configuration.

Shared Sub ToggleWebEncrypt()
    ' Open the Web.config file.
    Dim config As Configuration = WebConfigurationManager. _
      OpenWebConfiguration("~")

    ' Get the connectionStrings section.
    Dim section As ConnectionStringsSection = DirectCast( _
        config.GetSection("connectionStrings"), _
        ConnectionStringsSection)

    ' Toggle encryption.
    If section.SectionInformation.IsProtected Then
        section.SectionInformation.UnprotectSection()
    Else
        section.SectionInformation.ProtectSection( _
          "DataProtectionConfigurationProvider")
    End If

    ' Save changes to the Web.config file.
    config.Save()
End Sub
static void ToggleWebEncrypt()
{
    // Open the Web.config file.
    Configuration config = WebConfigurationManager.
        OpenWebConfiguration("~");

    // Get the connectionStrings section.
    ConnectionStringsSection section =
        config.GetSection("connectionStrings")
        as ConnectionStringsSection;

    // Toggle encryption.
    if (section.SectionInformation.IsProtected)
    {
        section.SectionInformation.UnprotectSection();
    }
    else
    {
        section.SectionInformation.ProtectSection(
            "DataProtectionConfigurationProvider");
    }

    // Save changes to the Web.config file.
    config.Save();
}

Para obtener más información acerca de la protección de aplicaciones ASP.NET, vea Seguridad de ASP.NET y la sección sobre prácticas de seguridad en ASP.NET 2.0 en el Centro para desarrolladores de ASP.NET.

Vea también

Conceptos

Compiladores de cadenas de conexión (ADO.NET)

Proteger la información de conexión (ADO.NET)

Utilizar las clases Configuration

Otros recursos

Archivos de configuración

Administración de sitios web ASP.NET