인증은 어떤 신원이 SQL Server에 연결되는지 결정합니다. 데이터베이스 권한은 연결 후 그 아이덴티티드가 할 수 있는 일을 결정합니다. 애플리케이션이 실행되는 환경에 맞는 인증을 선택하고, 전송 계층 보안(TLS) 암호화와 인증서 검증 을 별도로 설정하세요.
SQL Server의 서버 인증 모드는 클라이언트가 보내는 자격 증명과는 구별됩니다:
- Windows 인증 모드는 Windows 신원을 인정합니다.
- 혼합 모드는 Windows 아이덴티티와 SQL Server 사용자 이름과 비밀번호를 허용합니다.
클라이언트 연결 문자열을 설정해도 서버의 인증 모드는 변하지 않습니다. 서버 구성에 대해서는 인증 모드 선택을 참조하세요.
인증 시나리오
환경이 지원할 때 애플리케이션 관리 비밀번호가 필요 없는 인증을 선호하세요.
| 응용 프로그램 환경 | 인증 선택 |
|---|---|
| 적절한 Windows 신원을 가진 도메인 환경. |
Integrated Security=true; SQL Server는 신뢰할 수 있는 환경의 다른 컴퓨터에 설치할 수 있습니다. |
| 도메인 아이덴티티를 설정한 리눅스 또는 macOS 애플리케이션입니다. | 클라이언트와 서버에 Kerberos 전제 조건이 통합된 보안. |
| Windows 로컬 개발은 LocalDB를 사용합니다. | 로컬 개발자 신원 아래 통합 보안. |
| Azure 호스팅 애플리케이션과 SQL 엔드포인트에서 Microsoft Entra 지원을 제공합니다. | 관리 ID 또는 다른 적절한 Microsoft Entra 인증 모드. |
| SQL 자격 증명이 필요한 환경입니다. | 보호된 구성 또는 비밀 저장소에서 가져온 최소 권한 자격 증명을 사용한 SQL 인증. |
인터넷에 접속하는 애플리케이션은 본질적으로 SQL 인증을 필요로 하지 않습니다. 웹 사용자의 로그인 여부와 애플리케이션의 데이터베이스 정체성은 별개의 결정입니다.
Windows 인증과 연결하세요
애플리케이션이 실행되는 식별 양식을 사용하세요:
Server=tcp:<server>,1433;Database=<database>;Integrated Security=true;Encrypt=true;TrustServerCertificate=false;MultiSubnetFailover=true;
Trusted_Connection=true 와 Integrated Security=true는 동의어입니다. 통합 보안이 활성화되어 있고, User IDPassword 연결 문자열 내에서는 무시됩니다. 다른 Windows 사용자를 선택하지 않습니다.
서비스는 일반적으로 웹 인터페이스를 사용하는 사람이 아닌 서비스 정체성으로 연결됩니다. 의도된 서비스 정체성에 데이터베이스 권한을 부여합니다. 최종 사용자의 신원을 컴퓨터 간에 위임해야 한다면, Kerberos 위임을 명시적으로 설정하고 검토하세요.
플랫폼 전제 조건
| Client | 요구 사항 및 동작 |
|---|---|
| Windows에서 .NET 프레임워크를 사용했습니다. | 네이티브 Windows 네트워킹과 보안 지원 제공자 인터페이스(SSPI)를 사용합니다. |
| Windows용 최신 .NET. | 기본적으로 네이티브 네트워킹을 사용합니다. Windows Negotiate는 설정이 완료되면 Kerberos를 선택합니다; NT LAN Manager(NTLM)로 다시 전환할 수 있습니다. |
| Linux 또는 macOS용 최신 .NET | 관리형 네트워킹과 .NETNegotiateAuthentication를 사용합니다. Kerberos 클라이언트, 영역, 서비스 주체명(SPN), 유효한 자격 증명 또는 티켓 캐시를 구성하세요. |
통합 보안은 도메인 신뢰, 도메인 이름 시스템(DNS) 해석, 시간 동기화, SQL Server SPN 구성 대신 대체할 수 없습니다. 리눅스에서는 애플리케이션을 시작하기 전에 플랫폼의 Kerberos 도구(예: kinit)로 티켓을 받으세요. Windows NTLM 백업이 Windows가 아닌 클라이언트에서 제공된다고 가정하지 마세요.
Kerberos 연결에 대해서는 SPN 등록을 참조하세요.
현재 SQL Server 연결의 인증 방식을 검사하려면 다음 Transact-SQL(T-SQL) 쿼리를 실행하세요:
SELECT auth_scheme
FROM sys.dm_exec_connections
WHERE session_id = @@SPID;
이 진단 뷰에 대한 접근은 서버의 권한에 따라 달라집니다. 성공적인 연결만으로는 NCLM이 아닌 케르베로스가 사용되었다는 증거는 아닙니다.
보안 컨텍스트 협상을 제어해야 하는 애플리케이션의 경우, SspiContextProvider 맞춤형 SSPI 구현을 지원합니다. 이는 맞춤형 Kerberos나 명시적 NTLM 자격 증명과 같은 시나리오를 위한 고급 확장 포인트입니다. 이 모드는 연결 문자열 인증 모드가 아니며, 또는 AccessTokenCallback.과 AccessToken 결합할 수 없습니다.
맞춤형 보안 지원 제공자 인터페이스(SSPI) 컨텍스트 제공자
SspiContextProvider 추상 클래스는 모든 SSPI 컨텍스트 제공자의 기반입니다. 커스텀 공급자를 생성하려면 SspiContextProvider에서 파생하고 GenerateContext 메서드를 재정의하세요. 연결을 열기 전에 SspiContextProvider의 SqlConnection 속성에 공급자의 인스턴스를 할당하세요.
GenerateContext 메서드는 SSPI 인증 핸드셰이크 중에 호출됩니다. 서버로부터 들어오는 인증 블롭, 나가는 응답 블롭을 위한 버퍼 기록기, 그리고 다음과 같은 연결 메타데이터를 포함하는 SspiAuthenticationParameters 객체를 받습니다:
-
Resource- 서버의 서비스 주체명(SPN). -
ServerName- 데이터 소스 이름. -
DatabaseName- 명시된 경우 대상 데이터베이스. -
UserId- 사용자 ID, 연결 문자열에 명시된 경우. -
Password- 비밀번호(연결 문자열에 명시된 경우).
중요한 고려 사항:
- 연결을 열기 전에
SspiContextProvider속성을 설정하세요. 열린 연결이나 연결 중인 연결에 이를 설정하려고 하면InvalidOperationException예외가 발생합니다. -
SspiContextProvider인스턴스는 연결 풀을 식별하는 데 사용되는 키의 일부입니다. 새 공급자가 새 풀을 생성하므로 각SspiContextProvider에 대해 새SqlConnection인스턴스를 생성하지 마세요. 풀링 대상으로 간주하려는 연결에는 동일한 provider 인스턴스를 참조하세요. - 커스텀
SspiContextProvider은 동일한 입력 매개변수에 대해 동일한 보안 컨텍스트로 인증해야 합니다. 보안 컨텍스트가 다르면, 잘못된 보안 컨텍스트를 가진 풀링 연결이 연결 요청에 대해 반환될 수 있습니다. -
SspiContextProvider는 토큰 기반 인증과 상호 배타적입니다. 어느 속성을 먼저 설정하든, 이것을AccessToken또는AccessTokenCallback와 함께 설정하면InvalidOperationException가 발생합니다.
Example
NegotiateAuthentication.NET 7 이상이 필요하므로 이 예제는 .NET 프레임워크에서 컴파일되지 않습니다. .NET 프레임워크 제공자의 경우, 대신 플랫폼 SSPI API를 기반으로 GenerateContext를 구현하세요.
다음 예시는 인증을 수행하는 데 사용하는 NegotiateAuthentication 맞춤형 SSPI 컨텍스트 제공자를 보여줍니다:
using System;
using System.Buffers;
using System.Net.Security;
using Microsoft.Data.SqlClient;
class CustomSspiContextProvider : SspiContextProvider
{
private NegotiateAuthentication? _auth;
protected override bool GenerateContext(
ReadOnlySpan<byte> incomingBlob,
IBufferWriter<byte> outgoingBlobWriter,
SspiAuthenticationParameters authParams)
{
_auth ??= new NegotiateAuthentication(
new NegotiateAuthenticationClientOptions
{
Package = "Negotiate",
TargetName = authParams.Resource,
});
byte[]? blob = _auth.GetOutgoingBlob(
incomingBlob, out NegotiateAuthenticationStatusCode statusCode);
if (statusCode is not NegotiateAuthenticationStatusCode.Completed
and not NegotiateAuthenticationStatusCode.ContinueNeeded)
{
return false;
}
if (blob is not null)
{
outgoingBlobWriter.Write(blob);
}
return true;
}
}
연결을 열기 전에 제공자를 할당하세요:
using var connection = new SqlConnection(
"Server=myServer;Database=myDatabase;Integrated Security=true;Encrypt=True;");
connection.SspiContextProvider = new CustomSspiContextProvider();
connection.Open();
보안 고려 사항
맞춤형 SSPI 컨텍스트 제공자를 구현할 때 다음과 같은 보안 고려사항을 염두에 두세요:
-
모든 입력을 검증하세요.
들어오는 블롭과 인증 매개변수를 처리하기 전에 반드시 검증하세요. 변형되거나 예상치 못한 데이터는
false에서GenerateContext을 반환하여 거부해야 합니다. -
자격 증명을 보호하세요.
SspiAuthenticationParameters객체에는Password및UserId와 같은 민감한 값이 포함될 수 있습니다. 이 값들을 기록하거나 보존하거나 보안되지 않은 방식으로 전송하지 마세요. - 검증된 인증 라이브러리를 사용하세요. 가능하다면 인증 로직을 직접 암호화 프로토콜을 구현하기보다는 잘 검증된 라이브러리 NegotiateAuthentication 에 위임하세요.
-
리소스를 해제하세요.
제공업체가 관리되지 않은 리소스나 인증 컨텍스트를 할당하는 경우, IDisposableIDisposable을 구현하고 적절히 정리되도록 하세요. SqlClient는
SspiContextProvider인스턴스를 폐기하지 않습니다. 애플리케이션이 더 이상 provider를 필요로 하지 않을 때 provider를 dispose하세요. -
인증 패키지를 제한하세요.
환경에 적합한 인증 패키지만 사용하세요(예:
Negotiate또는Kerberos). 신뢰할 수 있는 입력과 설정만 인증 패키지에 전달하세요. - 철저히 테스트. 토큰 갱신, 연결 풀링, 장애 조치 시나리오를 포함한 모든 예상 조건에서 프로바이더가 올바르게 작동하는지 확인하세요.
Microsoft는 맞춤형 SspiContextProvider 구현을 검증하거나 감사하지 않으며, 맞춤형 공급자를 통해 인증된 연결의 보안을 보장하지도 않습니다. 맞춤형 구현으로 인해 발생하는 취약점은 모두 귀하의 책임입니다.
로그인 유형
로그인은 서버에 대한 신원 접근 권한을 부여합니다. 데이터베이스 사용자는 데이터베이스 내 신원을 나타냅니다. 의도한 로그인 또는 그룹을 데이터베이스 사용자에게 매핑한 후, 데이터베이스 역할을 통해 필요한 권리만 부여합니다.
SQL Server는 Windows 계정 로그인, Windows 그룹 로그인, SQL 로그인을 지원합니다. Windows 그룹은 관리자가 각 개인별로 별도의 SQL Server 로그인 없이 멤버십을 관리할 수 있게 해줍니다. 코드 서명에 사용되는 인증서 및 비대칭 키 로그인은 인터랙티브 연결 식별이 아닙니다.
포함된 데이터베이스 사용자와 Microsoft Entra 프린시펄은 서로 다른 프로비저닝 요구사항을 가집니다. 모든 사용자가 SQL 로그인이 필요하다고 가정하기보다는 Principals 와 엔드포인트의 인증 문서를 확인하세요.
혼합 모드 인증
SQL 인증을 받도록 설정된 엔드포인트에서만 사용하세요.
User ID 및 Password를 지정하고, 통합 보안을 비활성화하고, 인증서 유효성 검사는 활성화된 상태로 유지하세요.
Authentication=Sql Password명시적으로 SQL 비밀번호 인증을 선택하며; Microsoft Entra 비밀번호 인증은 선택하지 않습니다.
다음 .NET 콘솔 예제에서는 Microsoft.Data.SqlClient를 사용합니다.
SQL_DATABASE, SQL_USER_ID, SQL_SERVER, SQL_PASSWORD를 개발 환경이나 비밀 주입 메커니즘을 통해 설정하세요.
SQL_SERVER 는 전송 제어 프로토콜(TCP) 엔드포인트 tcp:sql-server.contoso.com,1433를 포함해야 합니다. 비밀번호나 완료된 연결 문자열을 출력하지 마세요.
using Microsoft.Data.SqlClient;
static string Required(string name) =>
Environment.GetEnvironmentVariable(name)
?? throw new InvalidOperationException($"Set {name} before running.");
var options = new SqlConnectionStringBuilder
{
DataSource = Required("SQL_SERVER"),
InitialCatalog = Required("SQL_DATABASE"),
Authentication = SqlAuthenticationMethod.SqlPassword,
UserID = Required("SQL_USER_ID"),
Password = Required("SQL_PASSWORD"),
Encrypt = SqlConnectionEncryptOption.Mandatory,
TrustServerCertificate = false,
MultiSubnetFailover = true
};
using var connection = new SqlConnection(options.ConnectionString);
await connection.OpenAsync();
using var command = new SqlCommand("SELECT DB_NAME();", connection);
Console.WriteLine(await command.ExecuteScalarAsync());
쿼리는 연결된 데이터베이스 이름을 출력합니다. 자격증명을 문자열로 연결하는 대신 SqlConnectionStringBuilder 를 사용하세요. 빌더는 연결 문자열 값을 이스케이프 처리할 뿐이며, 애플리케이션이 어떤 서버, 데이터베이스 또는 권한을 허용해야 하는지는 결정하지 않습니다.
기본값은 유지 Persist Security Info=false하세요. 생산 비밀을 보호된 비밀 저장소에 저장하고, 누가 읽을 수 있는지 제한하며, 번갈아 가세요. 일상적인 애플리케이션 요청에는 관리자나 데이터베이스 소유자 신원을 사용하지 마세요.
Microsoft Entra 및 서비스 제한 사항
Integrated Security=trueWindows 신원을 SQL Server에 인증합니다.
Authentication=Active Directory IntegratedMicrosoft Entra 토큰을 획득합니다. 이 두 단어는 서로 바꿔 쓸 수 없습니다.
Azure SQL Database는 일반적인 Windows 통합 인증 대신 SQL 또는 Microsoft Entra 인증을 사용합니다. Microsoft Fabric의 SQL 데이터베이스는 Microsoft Entra 아이덴티티만 지원하며; SQL 인증과 로그인은 지원되지 않습니다. 토큰 기반 연결은 Microsoft Entra 기사를 참고하세요.