Verbindungszeichenfolgen und Konfigurationsdateien

Das Einbetten von Verbindungszeichenfolgen in den Code Ihrer Anwendung kann zu Sicherheitslücken und Wartungsproblemen führen. Unverschlüsselte Verbindungszeichenfolgen, die in den Quellcode einer Anwendung kompiliert wurden, können mit dem Tool Ildasm.exe (IL Disassembler) angezeigt werden. Hinzu kommt, dass die Anwendung neu kompiliert werden muss, wenn sich die Verbindungszeichenfolge irgendwann einmal ändert. Aus diesen Gründen empfehlen wir, Verbindungszeichenfolgen in einer Anwendungskonfigurationsdatei zu speichern.

Arbeiten mit Anwendungskonfigurationsdateien

Anwendungskonfigurationsdateien enthalten anwendungsspezifische Einstellungen. Eine ASP.NET-Anwendung kann beispielsweise mindestens eine web.config-Datei enthalten, und eine Windows-Anwendung kann eine optionale app.config-Datei enthalten. Konfigurationsdateien haben etliche Elemente gemein, auch wenn sich der Name und der Speicherort der Konfigurationsdateien abhängig vom jeweiligen Host der Anwendung ändert.

Der "connectionStrings"-Abschnitt

Verbindungszeichenfolgen können als Schlüssel/Wert-Paare im Abschnitt connectionStrings des configuration-Elements einer Anwendungskonfigurationsdatei gespeichert werden. Zu den untergeordneten Elementen gehören add, clear und remove.

Das folgende Konfigurationsdateifragment zeigt das Schema und die Syntax für das Speichern einer Verbindungszeichenfolge. Das name-Attribut ist ein Name, den Sie zum eindeutigen Identifizieren einer Verbindungszeichenfolge angeben, damit diese zur Laufzeit abgerufen werden kann. providerName ist der unveränderliche Name des .NET Framework-Datenanbieters, der in der Datei „machine.config“ registriert ist.

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

Hinweis

Sie können einen Teil der Verbindungszeichenfolge in einer Konfigurationsdatei speichern und zur Vervollständigung zur Laufzeit die DbConnectionStringBuilder-Klasse verwenden. Diese Vorgehensweise empfiehlt sich in Szenarien, in denen Ihnen die Elemente der Verbindungszeichenfolge vorab nicht bekannt sind oder wenn Sie sicherheitsrelevante Informationen nicht in einer Konfigurationsdatei speichern möchten. Weitere Informationen finden Sie in Connection String Builders (Verbindungszeichenfolgengeneratoren).

Verwenden externer Konfigurationsdateien

Externe Konfigurationsdateien sind separate Dateien, die ein aus einem einzigen Abschnitt bestehendes Fragment einer Konfigurationsdatei enthalten. Auf die externe Konfigurationsdatei wird dann von der Hauptkonfigurationsdatei verwiesen. Das Speichern des Abschnitts connectionStrings in einer separaten Datei empfiehlt sich, wenn die Verbindungszeichenfolgen auch nach der Bereitstellung der Anwendung noch geändert werden können. ASP.NET verhält sich z. B. standardmäßig so, dass nach Änderungen an Konfigurationsdateien eine Anwendung neu gestartet wird, wodurch Statusinformationen verloren gehen. Änderungen an einer externen Konfigurationsdatei hingegen führen nicht zum Neustart der Anwendung. Externe Konfigurationsdateien sind nicht auf ASP.NET beschränkt und können auch von Windows-Anwendungen verwendet werden. Außerdem kann der Zugriff auf externe Konfigurationsdateien auch durch Dateizugriffssicherheit und Berechtigungen eingeschränkt werden. Der Einsatz externer Konfigurationsdateien zur Laufzeit ist transparent und erfordert keine besondere Codierung.

Wenn Sie Verbindungszeichenfolgen in einer externen Konfigurationsdatei speichern möchten, erstellen Sie eine separate Datei, die ausschließlich den connectionStrings-Abschnitt enthält. Nehmen Sie in diese Datei keine zusätzlichen Elemente, Abschnitte oder Attribute auf. Das folgende Beispiel zeigt die Syntax für eine externe Konfigurationsdatei.

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

Verwenden Sie in der Hauptkonfigurationsdatei der Anwendung das configSource-Attribut, um den vollqualifizierten Namen und den Speicherort der externen Datei anzugeben. Das folgende Beispiel verweist auf eine Konfigurationsdatei mit dem Namen connections.config.

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

