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.
Wichtig
Microsoft empfiehlt, immer den sichersten Authentifizierungsflow zu verwenden. Wenn Sie eine Verbindung mit Azure SQL herstellen, ist Managed Identities for Azure Resources die empfohlene Authentifizierungsmethode.
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.
Im Abschnitt connectionStrings
.
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önnten. 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 der ConfigurationManager verwendet, der die veraltete ConfigurationSettings-Klasse ersetzt. 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 WebConfigurationManagerfür ASP.NET-Anwendungen und 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
System.Configuration.dll ist nicht in allen Projekttypen enthalten, sodass Sie möglicherweise 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 über den 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 über den Anbieternamen
In diesem Beispiel wird gezeigt, wie eine Verbindungszeichenfolge durch Angabe des unveränderlichen Anbieternamens im Format System.Data.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 mithilfe der geschützten 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.
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 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.
"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.
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 Verbindungszeichenfolge kann nur auf dem Computer entschlüsselt werden, auf dem sie verschlüsselt wurde.) Die Save-Methode schließt den Vorgang ab und speichert die Änderungen.
Sie müssen in Ihrem Projekt einen Verweis auf System.Configuration.dll
hinzufügen, damit der Code ausgeführt wird.
Wichtig
Microsoft empfiehlt, immer den sichersten Authentifizierungsflow zu verwenden. Wenn Sie eine Verbindung mit Azure SQL herstellen, ist Managed Identities for Azure Resources die empfohlene Authentifizierungsmethode.
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
. In diesem Fall können Sie den relativen Pfad zur Datei Web.config mit einer Tilde angeben. 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.