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.
Importante
A Microsoft recomenda usar o fluxo de autenticação mais seguro disponível. Se você estiver se conectando ao SQL do Azure, as Identidades gerenciadas para recursos do Azure é o método de autenticação recomendado.
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 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 cenários em que não se conhecem elementos da cadeia de conexão com antecedência ou quando não se deseja salvar informações confidenciais em um arquivo de configuração. Para obter mais informações, confira Construtores de cadeias de conexão.
Usar arquivos de configuração externa
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 depois que o aplicativo é implantado. 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>
Recuperar cadeias de conexão em tempo de execução
O .NET Framework 2.0 introduziu novas classes no System.Configuration namespace 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.
Trabalhar 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 a classe ConfigurationSettings obsoleta. 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 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: listar 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
O 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 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: recuperar 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: recuperar uma cadeia de conexão por nome do 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
Criptografar seções de arquivos 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.
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 seu 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 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>
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.
Usar 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.
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 é então criptografado e copiado para a pasta que contém o executável com o nome "MyApplication.exe.config".
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. (A cadeia de conexão só pode ser descriptografada no computador em que foi criptografada.) O método Save conclui a operação e salva as alterações.
Você deve adicionar uma referência a System.Configuration.dll
em seu projeto para que o código seja executado.
Importante
A Microsoft recomenda usar o fluxo de autenticação mais seguro disponível. Se você estiver se conectando ao SQL do Azure, as Identidades gerenciadas para recursos do Azure é o método de autenticação recomendado.
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
. 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.