Cadeias de conexão e arquivos de configuração

Inserir cadeias de conexão no código do seu aplicativo pode resultar em vulnerabilidades de segurança e problemas de manutenção. As cadeias de conexão não criptografadas compiladas no código-fonte de um aplicativo podem ser exibidas com a ferramenta Ildasm.exe (IL Disassembler). Além disso, se a cadeia de conexão for alterada, seu aplicativo deverá ser recompilado. Por esses motivos, recomendamos armazenar cadeias de conexão em um arquivo de configuração do aplicativo.

Trabalhando com arquivos de configuração de aplicativo

Os arquivos de configuração do aplicativo contêm as configurações que são específicas para um determinado aplicativo. Por exemplo, um aplicativo ASP.NET pode ter um ou mais arquivos web.config e um aplicativo do Windows pode ter um arquivo app.config opcional. Os arquivos de configuração compartilham elementos comuns, embora o nome e o local de um arquivo de configuração variem dependendo do host do aplicativo.

A seção de connectionStrings

As cadeias de conexão podem ser armazenadas como pares chave/valor na seção connectionStrings do elemento configuration de um arquivo de configuração de aplicativo. Os elementos filho incluem add, clear e remove.

O fragmento de arquivo de configuração a seguir demonstra o esquema e a sintaxe para armazenar uma cadeia de conexão. O atributo name é um nome que você fornece para identificar exclusivamente uma cadeia de conexão para que ela possa ser recuperada em tempo de execução. O providerName é o nome invariável do provedor de dados .NET Framework, que está registrado no arquivo 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>  

Observação

Você pode salvar parte de uma cadeia de conexão em um arquivo de configuração e usar a classe DbConnectionStringBuilder para concluí-la em tempo de execução. Isso é útil em situações onde você não conhece os elementos da cadeia de conexão com antecedência, ou quando não quer salvar informações confidenciais em um arquivo de configuração. Para obter mais informações, confira Construtores de cadeias de conexão.

Utilizando arquivos de configuração externos

Os arquivos de configuração externos são arquivos separados que contêm um fragmento de um arquivo de configuração que consiste em uma única seção. O arquivo de configuração externo é, em seguida, referenciado pelo arquivo de configuração principal. O armazenamento da seção connectionStrings em um arquivo fisicamente separado é útil em situações em que as cadeias de conexão podem ser editadas após a implantação do aplicativo. Por exemplo, o comportamento padrão do ASP.NET é reiniciar o domínio de um aplicativo quando os arquivos de configuração são modificados, o que resulta em perda de informações de estado. No entanto, modificar um arquivo de configuração externo não causa uma reinicialização do aplicativo. Os arquivos de configuração externos não estão limitados ao ASP.NET; eles também podem ser usados por aplicativos do Windows. Além disso, a segurança de acesso a arquivos e as permissões podem ser usadas para restringir o acesso a arquivos de configuração externos. Trabalhar com arquivos de configuração externos em tempo de execução é transparente e não exige nenhuma codificação especial.

Para armazenar cadeias de conexão em um arquivo de configuração externo, crie um arquivo separado que contenha somente a seção connectionStrings. Não inclui elementos, seções ou atributos adicionais. Este exemplo mostra a sintaxe para um arquivo de configuração externo.

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

No arquivo de configuração de aplicativo principal, use o atributo configSource para especificar o nome totalmente qualificado e o local do arquivo externo. Este exemplo refere-se a um arquivo de configuração externo chamado connections.config.

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

Recuperando cadeias de conexão em tempo de execução

O .NET Framework 2.0 introduziu novas classes no namespace System.Configuration para simplificar a recuperação de cadeias de conexão de arquivos de configuração em tempo de execução. Você pode programaticamente recuperar uma cadeia de conexão por nome ou nome do provedor.

Observação

O arquivo machine.config também contém uma seção connectionStrings, que contém as cadeias de conexão usadas pelo Visual Studio. Ao recuperar cadeias de conexão pelo nome do provedor do arquivo app.config em um aplicativo do Windows, as cadeias de conexão em machine.config são carregadas primeiro e, em seguida, as entradas de app.config. Adicionar clear imediatamente após o elemento connectionStrings remove todas as referências herdadas da estrutura de dados na memória, de modo que somente as cadeias de conexão definidas no arquivo app.config local serão consideradas.

Trabalhando com as classes de configuração

A partir do .NET Framework 2.0, ConfigurationManager é usado ao trabalhar com arquivos de configuração no computador local, substituindo o ConfigurationSettings obsoleto. WebConfigurationManager é usado para trabalhar com arquivos de configuração do ASP.NET. Ele foi criado para trabalhar com arquivos de configuração em um servidor Web e permite o acesso programático a seções do arquivo de configuração como system.web.

Observação

