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

A incorporação de cadeias de conexão no código do seu aplicativo pode levar a 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 visualizadas usando 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 do aplicativo

Os arquivos de configuração do aplicativo contêm configurações que são específicas para um aplicativo específico. 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 connectionStrings

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

O fragmento do 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 invariante do provedor de dados do .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>  

Nota

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

Usando arquivos de configuração externos

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 é então referenciado pelo arquivo de configuração principal. Armazenar a 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 ASP.NET padrão é reiniciar um domínio de aplicativo quando os arquivos de configuração são modificados, o que resulta na 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 a ASP.NET; eles também podem ser usados por aplicativos do Windows. Além disso, a segurança e as permissões de acesso a arquivos 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 requer codificação especial.

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

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

No arquivo de configuração do aplicativo principal, use o atributo configSource para especificar o nome e o local totalmente qualificados 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 para simplificar a System.Configuration recuperação de cadeias de conexão de arquivos de configuração em tempo de execução. Você pode recuperar programaticamente uma cadeia de conexão por nome ou por nome de provedor.

Nota

O arquivo machine.config também contém uma seção connectionStrings, que contém cadeias de conexão usadas pelo Visual Studio. Ao recuperar cadeias de conexão por nome de 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, para que apenas as cadeias de conexão definidas no arquivo app.config local sejam 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 preterido ConfigurationSettings. WebConfigurationManager é usado para trabalhar com ASP.NET arquivos de configuração. Ele foi projetado para trabalhar com arquivos de configuração em um servidor Web e permite acesso programático a seções de arquivos de configuração, como system.web.

Nota

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

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

Property Description
Name O nome da cadeia de conexão. Mapeia para o atributo name .
ProviderName O nome do provedor totalmente qualificado. Mapeia para o atributo providerName .
ConnectionString A cadeia de conexão. Mapeia para o atributo connectionString .

Exemplo: Listando todas as cadeias de conexão

Este exemplo itera através do ConnectionStringSettingsCollection e exibe as ConnectionStringSettings.Namepropriedades , ConnectionStringSettings.ProviderNamee na ConnectionStringSettings.ConnectionString janela do console.

Nota

System.Configuration.dll não está incluído em todos os tipos de projeto, e talvez seja necessário definir uma referência a ele para usar as classes de configuração. O nome e o local de um determinado arquivo de configuração de aplicativo variam de acordo com o 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 ConnectionStringSettings objeto, combinando o parâmetro de entrada fornecido com o ConnectionStrings nome. Se nenhum nome correspondente for encontrado, 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 invariante do provedor no formato System.Data.ProviderName. O código itera através do ConnectionStringSettingsCollection e retorna a cadeia de conexão para o primeiro ProviderName encontrado. Se o nome do provedor não for encontrado, 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 a configuração protegida

ASP.NET 2.0 introduziu um novo recurso, chamado configuração protegida, que permite criptografar informações confidenciais em um arquivo de configuração. Embora projetada principalmente para ASP.NET, a configuração protegida também pode ser usada para criptografar seções de arquivos de configuração em aplicativos do Windows. Para obter uma descrição detalhada dos recursos de configuração protegida, consulte 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 que ele foi criptografado. O configProtectionProvider especifica o provedor de configuração protegido usado para criptografar e descriptografar as cadeias de conexão. A seção EncryptedData contém o texto cifrado.

<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 o CipherValue e disponibilizá-lo para seu aplicativo. Não precisa de escrever nenhum código adicional para gerir o processo de desencriptação.

Provedores de configuração protegidos

Os provedores de configuração protegidos 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 protegidos 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>  

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

Provider Description
RsaProtectedConfigurationProvider Utiliza o algoritmo de encriptação RSA para encriptar e desencriptar dados. O algoritmo RSA pode ser usado para criptografia de chave pública e assinaturas digitais. Também é conhecida como "chave pública" ou criptografia assimétrica porque emprega duas chaves diferentes. Você pode usar a ASP.NET Ferramenta de Registro do IIS (Aspnet_regiis.exe) para criptografar seções em um arquivo Web.config e gerenciar as chaves de criptografia. ASP.NET desencripta o ficheiro de configuração quando processa o ficheiro. A identidade do aplicativo ASP.NET deve ter acesso de leitura à chave de criptografia usada para criptografar e descriptografar as seções criptografadas.
DpapiProtectedConfigurationProvider Usa a API de Proteção de Dados do Windows (DPAPI) para criptografar seções de configuração. Ele usa os serviços de criptografia internos do Windows e pode ser configurado para proteção específica da máquina ou da conta do usuário. A proteção específica da máquina é útil para vários aplicativos no mesmo servidor que precisam compartilhar informações. A proteção específica da conta de usuário pode ser usada com serviços executados com uma identidade de usuário específica, como um ambiente de hospedagem compartilhada. Cada aplicativo é executado sob uma identidade separada que restringe o acesso a recursos como arquivos e bancos de dados.

Ambos os fornecedores oferecem uma forte encriptação de dados. No entanto, se você estiver planejando usar o mesmo arquivo de configuração criptografado em vários servidores, como uma Web farm, somente o RsaProtectedConfigurationProvider permitirá exportar as chaves de criptografia usadas para criptografar os dados e importá-los em outro servidor. Para obter mais informações, consulte Importando e exportando contêineres de chave RSA de configuração protegida.

Usando as classes de configuração

O System.Configuration namespace fornece classes para trabalhar com definições de configuração programaticamente. A ConfigurationManager classe fornece acesso a arquivos de configuração de máquina, aplicativo e usuário. Se você estiver criando um aplicativo ASP.NET, poderá usar a WebConfigurationManager classe, que fornece a mesma funcionalidade e, ao mesmo tempo, permite que você acesse configurações exclusivas para ASP.NET aplicativos, como as encontradas em <system.web>.

Nota

O System.Security.Cryptography namespace contém classes que fornecem opções adicionais para criptografar e descriptografar dados. Use essas classes se precisar de serviços criptográficos que não estão disponíveis usando a configuração protegida. Algumas dessas classes são wrappers para a 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 alternar a criptografia da seção connectionStrings em um arquivo app.config para um aplicativo do Windows. Neste exemplo, o procedimento usa o nome do aplicativo como um argumento, por exemplo, "MyApplication.exe". O ficheiro app.config será então encriptado e copiado para a pasta que contém o executável sob o nome de "MyApplication.exe.config".

Nota

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

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

Nota

Você deve definir uma referência para 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 Web.config

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

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 obter mais informações sobre como proteger aplicativos ASP.NET, consulte Protegendo ASP.NET sites.

Consulte também