Stringhe di connessione e file di configurazione (ADO.NET)

Se le stringhe di connessione vengono incorporate nel codice dell'applicazione, è possibile che si verifichino vulnerabilità della sicurezza e problemi di manutenzione. Le stringhe di connessione non crittografate compilate nel codice sorgente di un'applicazione possono essere visualizzate tramite lo strumento Ildasm.exe (disassemblatore MSIL). Inoltre, se la stringa di connessione viene modificata, è necessario ricompilare l'applicazione. Per questi motivi, si consiglia di archiviare le stringhe di connessione in un file di configurazione dell'applicazione.

Utilizzo dei file di configurazione delle applicazioni

I file di configurazione delle applicazioni contengono impostazioni specifiche di una determinata applicazione. Ad esempio, un'applicazione ASP.NET può includere uno o più file web.config, mentre un'applicazione Windows può includere un file app.config facoltativo. I file di configurazione condividono elementi comuni, anche se il nome e il percorso variano a seconda dell'host dell'applicazione.

Sezione connectionStrings

Le stringhe di connessione possono essere archiviate come coppie chiave/valore nella sezione connectionStrings dell'elemento configuration di un file di configurazione dell'applicazione. Gli elementi figlio includono add, clear e remove.

Nel frammento di file di configurazione seguente sono illustrati lo schema e la sintassi per l'archiviazione di una stringa di connessione. L'attributo name corrisponde al nome specificato per identificare in modo univoco una connessione, in modo che possa essere recuperato in fase di esecuzione. L'attributo providerName è il nome invariabile del provider di dati .NET Framework, registrato nel file 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

È possibile salvare parte di una stringa di connessione in un file di configurazione e utilizzare la classe DbConnectionStringBuilder per completarlo in fase di esecuzione.Questa funzione è utile nelle situazioni in cui non si conoscono in anticipo gli elementi della stringa di connessione o quando non si desidera salvare informazioni sensibili in un file di configurazione.Per ulteriori informazioni, vedere Compilatori di stringhe di connessione (ADO.NET).

Utilizzo di file di configurazione esterni

I file di configurazione esterni sono file distinti che contengono un frammento di un file di configurazione costituito da un'unica sezione. Al file di configurazione esterno viene quindi fatto riferimento dal file di configurazione principale. L'archiviazione della sezione connectionStrings in un file fisicamente distinto risulta utile nelle situazioni in cui le stringhe di connessione potrebbero essere modificate dopo la distribuzione dell'applicazione. Ad esempio, il comportamento ASP.NET standard prevede il riavvio di un dominio di applicazione quando i file di configurazione vengono modificati, con la conseguenza che le informazioni sullo stato vanno perse. Tuttavia, la modifica di un file di configurazione esterno non provoca un riavvio dell'applicazione. Oltre che in ASP.NET, i file di configurazione esterni possono essere utilizzati anche nelle applicazioni Windows. È possibile inoltre utilizzare la sicurezza e le autorizzazioni di accesso ai file per limitare l'accesso ai file di configurazione esterni. L'utilizzo di file di configurazione esterni in fase di esecuzione è trasparente e non richiede codice speciale.

Per archiviare le stringhe di connessione in un file di configurazione esterno, creare un file distinto che contiene solo la sezione connectionStrings. Non includere altri elementi, sezioni o attributi. In questo esempio è illustrata la sintassi di un file di configurazione esterno.

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

Nel file di configurazione principale dell'applicazione utilizzare l'attributo configSource per specificare il nome completo e il percorso del file esterno. In questo esempio si fa riferimento a un file di configurazione esterno denominato connections.config.

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

Recupero delle stringhe di connessione in fase di esecuzione

In .NET Framework 2.0 sono state introdotte nuove classi nello spazio dei nomi System.Configuration per semplificare il recupero delle stringhe di connessione dai file di configurazione in fase di esecuzione. È possibile recuperare una stringa di connessione a livello di codice in base al nome o al nome del provider.

NotaNota

Il file machine.config include anche una sezione connectionStrings contenente le stringhe di connessione utilizzate da Visual Studio.Se le stringhe di connessione vengono recuperate in base al nome del provider dal file app.config in un'applicazione Windows, vengono caricate dapprima le stringhe di connessione presenti in machine.config e quindi le voci di app.config.L'aggiunta di clear immediatamente dopo l'elemento connectionStrings consente di rimuovere tutti i riferimenti ereditati dalla struttura dati in memoria, in modo che vengano considerate solo le stringhe di connessione definite nel file app.config locale.

Utilizzo delle classi di configurazione

