Строки подключения и файлы конфигурации
Область применения: платформа .NET Framework .NET Core .NET Standard
Внедрение строк соединения в код приложения может привести к появлению уязвимых мест в системе безопасности и проблем с обслуживанием. Незашифрованные строки подключения, скомпилированные в исходный код приложения, можно просматривать с помощью средства Ildasm.exe (IL Disassembler). Кроме того, после изменения строки соединения необходимо перекомпилировать приложение. По этим причинам рекомендуется хранить строки соединения в файле конфигурации приложения.
Работа с файлами конфигурации приложения
Файлы конфигурации приложения содержат настройки, относящиеся к отдельному приложению. Например, приложение ASP.NET может иметь один или несколько файлов web.config, а приложение Windows — дополнительный файл app.config. В файлах конфигурации присутствуют общие элементы, хотя имя и расположение любого файла конфигурации в значительной степени зависят от того, где размещается приложение.
Раздел connectionStrings
Строки подключения могут храниться в виде пар "ключ/значение" в разделе connectionStrings элемента configuration файла конфигурации приложения. Дочерние элементы включают add, clear и remove.
Следующий фрагмент файла конфигурации демонстрирует схему и синтаксис хранения строки соединения. Атрибут name является именем, которое задано для уникальной идентификации строки подключения, чтобы ее можно было получить во время выполнения. providerName имеет значение Microsoft.Data.SqlClient (то есть поставщик данных Microsoft SqlClient для SQL Server).
<?xml version='1.0' encoding='utf-8'?>
<configuration>
<connectionStrings>
<clear />
<add name="Name"
providerName="Microsoft.Data.SqlClient"
connectionString="Valid Connection String;" />
</connectionStrings>
</configuration>
Примечание.
Можно сохранить часть строки соединения в файле конфигурации и для ее дополнения во время выполнения использовать класс DbConnectionStringBuilder. Это удобно в сценариях, в которых заранее неизвестны элементы строки соединения или желательно не сохранять конфиденциальные данные в файле конфигурации. Дополнительные сведения см. в статье Connection String Builders (Построители строк подключения).
Использование внешних файлов конфигурации
Внешние файлы конфигурации представляют собой отдельные файлы, каждый из которых содержит фрагмент файла конфигурации, состоящий из одного раздела. В таком случае основной файл конфигурации ссылается на внешний файл конфигурации. Хранение раздела connectionStrings в физически отдельном файле становится удобным в ситуациях, когда может потребоваться внесение изменений в строки подключения после развертывания приложения. Например, в ASP.NET по умолчанию после изменения файлов конфигурации осуществляется перезапуск домена приложения, что приводит к потере сведений о состоянии. Но изменение внешнего файла конфигурации не вызывает перезапуск приложения. Возможность применения внешних файлов конфигурации не ограничивается ASP.NET; их можно также использовать в приложениях Windows. Кроме того, для ограничения доступа к внешним файлам конфигурации могут использоваться средства обеспечения безопасности доступа к файлам и разрешения. Работа с внешними файлами конфигурации во время выполнения осуществляется в прозрачном режиме и не требует разработки специального кода.
Для хранения строк подключения во внешнем файле конфигурации создайте отдельный файл, содержащий единственный раздел connectionStrings. Не следует включать какие-либо дополнительные элементы, разделы или атрибуты. В данном примере показан синтаксис внешнего файла конфигурации.
<connectionStrings>
<add name="Name"
providerName="Microsoft.Data.SqlClient"
connectionString="Valid Connection String;" />
</connectionStrings>
В основном файле конфигурации приложения для указания полного имени и расположения внешнего файла используется атрибут configSource. В следующем примере применяется ссылка на внешний файл конфигурации с именем connections.config
.
<?xml version='1.0' encoding='utf-8'?>
<configuration>
<connectionStrings configSource="connections.config"/>
</configuration>
Получение строк соединения во время выполнения
В .NET Framework 2.0 в пространстве имен System.Configuration появились новые классы, упрощающие извлечение строк подключения из файлов конфигурации во время выполнения. Предусмотрена возможность получить строку соединения программным путем по ее имени или по имени поставщика.
Примечание.
Файл machine.config также содержит раздел connectionStrings, включающий строку подключения, используемую Visual Studio. При получении строка подключения по имени поставщика из файла app.config в приложении Windows сначала загружаются строка подключения в machine.config, а затем записи из app.config. Добавление ясно сразу после того, как элемент connectionStrings удаляет все унаследованные ссылки из структуры данных в памяти, чтобы считаться только строка подключения, определенные в локальном файле app.config.
Работа с файлами конфигурации
Начиная с версии .NET Framework 2.0, для работы с файлами конфигурации на локальном компьютере используется класс ConfigurationManager, который заменил устаревший класс ConfigurationSettings. WebConfigurationManager служит для работы с файлами конфигурации ASP.NET. Он создан для работы с файлами конфигурации веб-сервера и предоставляет программный доступ к разделам файла конфигураций, например system.web.
Примечание.
Вызывающему объекту для доступа к файлам конфигурации во время выполнения должны быть предоставлены разрешения. Требуемые разрешения зависят от типа приложения, файла конфигурации и расположения. Дополнительные сведения см. в разделах Использование классов конфигурации и WebConfigurationManager для приложений ASP.NET и ConfigurationManager для приложений Windows.
Для получения строк соединения из файлов конфигурации приложения используется ConnectionStringSettingsCollection. Этот объект содержит коллекцию объектов ConnectionStringSettings, каждый из которых представляет одну запись в разделе connectionStrings. Его свойства сопоставляются с атрибутами строк соединения, что позволяет получить строку соединения, указав имя строки или имя поставщика.
Свойство | Description |
---|---|
Name | Имя строки соединения. Сопоставляется с атрибутом name. |
ProviderName | Полное имя поставщика. Сопоставляется с атрибутом providerName. |
ConnectionString | Строка подключения. Сопоставляется с атрибутом connectionString. |
Пример. Перечисление всех строка подключения
В этом примере выполняется итерация ConnectionStringSettingsCollection и отображаются свойства ConnectionStringSettings.Name, ConnectionStringSettings.ProviderName и ConnectionStringSettings.ConnectionString в окне консоли.
Примечание.
Файл System.Configuration.dll не включается в проекты всех типов, поэтому для использования классов конфигурации может потребоваться сформировать на него ссылку. Имя и расположение файла конфигурации определенного приложения зависит от типа приложения и процесса размещения.
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);
}
}
}
}
Пример: получение строка подключения по имени
Данный пример демонстрирует способ получения строки соединения из файла конфигурации путем указания ее имени. Код создает объект ConnectionStringSettings, сопоставляя указанный входной параметр с именем ConnectionStrings. Если совпадающее имя не найдено, функция возвращает значение null
(Nothing
в Visual Basic).
// 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;
}
Пример. Получение строка подключения по имени поставщика
В этом примере демонстрируется, как получить строку подключения путем указания имени поставщика в формате Microsoft.Data.SqlClient. В коде выполняется итерация по ConnectionStringSettingsCollection и происходит возврат строки соединения для первого найденного ProviderName. Если имя поставщика не найдено, функция возвращает значение null
(Nothing
в 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)
{
// 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;
}
Шифрование разделов файлов конфигурации с помощью защищенной конфигурации
В ASP.NET 2.0 появилась новая возможность, защищенная конфигурация, с помощью которой можно шифровать в файле конфигурации конфиденциальную информацию. Защищенная конфигурация разрабатывалась в первую очередь для ASP.NET, но ее можно также использовать для шифрования разделов файлов конфигурации в приложениях Windows. Подробное описание возможностей защищенной конфигурации см. в разделе Шифрование сведений о конфигурации с помощью функции защищенной конфигурации.
В приведенном ниже фрагменте файла конфигурации показан раздел connectionStrings после шифрования. В разделе configProtectionProvider задается поставщик защищенной конфигурации, который используется для шифрования и дешифрования строк подключения. Раздел EncryptedData содержит зашифрованный текст.
<connectionStrings configProtectionProvider="DataProtectionConfigurationProvider">
<EncryptedData>
<CipherData>
<CipherValue>AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAAH2... </CipherValue>
</CipherData>
</EncryptedData>
</connectionStrings>
Когда зашифрованная строка подключения извлекается во время выполнения, платформа .NET Framework с помощью указанного поставщика дешифрует значение CipherValue и передает его приложению. Нет необходимости создавать дополнительный код для управления процессом дешифрования.
Защита поставщиков конфигурации
Поставщики защищенной конфигурации регистрируются в разделе configProtectedData файла machine.config на локальном компьютере, как показано в приведенном ниже фрагменте, в котором демонстрируются два поставщика защищенной конфигурации, поставляемые с платформой .NET Framework. Показанные значения были усечены для удобства чтения.
<configProtectedData defaultProvider="RsaProtectedConfigurationProvider">
<providers>
<add name="RsaProtectedConfigurationProvider"
type="System.Configuration.RsaProtectedConfigurationProvider" />
<add name="DataProtectionConfigurationProvider"
type="System.Configuration.DpapiProtectedConfigurationProvider" />
</providers>
</configProtectedData>
Можно назначить дополнительные поставщики защищенной конфигурации, добавляя их в файл machine.config. Кроме того, можно создать собственный поставщик защищенной конфигурации путем наследования от абстрактного базового класса ProtectedConfigurationProvider. В приведенной ниже таблице дано описание двух файлов конфигурации, входящих в платформу .NET Framework.
Provider | Description |
---|---|
RsaProtectedConfigurationProvider | Использует алгоритм RSA для шифрования и расшифровки данных. Алгоритм RSA можно использовать для шифрования с открытым ключом и цифровых сигнатур. Он также известен как алгоритм с «открытым ключом» или алгоритм асимметричного шифрования, поскольку в нем используется два разных ключа. Для шифрования разделов в файле Web.config и управления ключами шифрования можно использовать средство регистрации служб IIS ASP.NET (Aspnet_regiis.exe). ASP.NET расшифровывает файл конфигурации при обработке файла. Удостоверение приложения ASP.NET должно иметь права на чтение ключа шифрования, который используется для шифрования и расшифровки зашифрованных разделов. |
DpapiProtectedConfigurationProvider | Использует API-интерфейс защиты данных (DPAPI) для шифрования разделов конфигурации. Он использует встроенные службы шифрования Windows и может быть настроен для защиты отдельных компьютеров или отдельных учетных записей пользователей. Защиту отдельных компьютеров удобно использовать для нескольких приложений на одном сервере, которым требуется совместное использование данных. Защиту учетных записей можно использовать со службами, выполняемыми с определенным удостоверением пользователя, например с общей средой размещения. Каждое приложение выполняется с отдельным идентификатором, что ограничивает доступ к таким ресурсам, как файлы и базы данных. |
Оба поставщика обеспечивают надежное шифрование данных. Однако, если планируется использовать один файл конфигурации на нескольких серверах, как в веб-ферме, то только RsaProtectedConfigurationProvider позволяет экспортировать ключи шифрования, применяемые для шифрования данных, и импортировать их в другой сервер. Дополнительные сведения см. в разделе Импорт и экспорт защищенных контейнеров ключей RSA для конфигурации.
Использование классов конфигурации
Пространство имен System.Configuration предоставляет классы для программной обработки параметров конфигурации. Класс ConfigurationManager обеспечивает доступ к компьютеру, приложению и пользовательским файлам конфигурации. При создании приложения ASP.NET можно использовать класс WebConfigurationManager, который предоставляет те же функциональные возможности и одновременно позволяет обращаться к уникальным настройкам приложений ASP.NET, в частности, в файле <system.web>.
Примечание.
Пространство имен System.Security.Cryptography содержит классы, которые предоставляют дополнительные возможности шифрования и расшифровки данных. Эти классы можно использовать в том случае, если требуются криптографические службы, недоступные с использованием защищенной конфигурации. Некоторые из этих классов являются оболочками для Microsoft CryptoAPI, а другие представляют собой реализации полностью на управляемом коде. Дополнительные сведения см. в разделе Службы криптографии.
Пример App.config
Этот пример демонстрирует переключение шифрования раздела connectionStrings в файле app.config для приложения Windows. В этом примере процедура принимает имя приложения в качестве аргумента, например, «MyApplication.exe». Затем файл app.config зашифровывается и копируется в папку, которая содержит исполняемый файл с именем MyApplication.exe.config.
Примечание.
Строку соединения можно расшифровать только на компьютере, где она была зашифрована.
В коде используется метод OpenExeConfiguration, чтобы открыть файл app.config для изменения, а метод GetSection возвращает раздел connectionStrings. Затем код проверяет свойство IsProtected, вызывая метод ProtectSection для шифрования раздела, если он не зашифрован. Метод UnprotectSection вызывается для расшифровки раздела. Метод Save завершает операцию и сохраняет изменения.
Примечание.
Для запуска кода необходимо задать ссылку на System.Configuration.dll
в проекте.
static void ToggleConfigEncryption(string exeFile)
{
// 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);
}
}
Пример Web.config
В этом примере используется метод OpenWebConfiguration класса WebConfigurationManager
. Обратите внимание, что в этом случае можно задать относительный путь к файлу Web.config с использованием символа "тильда". В коде должна быть ссылка на класс System.Web.Configuration
.
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();
}
Дополнительные сведения о защите приложений ASP.NET см. в статье Защита веб-сайтов ASP.NET.