연결 문자열 및 구성 파일(ADO.NET)
업데이트: November 2007
응용 프로그램 코드에 연결 문자열을 포함하면 보안상 취약한 부분이 생기고 유지 관리상의 문제가 발생할 수 있습니다. MSIL 디스어셈블러(Ildasm.exe) 도구를 사용하면 응용 프로그램의 소스 코드로 컴파일된 암호화되지 않은 연결 문자열을 볼 수 있습니다. 뿐만 아니라 연결 문자열이 계속해서 변경되는 경우에는 응용 프로그램을 다시 컴파일해야 합니다. 이와 같은 여러 가지 이유로 연결 문자열은 응용 프로그램 구성 파일에 저장하는 것이 좋습니다.
응용 프로그램 구성 파일 사용
응용 프로그램 구성 파일에는 특정 응용 프로그램과 관련된 설정이 들어 있습니다. 예를 들어, ASP.NET 응용 프로그램에는 하나 이상의 web.config 파일이 있을 수 있고, Windows 응용 프로그램에는 app.config라는 선택적 파일이 하나 있을 수 있습니다. 구성 파일의 이름과 위치는 응용 프로그램 호스트에 따라 다르지만 모든 구성 파일은 다음과 같은 공통 요소를 공유합니다.
connectionStrings 섹션
연결 문자열은 응용 프로그램 구성 파일의 configuration 요소 내 connectionStrings 섹션에 키/값 쌍으로 저장할 수 있습니다. 자식 요소에는 add, clear 및 remove가 있습니다.
다음은 연결 문자열을 저장하기 위한 스키마 및 구문이 나와 있는 구성 파일의 일부분입니다. name 특성은 연결 문자열을 고유하게 식별하는 기능을 제공하여 연결 문자열이 런타임에 검색될 수 있도록 하는 이름입니다. providerName은 machine.config 파일에 등록되어 있는 .NET Framework 데이터 공급자의 고정 이름입니다.
<?xml version='1.0' encoding='utf-8'?>
<configuration>
<connectionStrings>
<clear />
<add name="Name"
providerName="System.Data.ProviderName"
connectionString="Valid Connection String;" />
</connectionStrings>
</configuration>
참고: |
---|
연결 문자열 일부를 구성 파일에 저장한 후 DbConnectionStringBuilder 클래스를 사용하여 런타임에 연결 문자열을 완성할 수 있습니다. 이 기능은 사전에 연결 문자열 요소를 정확히 알고 있지 않거나 중요한 정보를 구성 파일에 저장하지 않으려는 경우에 유용합니다. 자세한 내용은 연결 문자열 작성기(ADO.NET)을 참조하십시오. |
외부 구성 파일 사용
외부 구성 파일은 단일 섹션으로 구성되며 구성 파일의 한 조각이 포함된 별도의 파일입니다. 외부 구성 파일은 기본 구성 파일에서 참조합니다. connectionStrings 섹션을 물리적으로 분리된 파일에 저장하면 응용 프로그램 배포 후 연결 문자열이 편집될 수 있는 경우에 유용합니다. 예를 들어, 표준 ASP.NET 동작에서는 구성 파일이 수정되면 응용 프로그램 도메인을 다시 시작합니다. 따라서 상태 정보가 손실될 수 있습니다. 하지만 외부 구성 파일은 수정해도 응용 프로그램이 다시 시작되지 않습니다. 외부 구성 파일은 ASP.NET뿐만 아니라 Windows 응용 프로그램에도 사용될 수 있습니다. 파일 액세스 보안 및 권한을 사용하여 외부 구성 파일에 대한 액세스를 제한할 수도 있습니다. 런타임에 외부 구성 파일을 사용하는 것은 투명하게 수행되므로 특별한 코딩이 필요하지 않습니다.
연결 문자열을 외부 구성 파일에 저장하려면 connectionStrings 섹션만 있는 별도의 파일을 만듭니다. 이외 다른 요소, 섹션 또는 특성은 포함하지 마십시오. 다음 예제에서는 외부 구성 파일의 구문을 보여 줍니다.
<connectionStrings>
<add name="Name"
providerName="System.Data.ProviderName"
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 파일에는 Visual Studio에서 사용하는 연결 문자열이 있는 connectionStrings 섹션도 포함되어 있습니다. 공급자 이름을 사용하여 Windows 응용 프로그램의 app.config 파일에서 연결 문자열을 검색하면 machine.config의 연결 문자열이 먼저 로드된 다음 app.config의 항목이 로드됩니다. connectionStrings 요소 바로 뒤에 clear를 추가하면 상속된 모든 참조가 메모리의 데이터 구조에서 제거되어 로컬 app.config 파일에 정의된 연결 문자열만 검색할 수 있습니다. |
구성 클래스 사용
.NET Framework 2.0부터는 로컬 컴퓨터의 구성 파일을 사용할 경우 더 이상 사용되지 않는 ConfigurationSettings 대신 ConfigurationManager가 사용됩니다. ASP.NET 구성 파일을 사용하는 경우에는 WebConfigurationManager가 사용됩니다. 이 클래스는 웹 서버의 구성 파일에 사용하도록 디자인되었으며 system.web과 같은 구성 파일 섹션에 프로그래밍 방식으로 액세스할 수 있도록 합니다.
참고: |
---|
런타임에 구성 파일에 액세스하려면 호출자에게 권한을 부여해야 합니다. 필요한 권한은 응용 프로그램의 종류와 구성 파일 및 구성 파일의 위치에 따라 다릅니다. 자세한 내용은 구성 클래스 사용 및 WebConfigurationManager(ASP.NET 응용 프로그램)와 ConfigurationManager(Windows 응용 프로그램)를 참조하십시오. |
ConnectionStringSettingsCollection을 사용하여 응용 프로그램 구성 파일에서 연결 문자열을 검색할 수 있습니다. 이 컬렉션에는 ConnectionStringSettings 개체 컬렉션이 포함되어 있으며, 각 개체는 connectionStrings 섹션의 단일 항목을 나타냅니다. 개체 속성은 연결 문자열 특성에 매핑되므로 이름 또는 공급자 이름을 지정하여 연결 문자열을 검색할 수 있습니다.
속성 |
설명 |
---|---|
연결 문자열의 이름으로, name 특성에 매핑됩니다. |
|
정규화된 공급자 이름으로, providerName 특성에 매핑됩니다. |
|
연결 문자열로, connectionString 특성에 매핑됩니다. |
예제: 모든 연결 문자열 나열
다음 예제에서는 ConnectionStringSettings 컬렉션을 반복한 후 Name, ProviderName 및 ConnectionString 속성을 콘솔 창에 표시합니다.
참고: |
---|
일부 프로젝트 형식에는 System.Configuration.dll이 포함되어 있지 않으므로 구성 클래스를 사용하려면 먼저 System.Configuration.dll에 대한 참조를 설정해야 할 수도 있습니다. 특정 응용 프로그램 구성 파일의 이름과 위치는 응용 프로그램의 종류 및 호스팅 프로세스에 따라 달라집니다. |
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);
}
}
}
}
예제: 이름을 사용하여 연결 문자열 검색
다음 예제에서는 이름을 지정하여 구성 파일에서 연결 문자열을 검색하는 방법을 보여 줍니다. 다음 코드에서는 ConnectionStringSettings 개체를 만들어 사용자가 제공한 입력 매개 변수가 ConnectionStrings 이름과 일치하는지 확인합니다. 일치하는 이름이 없으면 함수에서 null(Visual Basic의 경우 Nothing)을 반환합니다.
' 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;
}
예제: 공급자 이름을 사용하여 연결 문자열 검색
다음 예제에서는 공급자 고정 이름을 System.Data.ProviderName 형식으로 지정하여 연결 문자열을 검색하는 방법을 보여 줍니다. 코드에서 ConnectionStringSettingsCollection을 반복한 후 일치하는 첫 번째 ProviderName에 대한 연결 문자열을 반환합니다. 공급자 이름이 없으면 이 함수가 null(Visual Basic의 경우 Nothing)을 반환합니다.
' 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;
}
보호되는 구성을 사용하여 구성 파일 섹션 암호화
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의 암호를 해독하고 응용 프로그램에서 해당 문자열을 사용할 수 있도록 합니다. 따라서 암호를 해독하는 데 추가 코드를 작성할 필요가 없습니다.
보호되는 구성 공급자
보호되는 구성 공급자는 로컬 컴퓨터에 있는 machine.config 파일의 configProtectedData 섹션에 등록됩니다. 다음 단편에서는 .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와 함께 포함된 두 개의 구성 파일이 설명되어 있습니다.
공급자 |
설명 |
---|---|
RSAProtectedConfigurationProvider |
RSA 암호화 알고리즘을 사용하여 데이터를 암호화하고 해독합니다. 공개 키 암호화 및 디지털 서명에도 RSA 알고리즘을 사용할 수 있습니다. 두 개의 서로 다른 키를 사용하므로 "공개 키" 또는 비대칭 암호화라고도 합니다. ASP.NET IIS 등록 도구(Aspnet_regiis.exe)를 사용하여 Web.config 파일의 섹션을 암호화하고 암호화 키를 관리할 수 있습니다. ASP.NET에서는 파일을 처리할 때 구성 파일의 암호를 해독합니다. ASP.NET 응용 프로그램의 ID는 섹션을 암호화하고 해독하는 데 사용되는 암호화 키에 대해 읽기 액세스 권한이 있어야 합니다. |
DPAPIProtectedConfigurationProvider |
Windows DPAPI(데이터 보호 API)를 사용하여 구성 섹션을 암호화합니다. Windows 기본 제공 암호화 서비스를 사용하며 시스템별 또는 사용자 계정별로 보호되도록 구성할 수 있습니다. 시스템별 보호는 동일한 서버에 정보를 공유해야 하는 여러 응용 프로그램이 있을 때 유용합니다. 사용자 계정별 보호는 공유된 호스팅 환경과 같이 특정 사용자 ID와 함께 실행되는 서비스에서 사용할 수 있습니다. 각 응용 프로그램은 파일 및 데이터베이스와 같은 리소스에 대한 액세스를 제한하는 개별 ID에 대해 실행됩니다. |
두 공급자 모두 강력한 데이터 암호화를 제공합니다. 그러나 웹 팜과 같이 여러 서버에서 동일한 암호화 구성 파일을 사용하려는 경우 데이터를 암호화하는 데 사용되는 암호화 키를 내보내고 다른 서버에서 가져오도록 하려면 RsaProtectedConfigurationProvider를 사용해야 합니다. 자세한 내용은 보호되는 구성 RSA 키 컨테이너 가져오기 및 내보내기를 참조하십시오.
구성 클래스 사용
System.Configuration 네임스페이스에서는 프로그래밍 방식으로 구성을 설정하는 클래스를 제공합니다. ConfigurationManager 클래스에서는 시스템, 응용 프로그램 및 사용자 구성 파일에 대한 액세스를 제공합니다. ASP.NET 응용 프로그램을 만드는 경우 WebConfigurationManager 클래스를 사용하여 **<system.web>**에 있는 설정과 같이 ASP.NET 응용 프로그램에 고유한 설정에 액세스할 수 있으면서 동일한 기능을 제공할 수 있습니다.
참고: |
---|
System.Security.Cryptography 네임스페이스에는 데이터를 암호화하고 해독하는 추가 옵션을 제공하는 클래스가 들어 있습니다. 보호되는 구성을 사용하여 처리할 수 없는 암호화 서비스가 필요한 경우 이러한 클래스를 사용합니다. 이러한 클래스 중 일부는 관리되지 않는 Microsoft CryptoAPI에 대한 래퍼이지만 나머지는 완전하게 관리되는 구현 클래스입니다. 자세한 내용은 암호화 서비스를 참조하십시오. |
App.config 예제
이 예제에서는 Windows 응용 프로그램의 app.config 파일에 있는 connectionStrings 섹션의 암호화를 전환하는 방법에 대해 설명합니다. 이 예제의 프로시저에서는 응용 프로그램 이름을 인수로 사용합니다(예: "MyApplication.exe"). app.config 파일을 암호화한 다음 이름이 "MyApplication.exe.config"인 실행 파일이 들어 있는 폴더로 복사합니다.
참고: |
---|
연결 문자열은 암호화된 컴퓨터에서만 해독될 수 있습니다. |
코드에서는 OpenExeConfiguration 메서드를 사용하여 편집할 app.config 파일을 열고 GetSection 메서드에서는 connectionStrings 섹션을 반환합니다. 그런 다음 코드에서 IsProtected 속성을 확인하여 섹션이 암호화되지 않은 경우 섹션을 암호화하는 ProtectSection을 호출합니다. 섹션의 암호를 해독하려면 UnProtectSection() 메서드를 호출합니다. Save 메서드가 작업을 완료하고 변경 내용을 저장합니다.
참고: |
---|
코드를 실행하려면 프로젝트에서 System.Configuration.dll에 대한 참조를 설정해야 합니다. |
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);
}
}
Web.config 예제
이 예제에서는 WebConfigurationManager의 OpenWebConfiguration 메서드를 사용합니다. 이 경우 물결표를 사용하여 Web.config 파일에 대한 상대 경로를 제공할 수 있습니다. 코드에는 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();
}
ASP.NET 응용 프로그램 보안에 대한 자세한 내용은 ASP.NET Developer Center에서 ASP.NET 웹 사이트 보안 및 ASP.NET 2.0 Security Practices at a Glance를 참조하십시오.