A partire da .NET Framework 2.0, quando si utilizzano i file di configurazione nel computer locale, viene utilizzato ConfigurationManager al posto dell'oggetto ConfigurationSettings deprecato. Per i file di configurazione di ASP.NET, viene utilizzato WebConfigurationManager, progettato per essere utilizzato con i file di configurazione in un server Web, che consente l'accesso a livello di codice alle sezioni del file di configurazione come system.web.

NotaNota

L'accesso ai file di configurazione in fase di esecuzione richiede la concessione di autorizzazioni al chiamante. Le autorizzazioni necessarie dipendono dal tipo di applicazione, dal file di configurazione e dal percorso.Per ulteriori informazioni, vedere Utilizzo delle classi di configurazione e WebConfigurationManager per le applicazioni ASP.NET e ConfigurationManager per le applicazioni Windows.

È possibile utilizzare ConnectionStringSettingsCollection per recuperare le stringhe di connessione dai file di configurazione dell'applicazione. Contiene una raccolta di oggetti ConnectionStringSettings ognuno dei quali rappresenta una singola voce della sezione connectionStrings. Le proprietà sono mappate ad attributi di stringa di connessione, consentendo di recuperare una stringa di connessione in base al nome o al nome del provider.

Proprietà

Descrizione

Name

Nome della stringa di connessione. È mappata all'attributo name.

ProviderName

Nome completo del provider. È mappata all'attributo providerName.

ConnectionString

Stringa di connessione. È mappata all'attributo connectionString.

Esempio: elenco di tutte le stringhe di connessione

In questo esempio viene scorsa la raccolta ConnectionStringSettings e vengono visualizzate le proprietà Name, ProviderName e ConnectionString nella finestra della console.

NotaNota

System.Configuration.dll non è incluso in tutti i tipi di progetto e potrebbe essere necessario impostare un riferimento a questo file per utilizzare le classi di configurazione.Il nome e il percorso di un determinato file di configurazione dell'applicazione variano in base al tipo di applicazione e al processo di hosting.

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);
            }
        }
    }
}

Esempio: recupero di una stringa di connessione in base al nome

In questo esempio viene illustrato come recuperare una stringa di connessione da un file di configurazione specificandone il nome. Nel codice viene creato un oggetto ConnectionStringSettings e il parametro di input specificato viene associato al nome ConnectionStrings. Se non viene trovato alcun nome corrispondente, la funzione restituisce null (Nothing in 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;
}

Esempio: recupero di una stringa di connessione in base al nome del provider

In questo esempio viene illustrato come recuperare una stringa di connessione specificando il nome invariabile del provider nel formato System.Data.ProviderName. Il codice consente di scorrere ConnectionStringSettingsCollection e restituisce la stringa di connessione per il primo ProviderName trovato. Se il nome del provider non viene trovato, la funzione restituisce null (Nothing in 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;
}

Crittografia di sezioni dei file di configurazione tramite configurazione protetta

In ASP.NET 2.0 è stata introdotta una nuova funzionalità, denominata configurazione protetta, che consente di crittografare le informazioni riservate in un file di configurazione. Sebbene sia stata progettata principalmente per ASP.NET, questa funzionalità può essere utilizzata anche per crittografare sezioni dei file di configurazione nelle applicazioni Windows. Per una descrizione dettagliata delle funzionalità di configurazione protetta, vedere Crittografia delle informazioni di configurazione tramite la configurazione protetta.

Nel frammento di file di configurazione seguente è illustrata la sezione connectionStrings dopo la crittografia. Nella sezione configProtectionProvider è specificato il provider di configurazione protetta utilizzato per crittografare e decrittografare le stringhe di connessione. La sezione EncryptedData contiene il testo crittografato.

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

Quando la stringa di connessione crittografata viene recuperata in fase di esecuzione, in .NET Framework viene utilizzato il provider specificato per decrittografare CipherValue e renderlo disponibile per l'applicazione. Non è necessario scrivere codice aggiuntivo per gestire il processo di decrittografia.

Provider di configurazione protetta

I provider di configurazione protetta sono registrati nella sezione configProtectedData del file machine.config nel computer locale, come illustrato nel frammento seguente, in cui sono indicati i due provider di configurazione protetta disponibili in .NET Framework. I valori mostrati sono stati troncati per facilitarne la lettura.

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

È possibile configurare altri provider di configurazione protetta aggiungendoli al file machine.config. È inoltre possibile creare un proprio provider di configurazione protetta ereditando dalla classe di base astratta ProtectedConfigurationProvider. Nella tabella seguente sono descritti i due file di configurazione inclusi in .NET Framework.

Provider

Descrizione

RSAProtectedConfigurationProvider

