Windows 인증을 보안 메커니즘으로 사용하는 경우 SSPI(보안 지원 공급자 인터페이스)는 보안 프로세스를 처리합니다. SSPI 계층에서 보안 오류가 발생하면 WCF(Windows Communication Foundation)에 의해 표시됩니다. 이 항목에서는 오류를 진단하는 데 도움이 되는 프레임워크 및 질문 집합을 제공합니다.
Kerberos 프로토콜에 대한 개요는 Kerberos 설명; SSPI 개요는 SSPI를 참조하세요.
Windows 인증의 경우 WCF는 일반적으로 클라이언트와 서비스 간에 Kerberos 상호 인증을 수행하는 SSP( 협상 보안 지원 공급자)를 사용합니다. Kerberos 프로토콜을 사용할 수 없는 경우 기본적으로 WCF는 NTLM(NT LAN 관리자)으로 대체됩니다. 그러나 WCF를 Kerberos 프로토콜만 사용하도록 구성하고, Kerberos를 사용할 수 없는 경우 예외를 발생시키도록 할 수 있습니다. 제한된 형태의 Kerberos 프로토콜을 사용하도록 WCF를 구성할 수도 있습니다.
디버깅 방법론
기본 메서드는 다음과 같습니다.
Windows 인증을 사용하는지 여부를 확인합니다. 다른 체계를 사용하는 경우 이 항목은 적용되지 않습니다.
Windows 인증을 사용하고 있다고 확신하는 경우 WCF 구성에서 Kerberos 직접 또는 Negotiate를 사용하는지 여부를 결정합니다.
구성이 Kerberos 프로토콜 또는 NTLM을 사용하는지 여부를 확인하면 올바른 컨텍스트에서 오류 메시지를 이해할 수 있습니다.
Kerberos 프로토콜 및 NTLM의 가용성
Kerberos SSP를 사용하려면 도메인 컨트롤러가 KDC(Kerberos 키 배포 센터)로 작동해야 합니다. Kerberos 프로토콜은 클라이언트와 서비스가 모두 도메인 ID를 사용하는 경우에만 사용할 수 있습니다. 다른 계정 조합에서는 다음 표에 요약된 대로 NTLM이 사용됩니다.
테이블 헤더는 서버에서 사용할 수 있는 계정 유형을 보여 줍니다. 왼쪽 열에는 클라이언트에서 사용할 수 있는 계정 유형이 표시됩니다.
로컬 사용자 | 로컬 시스템 | 도메인 사용자 | 도메인 머신 | |
---|---|---|---|---|
로컬 사용자 | NTLM | NTLM | NTLM | NTLM |
로컬 시스템 | 익명 NTLM | 익명 NTLM | 익명 NTLM | 익명 NTLM |
도메인 사용자 | NTLM | NTLM | Kerberos | Kerberos |
Domain Machine | NTLM | NTLM | Kerberos | Kerberos |
특히 네 가지 계정 유형은 다음과 같습니다.
로컬 사용자: 컴퓨터 전용 사용자 프로필입니다. 예를 들어
MachineName\Administrator
또는MachineName\ProfileName
입니다.로컬 시스템: 도메인에 가입되지 않은 컴퓨터의 기본 제공 계정 시스템입니다.
도메인 사용자: Windows 도메인의 사용자 계정입니다. 예:
DomainName\ProfileName
.Domain Machine: Windows 도메인에 가입된 컴퓨터에서 기계 정체성을 가진 프로세스입니다. 예:
MachineName\Network Service
.
비고
서비스 자격 증명은 Open 클래스의 ServiceHost 메서드가 호출될 때 캡처됩니다. 클라이언트 자격 증명은 클라이언트가 메시지를 보낼 때마다 읽습니다.
일반적인 Windows 인증 문제
이 섹션에서는 몇 가지 일반적인 Windows 인증 문제 및 가능한 해결 방법에 대해 설명합니다.
Kerberos 프로토콜
Kerberos 프로토콜의 SPN/UPN 문제
Windows 인증을 사용하고 Kerberos 프로토콜을 SSPI에서 사용하거나 협상하는 경우 클라이언트 엔드포인트에서 사용하는 URL에는 서비스 URL 내에 서비스 호스트의 정규화된 도메인 이름이 포함되어야 합니다. 이 경우 서비스가 실행 중인 계정이 Active Directory 도메인에 컴퓨터를 추가할 때 생성되는 컴퓨터(기본) SPN(서비스 사용자 이름) 키에 액세스할 수 있다고 가정합니다. 이 키는 네트워크 서비스 계정에서 서비스를 실행하여 가장 일반적으로 수행됩니다. 서비스에 컴퓨터 SPN 키에 대한 액세스 권한이 없는 경우 서비스가 클라이언트의 엔드포인트 ID에서 실행 중인 계정의 올바른 SPN 또는 UPN(사용자 계정 이름)을 제공해야 합니다. WCF가 SPN 및 UPN에서 작동하는 방법에 대한 자세한 내용은 서비스 ID 및 인증을 참조하세요.
웹 팜 또는 웹 정원과 같은 부하 분산 시나리오에서 일반적인 방법은 각 애플리케이션에 대한 고유한 계정을 정의하고, 해당 계정에 SPN을 할당하고, 애플리케이션의 모든 서비스가 해당 계정에서 실행되도록 하는 것입니다.
서비스 계정에 대한 SPN을 가져오려면 Active Directory 도메인 관리자여야 합니다. 자세한 내용은 Windows용 Kerberos 기술 보충을 참조하세요.
Kerberos 프로토콜 직접을 사용하려면 도메인 컴퓨터 계정에서 서비스를 실행해야 합니다.
이는 다음 코드에서 보여진 대로 ClientCredentialType
속성이 Windows
로 설정되고 NegotiateServiceCredential 속성이 false
로 설정될 때 발생합니다.
WSHttpBinding b = new WSHttpBinding();
// By default, the WSHttpBinding uses Windows authentication
// and Message mode.
b.Security.Message.NegotiateServiceCredential = false;
Dim b As New WSHttpBinding()
' By default, the WSHttpBinding uses Windows authentication
' and Message mode.
b.Security.Message.NegotiateServiceCredential = False
해결하려면 도메인에 가입된 컴퓨터에서 네트워크 서비스와 같은 Domain Machine 계정을 사용하여 서비스를 실행합니다.
위임에 자격 증명 협상 필요
위임과 함께 Kerberos 인증 프로토콜을 사용하려면 자격 증명 협상("다중 다리" 또는 "다단계" Kerberos라고도 함)을 사용하여 Kerberos 프로토콜을 구현해야 합니다. 자격 증명 협상이 없는 Kerberos 인증을 구현하는 경우(일명 "원샷" 또는 "단발" Kerberos) 예외가 발생합니다.
자격 증명 협상으로 Kerberos를 구현하려면 다음 단계를 수행합니다.
구현 AllowedImpersonationLevel을(를) Delegation로 설정하여 위임합니다.
SSPI 협상이 필요합니다.
표준 바인딩을 사용하는 경우 속성을
NegotiateServiceCredential
.로 설정합니다true
.사용자 지정 바인딩을 사용하는 경우
AuthenticationMode
요소의Security
특성을SspiNegotiated
로 설정합니다.
NTLM 사용을 허용하지 않음으로써 Kerberos를 사용하려면 SSPI 협상이 필요합니다.
다음 문을 사용하여 코드에서 이 작업을 수행합니다.
ChannelFactory.Credentials.Windows.AllowNtlm = false
구성 파일에서
allowNtlm
특성을false
로 설정하여 이 작업을 수행할 수 있습니다. 이 특성은 창<에 포함되어 있습니다>.
NTLM 프로토콜
협상 SSP가 NTLM으로 되돌아가지만 NTLM이 비활성화되어 있습니다.
AllowNtlm 속성은 false
으로 설정되어 NTLM을 사용하는 경우 WCF(Windows Communication Foundation)가 예외를 발생시키기 위해 최선을 다하도록 합니다. 이 속성을 false
으로 설정해도 NTLM 자격 증명의 네트워크 전송을 방지하지 못할 수 있습니다.
다음은 NTLM에 대한 대체를 사용하지 않도록 설정하는 방법을 보여줍니다.
CalculatorClient cc = new
CalculatorClient("WSHttpBinding_ICalculator");
cc.ClientCredentials.Windows.AllowNtlm = false;
Dim cc As New CalculatorClient("WSHttpBinding_ICalculator")
cc.ClientCredentials.Windows.AllowNtlm = False
NTLM 로그온 실패
클라이언트 자격 증명이 서비스에서 유효하지 않습니다. 사용자 이름과 암호가 올바르게 설정되었는지 확인하고 서비스가 실행 중인 컴퓨터에 알려진 계정에 해당합니다. NTLM은 지정된 자격 증명을 사용하여 서비스의 컴퓨터에 로그온합니다. 자격 증명은 클라이언트가 실행 중인 컴퓨터에서 유효할 수 있지만, 자격 증명이 서비스 컴퓨터에서 유효하지 않으면 이 로그온이 실패합니다.
익명 NTLM 로그온이 발생하지만 익명 로그온은 기본적으로 사용하지 않도록 설정됩니다.
클라이언트 AllowedImpersonationLevel 를 만들 때 속성은 다음 예제와 같이 설정 Anonymous되지만 기본적으로 서버는 익명 로그온을 허용하지 않습니다. 클래스 AllowAnonymousLogons의 속성 WindowsServiceCredential의 기본값이 false
이기 때문에 발생합니다.
다음 클라이언트 코드는 익명 로그온을 사용하려고 시도합니다(기본 속성은 Identification
).
CalculatorClient cc =
new CalculatorClient("WSHttpBinding_ICalculator");
cc.ClientCredentials.Windows.AllowedImpersonationLevel =
System.Security.Principal.TokenImpersonationLevel.Anonymous;
Dim cc As New CalculatorClient("WSHttpBinding_ICalculator")
cc.ClientCredentials.Windows.AllowedImpersonationLevel = _
System.Security.Principal.TokenImpersonationLevel.Anonymous
다음 서비스 코드는 서버에서 익명 로그온을 사용하도록 기본값을 변경합니다.
Uri httpUri = new Uri("http://localhost:8000/");
ServiceHost sh = new ServiceHost(typeof(Calculator), httpUri);
sh.Credentials.WindowsAuthentication.AllowAnonymousLogons = true;
Dim httpUri As New Uri("http://localhost:8000/")
Dim sh As New ServiceHost(GetType(Calculator), httpUri)
sh.Credentials.WindowsAuthentication.AllowAnonymousLogons = True
가장 행위에 대한 자세한 내용은 위임 및 가장을 참조하세요.
또는 기본 제공 계정 SYSTEM을 사용하여 클라이언트가 Windows 서비스로 실행됩니다.
기타 문제
클라이언트 자격 증명이 올바르게 설정되지 않음
Windows 인증은 WindowsClientCredential 클래스의 ClientCredentials 속성에서 반환된 ClientBase<TChannel> 인스턴스를 사용하며, UserNamePasswordClientCredential는 사용하지 않습니다. 다음은 잘못된 예제를 보여줍니다.
CalculatorClient cc = new
CalculatorClient("WSHttpBinding_ICalculator");
cc.ClientCredentials.UserName.UserName = GetUserName(); // wrong!
cc.ClientCredentials.UserName.Password = GetPassword(); // wrong!
Dim cc As New CalculatorClient("WSHttpBinding_ICalculator")
cc.ClientCredentials.UserName.UserName = GetUserName() ' wrong!
cc.ClientCredentials.UserName.Password = GetPassword() ' wrong!
다음은 올바른 예제입니다.
CalculatorClient cc = new
CalculatorClient("WSHttpBinding_ICalculator");
// This code returns the WindowsClientCredential type.
cc.ClientCredentials.Windows.ClientCredential.UserName = GetUserName();
cc.ClientCredentials.Windows.ClientCredential.Password = GetPassword();
Dim cc As New CalculatorClient("WSHttpBinding_ICalculator")
' This code returns the WindowsClientCredential type.
cc.ClientCredentials.Windows.ClientCredential.UserName = GetUserName()
cc.ClientCredentials.Windows.ClientCredential.Password = GetPassword()
SSPI를 사용할 수 없음
다음 운영 체제는 서버로 사용되는 경우 Windows 인증을 지원하지 않습니다. Windows XP Home Edition, Windows XP Media Center Edition 및 Windows Vista Home Edition.
다른 ID를 사용하여 개발 및 배포
한 컴퓨터에서 애플리케이션을 개발하고 다른 컴퓨터에 배포하고 다른 계정 유형을 사용하여 각 컴퓨터에서 인증하는 경우 다른 동작이 발생할 수 있습니다. 예를 들어 인증 모드를 사용하여 Windows XP Pro 컴퓨터에서 애플리케이션을 개발한다고 SSPI Negotiated
가정해 보겠습니다. 로컬 사용자 계정을 사용하여 인증하는 경우 NTLM 프로토콜이 사용됩니다. 애플리케이션이 개발되면 도메인 계정으로 실행되는 Windows Server 2003 컴퓨터에 서비스를 배포합니다. 이 시점에서 클라이언트는 Kerberos 및 도메인 컨트롤러를 사용하므로 서비스를 인증할 수 없습니다.