Acessar arquivos de configuração em tempo de execução exige a concessão de permissões para o chamador; as permissões necessárias dependem do tipo de aplicativo, do arquivo de configuração e do local. Para obter mais informações, confira Usando as classes de configuração, WebConfigurationManager para aplicativos ASP.NET e ConfigurationManager para aplicativos do Windows.

Você pode usar ConnectionStringSettingsCollection para recuperar cadeias de conexão de arquivos de configuração do aplicativo. Ele contém uma coleção de objetos ConnectionStringSettings, cada um deles representando uma única entrada na seção connectionStrings. Suas propriedades mapeiam para atributos de cadeia de conexão, permitindo que você recupere uma cadeia de conexão especificando o nome ou o nome do provedor.

Propriedade Descrição
Name O nome da cadeia de conexão. Mapeado para o atributo name.
ProviderName O nome do provedor totalmente qualificado. Mapeado para o atributo providerName.
ConnectionString A cadeia de conexão. Mapeada para o atributo connectionString.

Exemplo: listando todas as cadeias de conexão

Este exemplo itera por meio de ConnectionStringSettingsCollection e exibe as propriedades ConnectionStringSettings.Name, ConnectionStringSettings.ProviderName e ConnectionStringSettings.ConnectionString na janela do console.

Observação

System.Configuration.dll não está incluído em todos os tipos de projeto, e você talvez precise definir uma referência para ele para usar as classes de configuração. O nome e o local de um arquivo de configuração do aplicativo específico variam pelo tipo de aplicativo e o processo de hospedagem.

using System.Configuration;

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

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

        foreach (ConnectionStringSettings cs in settings)
        {
            Console.WriteLine(cs.Name);
            Console.WriteLine(cs.ProviderName);
            Console.WriteLine(cs.ConnectionString);
        }
    }
}
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

Exemplo: recuperando uma cadeia de conexão por nome

Este exemplo demonstra como recuperar uma cadeia de conexão de um arquivo de configuração especificando seu nome. O código cria um objeto ConnectionStringSettings, correspondendo o parâmetro de entrada fornecido com o nome de ConnectionStrings. Se nenhum nome correspondente for localizado, a função retornará null (Nothing no Visual Basic).

// Retrieves a connection string by name.
// Returns null if the name is not found.
static string? GetConnectionStringByName(string name)
{
    // Look for the name in the connectionStrings section.
    ConnectionStringSettings? settings =
        ConfigurationManager.ConnectionStrings[name];

    // If found, return the connection string (otherwise return null)
    return settings?.ConnectionString;
}
' 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

Exemplo: recuperando uma cadeia de conexão por nome de provedor

Este exemplo demonstra como recuperar uma cadeia de conexão especificando o nome invariável do provedor no formato System.Data.ProviderName. O código itera por meio do ConnectionStringSettingsCollection e retorna a cadeia de conexão para o primeiro ProviderName encontrado. Se o nome do provedor não for localizado, a função retornará null (Nothing no Visual Basic).

// Retrieve a connection string by specifying the providerName.
// Assumes one connection string per provider in the config file.
static string? GetConnectionStringByProvider(string providerName)
{
    // 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)
            {
                return cs.ConnectionString;
            }
        }
    }
    return null;
}
' 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

Criptografando seções do arquivo de configuração usando configuração protegida

O ASP.NET 2.0 introduziu uma nova funcionalidade, chamada configuração protegida, que permite criptografar informações confidenciais em um arquivo de configuração. Embora tenha sido projetado principalmente para ASP.NET, a configuração protegida também pode ser usada para criptografar seções do arquivo de configuração em aplicativos do Windows. Para obter uma descrição detalhada das funcionalidades da configuração protegida, confira Criptografando informações de configuração usando a configuração protegida.

O fragmento do arquivo de configuração a seguir mostra a seção connectionStrings depois de ser criptografada. O configProtectionProvider especifica o provedor de configuração protegida usado para criptografar e descriptografar as cadeias de conexão. A seção EncryptedData contém o texto de criptografia.

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

Quando a cadeia de conexão criptografada é recuperada em tempo de execução, o .NET Framework usa o provedor especificado para descriptografar CipherValue e disponibilizá-lo para o aplicativo. Você não precisa escrever nenhum código adicional para gerenciar o processo descriptografia.

Provedores de configuração protegida

Os provedores de configuração protegida são registrados na seção configProtectedData do arquivo machine.config no computador local, conforme mostrado no fragmento a seguir, que mostra os dois provedores de configuração protegida fornecidos com o .NET Framework. Os valores mostrados aqui foram truncados para facilitar a leitura.

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

Configure outros provedores de configuração protegida adicionando-os ao arquivo machine.config. Você também pode criar seu próprio provedor de configuração protegida por herança da classe base abstrata ProtectedConfigurationProvider. A tabela a seguir descreve os dois arquivos de configuração incluídos no .NET Framework.