Abrufen von Verbindungszeichenfolgen zur Laufzeit

Mit .NET Framework 2.0 wurden neue Klassen im System.Configuration-Namespace eingeführt, um das Abrufen von Verbindungszeichenfolgen aus Konfigurationsdateien zur Laufzeit zu vereinfachen. Sie können programmgesteuert eine Verbindungszeichenfolge nach Namen oder Anbieternamen abrufen.

Hinweis

Die Datei machine.config enthält auch einen connectionStrings-Abschnitt, der von Visual Studio verwendete Verbindungszeichenfolgen enthält. Beim Abrufen von Verbindungszeichenfolgen anhand des Anbieternamens aus der Datei app.config in einer Windows-Anwendung werden zuerst die in machine.config vorhandenen Verbindungszeichenfolgen und dann die in app.config vorhandenen Verbindungszeichenfolgen geladen. Wenn unmittelbar hinter dem connectionStrings-Element clear hinzugefügt wird, werden alle geerbten Verweise aus der Datenstruktur im Arbeitsspeicher entfernt, sodass nur die in der lokalen Datei app.config definierten Verbindungszeichenfolgen berücksichtigt werden.

Arbeiten mit den Konfigurationsklassen

Ab .NET Framework 2.0 wird bei der Arbeit mit Konfigurationsdateien auf dem lokalen Computer ConfigurationManager verwendet, um ConfigurationSettings zu ersetzen. Für die Arbeit mit ASP.NET-Konfigurationsdateien kommt der WebConfigurationManager zum Einsatz. Er wurde für die Verwendung mit den auf einem Webserver befindlichen Konfigurationsdateien entwickelt und erlaubt den programmgesteuerten Zugriff auf Konfigurationsdateiabschnitte, wie z.B. system.web.

Hinweis

Wenn ein Aufrufer zur Laufzeit auf Konfigurationsdateien zugreifen können soll, benötigt er Berechtigungen. Welche Berechtigungen notwendig sind, hängt von der Art der Anwendung, der Konfigurationsdatei und dem Speicherort ab. Weitere Informationen finden Sie unter Verwenden der Konfigurationsklassen und WebConfigurationManager (für ASP.NET-Anwendungen) und unter ConfigurationManager (für Windows-Anwendungen).

Zum Abrufen von Verbindungszeichenfolgen aus Anwendungskonfigurationsdateien können Sie die ConnectionStringSettingsCollection verwenden. Sie enthält eine Auflistung von ConnectionStringSettings-Objekten, wobei jedes Objekt für einen einzelnen Eintrag im connectionStrings-Abschnitt steht. Ihre Eigenschaften werden entsprechenden Verbindungszeichenfolgenattributen zugeordnet, sodass es möglich ist, Verbindungszeichenfolgen nach dem Namen oder dem Anbieternamen abzurufen.

Eigenschaft BESCHREIBUNG
Name Name der Verbindungszeichenfolge: Wird dem name-Attribut zugeordnet.
ProviderName Vollqualifizierter Anbietername: Wird dem providerName-Attribut zugeordnet.
ConnectionString Verbindungszeichenfolge. Wird dem connectionString-Attribut zugeordnet.

Beispiel: Auflisten aller Verbindungszeichenfolgen

Dieses Beispiel iteriert durch ConnectionStringSettingsCollection und zeigt die Eigenschaften ConnectionStringSettings.Name, ConnectionStringSettings.ProviderName und ConnectionStringSettings.ConnectionString im Konsolenfenster an.

Hinweis

<legacyBold>System.Configuration.dll</legacyBold> ist nicht in allen Projekttypen enthalten, sodass Sie u. U. einen Verweis einfügen müssen, um die Konfigurationsklassen zu verwenden. Wie die jeweilige Anwendungskonfigurationsdatei heißt und wo sie gespeichert ist, hängt von der Art der Anwendung und dem Hostingprozess ab.

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

Beispiel: Abrufen einer Verbindungszeichenfolge nach dem Namen

In diesem Beispiel wird gezeigt, wie eine Verbindungszeichenfolge aus einer Konfigurationsdatei durch Angabe ihres Namens abgerufen werden kann. Der Code erstellt ein ConnectionStringSettings-Objekt, das den bereitgestellten Eingabeparameter mit dem ConnectionStrings-Namen abgleicht. Wird kein übereinstimmender Name gefunden, gibt die Funktion null (Nothing in Visual Basic) zurück.