Utilizza l'algoritmo di crittografia RSA per crittografare e decrittografare i dati. L'algoritmo RSA può essere utilizzato per la crittografia a chiave pubblica e per le firme digitali. È anche noto come crittografia a "chiave pubblica" o asimmetrica perché impiega due chiavi diverse. È possibile utilizzare Strumento di ASP.NET per la registrazione di IIS (Aspnet_regiis.exe) per crittografare le sezioni di un file Web.config e gestire le chiavi di crittografia. In ASP.NET il file di configurazione viene decrittografato al momento dell'elaborazione. L'identità dell'applicazione ASP.NET deve disporre di accesso in lettura alla chiave di crittografia utilizzata per crittografare e decrittografare le sezioni crittografate.

DPAPIProtectedConfigurationProvider

Utilizza DPAPI (Data Protection API) di Windows per crittografare le sezioni di configurazione. Utilizza i servizi di crittografia incorporati di Windows e può essere configurato per la protezione specifica del computer o specifica dell'account utente. La protezione specifica del computer risulta utile quando più applicazioni sullo stesso server devono condividere informazioni. La protezione specifica dell'account utente può essere utilizzata con i servizi eseguiti con un'identità utente specifica, ad esempio un ambiente di hosting condiviso. Ogni applicazione viene eseguita con un'identità distinta, limitando l'accesso a risorse quali file e database.

Entrambi i provider offrono una crittografia avanzata per i dati. Se tuttavia si prevede di utilizzare lo stesso file di configurazione crittografato in più server, ad esempio una Web farm, solo RsaProtectedConfigurationProvider consente di esportare le chiavi di crittografia utilizzate per crittografare i dati e importarle in un altro server. Per ulteriori informazioni, vedere Importazione ed esportazione di contenitori di chiavi RSA della configurazione protetta.

Utilizzo delle classi di configurazione

Lo spazio dei nomi System.Configuration fornisce classi per specificare le impostazioni di configurazione a livello di codice. La classe ConfigurationManager fornisce accesso a file di configurazione del computer, dell'applicazione e dell'utente. Se si crea un'applicazione ASP.NET, è possibile utilizzare la classe WebConfigurationManager, che fornisce la stessa funzionalità consentendo anche di accedere a impostazioni che sono univoche per le applicazioni ASP.NET, ad esempio quelle disponibili in <system.web>.

NotaNota

Lo spazio dei nomi System.Security.Cryptography contiene classi che forniscono opzioni aggiuntive per la crittografia e la decrittografia dei dati.Utilizzare queste classi se si richiedono servizi di crittografia che non sono disponibili tramite configurazione protetta.In alcuni casi si tratta di wrapper presenti nelle CryptoAPI di Microsoft non gestite, in altri semplicemente di implementazioni gestite.Per ulteriori informazioni, vedere Cryptographic Services.

Esempio di App.config

In questo esempio viene illustrato come attivare e disattivare la crittografia della sezione connectionStrings in un file app.config per un'applicazione Windows. La procedura assume il nome dell'applicazione come argomento, ad esempio "MyApplication.exe". Il file app.config verrà quindi crittografato e copiato nella cartella che contiene il file eseguibile con il nome "MyApplication.exe.config".

NotaNota

La stringa di connessione può essere decrittografata solo nel computer in cui è stata crittografata.

Nel codice viene utilizzato il metodo OpenExeConfiguration per aprire il file app.config per la modifica, mentre il metodo GetSection restituisce la sezione connectionStrings. Viene quindi controllata la proprietà IsProtected, con una chiamata a ProtectSection per crittografare la sezione, se non è crittografata. Il metodo UnProtectSection() viene richiamato per decrittografare la sezione. Il metodo Save completa l'operazione e salva le modifiche.

NotaNota

È necessario impostare un riferimento a System.Configuration.dll nel progetto affinché il codice venga eseguito.

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);
    }
}

Esempio di Web.config

In questo esempio viene utilizzato il metodo OpenWebConfiguration di WebConfigurationManager. Si noti che in questo caso è possibile specificare il percorso relativo del file Web.config utilizzando una tilde. Il codice richiede un riferimento alla classe 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();
}

Per ulteriori informazioni sulla protezione di applicazioni ASP.NET, vedere Sicurezza dei siti Web ASP.NET e ASP.NET 2.0 Security Practices at a Glance sul sito Web ASP.NET Developer Center (informazioni in lingua inglese).

Vedere anche

Concetti

Compilatori di stringhe di connessione (ADO.NET)

Protezione delle informazioni di connessione (ADO.NET)

Utilizzo delle classi di configurazione

Altre risorse

File di configurazione

Amministrazione di siti Web ASP.NET