Provedor Descrição
RsaProtectedConfigurationProvider Usa o algoritmo de criptografia RSA para criptografar e descriptografar dados. O algoritmo RSA pode ser usado para criptografia de chave pública e assinaturas digitais. Também é conhecido como “chave pública” ou criptografia assimétrica porque emprega duas chaves diferentes. Use a Ferramenta de Registro do IIS do ASP.NET (Aspnet_regiis.exe) para criptografar as seções em um arquivo Web.config e gerenciar as chaves de criptografia. O ASP.NET descriptografa o arquivo de configuração quando processa o arquivo. A identidade do aplicativo do ASP.NET deve ter acesso de leitura para a chave de criptografia que é usada para criptografar e descriptografar as seções criptografadas.
DpapiProtectedConfigurationProvider Usa a API de Proteção aos Dados do Windows (DPAPI) para criptografar seções de configuração. Usa os serviços de criptografia internos do Windows e pode ser configurado para proteção específica de computador ou da conta do usuário. A proteção específica do computador é útil para vários aplicativos no mesmo servidor que precisam compartilhar informações. A proteção específica da conta do usuário pode ser usada com serviços que são executados com uma identidade de usuário específica, como um ambiente de hospedagem compartilhado. Cada aplicativo é executado em uma identidade separada que restringe o acesso a recursos como arquivos e bancos de dados.

Os dois provedores oferecem criptografia de dados forte. Entretanto, se você estiver planejando usar o mesmo arquivo de configuração criptografado em vários servidores, como uma Web farm, apenas o RsaProtectedConfigurationProvider permite que você exporte as chaves de criptografia usadas para criptografar os dados e importá-los em outro servidor. Para obter mais informações, confira Importando e exportando contêineres de chave RSA da configuração protegida.

Usando as classes de configuração

O namespace System.Configuration fornece classes para trabalhar com parâmetros de configuração programaticamente. A classe ConfigurationManager fornece acesso a arquivos de computador, aplicativo e configuração do usuário. Se você estiver criando um aplicativo do ASP.NET, poderá usar a classe WebConfigurationManager, que fornece a mesma funcionalidade além de permitir o acesso às configurações que são exclusivas para os aplicativos do ASP.NET, como os encontrados em <system.web>.

Observação

O namespace System.Security.Cryptography contém classes que oferecem opções adicionais para criptografar e descriptografar dados. Use essas classes se você precisar de serviços de criptografia que não estão disponíveis usando a configuração protegida. Algumas dessas classes são wrappers da Microsoft CryptoAPI não gerenciada, enquanto outras são implementações puramente gerenciadas. Para obter mais informações, consulte Serviços Criptográficos.

Exemplo de App.config

Este exemplo demonstra como ativar/desativar a criptografia da seção connectionStrings em um arquivo app.config para um aplicativo do Windows. Nesse exemplo, o procedimento utiliza o nome do aplicativo como um argumento, por exemplo, “MyApplication.exe”. O arquivo app.config será então criptografado e copiado para a pasta que contém o executável com o nome "MyApplication.exe.config".

Observação

A cadeia de conexão somente pode ser descriptografada no computador no qual foi criptografada.

O código usa o método OpenExeConfiguration para abrir o arquivo app.config para edição, e o método GetSection retorna a seção connectionStrings. O código em seguida verifica a propriedade IsProtected, chamando ProtectSection para criptografar a seção se não estiver criptografada. O método UnprotectSection é chamado para descriptografar a seção. O método Save conclui a operação e salva as alterações.

Observação

Você deve definir uma referência a System.Configuration.dll em seu projeto para que o código seja executado.

static void ToggleConfigEncryption(string exeFile)
{
    // Get the application path needed to obtain
    // the application configuration file.

    // Takes the executable file name without the
    // .config extension.
    var exePath = exeFile.Replace(".config", "");

    try
    {
        // Open the configuration file and retrieve
        // the connectionStrings section.
        Configuration config = ConfigurationManager.
            OpenExeConfiguration(exePath);

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

        if (section != null)
        {
            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);
    }
}
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

Exemplo de Web.config

Esse exemplo usa o método OpenWebConfiguration do WebConfigurationManager. Observe que, nesse caso, você pode fornecer o caminho relativo para o arquivo Web.config usando um til. O código exige uma referência à classe System.Web.Configuration.

static void ToggleWebEncrypt()
{
    // Open the Web.config file.
    Configuration config = WebConfigurationManager.
        OpenWebConfiguration("~");

    // Get the connectionStrings section.
    var 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();
}
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

Para saber mais sobre como proteger aplicativos ASP.NET, confira Proteger sites ASP.NET.

Confira também