// 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

Beispiel: Abrufen einer Verbindungszeichenfolge nach dem Anbieternamen

In diesem Beispiel wird gezeigt, wie eine Verbindungszeichenfolge durch Angabe des unveränderlichen Anbieternamens im Format System.Daten.ProviderName abgerufen werden kann. Der Code durchläuft die ConnectionStringSettingsCollection und gibt die Verbindungszeichenfolge für den ersten gefundenen ProviderName-Eintrag zurück. Wird kein Anbietername gefunden, gibt die Funktion null (Nothing in Visual Basic) zurück.

// 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

Verschlüsseln von Konfigurationsdateiabschnitten mit geschützter Konfiguration

In ASP.NET 2.0 wurde mit der geschützten Konfiguration ein neues Feature eingeführt, mit dem Sie sicherheitsrelevante Informationen in einer Konfigurationsdatei verschlüsseln können. Die geschützte Konfiguration wurde zwar primär für ASP.NET entwickelt, sie kann aber auch zum Verschlüsseln von Konfigurationsdateiabschnitten in Windows-Anwendungen verwendet werden. Eine ausführliche Beschreibung der Funktionen der geschützten Konfiguration finden Sie unter Verschlüsseln von Konfigurationsinformationen mithilfe der geschützten Konfiguration.

Das folgende Konfigurationsdateifragment zeigt den connectionStrings-Abschnitt nach der Verschlüsselung. configProtectionProvider gibt den Anbieter für die geschützte Konfiguration an, der zum Verschlüsseln und Entschlüsseln der Verbindungszeichenfolgen verwendet wird. Der EncryptedData-Abschnitt enthält den Verschlüsselungstext.

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

Wenn die verschlüsselte Verbindungszeichenfolge zur Laufzeit abgerufen wird, verwendet .NET Framework den angegebenen Anbieter, um den CipherValue zu entschlüsseln und ihn für Ihre Anwendung zur Verfügung zu stellen. Sie müssen für die Verwaltung des Entschlüsselungsprozesses keinen zusätzlichen Code schreiben.

Anbieter für die geschützte Konfiguration

Die Anbieter für die geschützte Konfiguration werden im configProtectedData-Abschnitt der Datei machine.config auf dem lokalen Computer registriert, wie dies im folgenden Fragment dargestellt ist. Das Fragment enthält die beiden Anbieter für die geschützte Konfiguration in .NET Framework. Die hier gezeigten Werte wurden aus Gründen der besseren Lesbarkeit gekürzt.

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

Sie können zusätzliche Anbieter für die geschützte Konfiguration konfigurieren, indem Sie sie der Datei machine.config hinzufügen. Sie können auch einen eigenen Anbieter für die geschützte Konfiguration erstellen, indem Sie von der abstrakten Basisklasse ProtectedConfigurationProvider erben. In der folgenden Tabelle werden die zwei in .NET Framework enthaltenen Anbieter für die geschützte Konfiguration beschrieben.

Anbieter Beschreibung
RsaProtectedConfigurationProvider Verwendet zum Verschlüsseln und Entschlüsseln der Daten den RSA-Verschlüsselungsalgorithmus. Der RSA-Algorithmus kann sowohl für die Verschlüsselung mit öffentlichem Schlüssel als auch für digitale Signaturen verwendet werden. Er wird auch als "öffentlicher Schlüssel" oder asymmetrische Verschlüsselung bezeichnet, da bei dieser Art der Verschlüsselung zwei verschiedene Schlüssel eingesetzt werden. Mit dem ASP.NET IIS-Registrierungstool (Aspnet_regiis.exe) können Sie die Abschnitte in einer Web.config-Datei verschlüsseln und die Verschlüsselungsschlüssel verwalten. ASP.NET entschlüsselt die Konfigurationsdatei, wenn die Datei verarbeitet wird. Die Identität der ASP.NET-Anwendung muss berechtigt sein, den Verschlüsselungsschlüssel zu lesen, mit dem die verschlüsselten Abschnitte verschlüsselt und entschlüsselt werden.
DpapiProtectedConfigurationProvider Verwendet zum Verschlüsseln der Konfigurationsabschnitte die Windows-Datenschutz-API (DPAPI). Die DPAPI verwendet die in Windows integrierten Kryptografiedienste, und sie kann für den computerspezifischen oder den benutzerkontospezifischen Schutz konfiguriert werden. Der computerspezifische Schutz bietet sich an, wenn auf demselben Server mehrere Anwendungen vorhanden sind, die Informationen gemeinsam nutzen müssen. Die Verwendung des benutzerkontospezifischen Schutzes empfiehlt sich bei Diensten, die mit einer bestimmten Benutzeridentität, z. B. einer freigegebenen gehosteten Umgebung, ausgeführt werden. Jede Anwendung wird unter einer separaten Identität ausgeführt, was den Zugriff auf Ressourcen, wie z. B. Dateien und Datenbanken, einschränkt.

Beide Anbieter bieten eine starke Verschlüsselung der Daten. Wenn Sie aber beabsichtigen, ein und dieselbe verschlüsselte Konfigurationsdatei auf mehreren Servern, z. B. in einer Webfarm, zu verwenden, müssen Sie den RsaProtectedConfigurationProvider verwenden, da nur er die Möglichkeit bietet, die zum Verschlüsseln der Daten verwendeten Verschlüsselungsschlüssel zu exportieren und sie auf einem anderen Server zu importieren. Weitere Informationen finden Sie unter Importieren und Exportieren von RSA-Schlüsselcontainern mit geschützter Konfiguration.

Verwenden der Konfigurationsklassen

Der System.Configuration-Namespace stellt Klassen zum programmgesteuerten Arbeiten mit Konfigurationseinstellungen bereit. Die ConfigurationManager-Klasse ermöglicht den Zugriff auf Computer-, Anwendungs- und Benutzerkonfigurationsdateien. Beim Erstellen einer ASP.NET-Anwendung können Sie die WebConfigurationManager-Klasse verwenden, die dieselbe Funktionalität bietet, Ihnen gleichzeitig aber auch den Zugriff auf Einstellungen erlaubt, die es so nur in ASP.NET-Anwendungen gibt, beispielsweise die Einstellungen in <system.web>.

Hinweis

Der System.Security.Cryptography-Namespace enthält Klassen, die zusätzliche Optionen zum Verschlüsseln und Entschlüsseln von Daten bereitstellen. Verwenden Sie diese Klassen, wenn Sie Kryptografiedienste benötigen, die bei Verwendung der geschützten Konfiguration nicht verfügbar sind. Einige dieser Klassen sind Wrapper für die nicht verwaltete Microsoft CryptoAPI, während es sich bei anderen Klassen um verwaltete Implementierungen handelt. Weitere Informationen finden Sie unter Kryptografiedienste.

"App.config"-Beispiel

In diesem Beispiel wird gezeigt, wie Sie die Verschlüsselung des Abschnitts connectionStrings in der Datei app.config einer Windows-Anwendung aktivieren und deaktivieren können. In diesem Beispiel übernimmt die Prozedur den Namen der Anwendung, z. B. MyApplication.exe, als Argument. Die Datei app.config wird dann verschlüsselt und in den Ordner kopiert, der die ausführbare Datei mit dem Namen „MyApplication.exe.config“ enthält.

Hinweis

Die Verbindungszeichenfolge kann nur auf dem Computer entschlüsselt werden, auf dem sie verschlüsselt wurde.

Der Code öffnet die Datei app.config mit der OpenExeConfiguration-Methode, um sie bearbeiten zu können, und die GetSection-Methode gibt den connectionStrings-Abschnitt zurück. Der Code überprüft nun die IsProtected-Eigenschaft, indem er die ProtectSection-Methode aufruft, um den Abschnitt zu verschlüsseln, sofern dieser nicht bereits verschlüsselt ist. Die UnprotectSection-Methode wird aufgerufen, um den Abschnitt zu entschlüsseln. Die Save-Methode schließt den Vorgang ab und speichert die Änderungen.

Hinweis

Sie müssen in Ihrem Projekt einen Verweis auf System.Configuration.dll angeben, damit der Code ausgeführt wird.

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

"Web.config"-Beispiel

Das folgende Beispiel verwendet die OpenWebConfiguration-Methode WebConfigurationManager. Beachten Sie, dass Sie in diesem Fall den relativen Pfad zur Datei Web.config mit einer Tilde angeben können. Der Code benötigt einen Verweis auf die System.Web.Configuration-Klasse.

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

Weitere Informationen zum Absichern von ASP.NET-Anwendungen finden Sie unter Absichern von ASP.NET-Websites.

Weitere Informationen