방법: 사용자 지정 사용자 이름 및 암호 유효성 검사기 사용
기본적으로 사용자 이름과 암호가 인증에 사용될 때, WCF(Windows Communication Foundation)에서는 Windows를 사용하여 사용자 이름과 암호의 유효성을 검사합니다. 그러나 WCF에서는 유효성 검사기라고도 하는 사용자 지정 사용자 이름 및 암호 인증 스키마를 허용합니다. 사용자 지정 사용자 이름 및 암호 유효성 검사기를 통합하려면 UserNamePasswordValidator에서 파생되는 클래스를 만들어 구성합니다.
샘플 응용 프로그램을 보려면 User Name Password Validator를 참조하십시오.
사용자 지정 사용자 이름 및 암호 유효성 검사기를 만들려면
UserNamePasswordValidator에서 파생되는 클래스를 만듭니다.
Public Class CustomUserNameValidator Inherits UserNamePasswordValidator
public class CustomUserNameValidator : UserNamePasswordValidator {
Validate 메서드를 재정의하여 사용자 지정 인증 스키마를 구현합니다.
다음 예제에서는 프로덕션 환경에서 Validate 메서드를 재정의하는 코드를 사용하지 않습니다. 코드를 사용자 지정 사용자 이름 및 암호 유효성 검사 스키마로 바꿉니다. 이 스키마는 데이터베이스에서 사용자 이름과 암호 쌍을 검색합니다.
인증 오류를 다시 클라이언트에 반환하려면 Validate 메서드에서 FaultException을 throw합니다.
' This method validates users. It allows in two users, test1 and test2 ' with passwords 1tset and 2tset respectively. ' This code is for illustration purposes only and ' must not be used in a production environment because it is not secure. Public Overrides Sub Validate(ByVal userName As String, ByVal password As String) If Nothing = userName OrElse Nothing = password Then Throw New ArgumentNullException() End If If Not (userName = "test1" AndAlso password = "1tset") AndAlso Not (userName = "test2" AndAlso password = "2tset") Then ' This throws an informative fault to the client. Throw New FaultException("Unknown Username or Incorrect Password") ' When you do not want to throw an infomative fault to the client, ' throw the following exception. ' Throw New SecurityTokenException("Unknown Username or Incorrect Password") End If End Sub
// This method validates users. It allows in two users, test1 and test2 // with passwords 1tset and 2tset respectively. // This code is for illustration purposes only and // must not be used in a production environment because it is not secure. public override void Validate(string userName, string password) { if (null == userName || null == password) { throw new ArgumentNullException(); } if (!(userName == "test1" && password == "1tset") && !(userName == "test2" && password == "2tset")) { // This throws an informative fault to the client. throw new FaultException("Unknown Username or Incorrect Password"); // When you do not want to throw an infomative fault to the client, // throw the following exception. // throw new SecurityTokenException("Unknown Username or Incorrect Password"); } }
사용자 지정 사용자 이름 및 암호 유효성 검사기를 사용하도록 서비스를 구성하려면
HTTP(S)를 통해 전송 또는 전송 수준 보안에서 메시지 보안을 사용하는 바인딩을 구성합니다.
메시지 보안을 사용하는 경우 메시지 보안 및 UserName 자격 증명 형식을 지원하는 wsHttpBinding Element 또는 customBinding Element처럼 시스템 제공 바인딩 중 하나를 추가합니다.
HTTP(S)를 통해 전송 수준 보안을 사용하는 경우 wsHttpBinding Element나 <basicHttpBinding> 또는 HTTP(S) 및 Basic 인증 체계를 사용하는 <netTcpBinding> 또는 customBinding Element를 추가합니다.
참고:
.NET Framework 버전 3.5 이상을 사용하는 경우 메시지 및 전송 보안과 함께 사용자 지정 사용자 이름 및 암호 유효성 검사기를 사용할 수 있습니다. .NET Framework 3.0를 사용하는 경우에는 메시지 보안에서만 사용자 지정 사용자 이름 및 암호 유효성 검사기를 사용할 수 있습니다. 팁:
이 컨텍스트에서 <netTcpBinding>을 사용하는 방법은 <security> of <netTcpBinding>를 참조하십시오. 구성 파일에서 <system.ServiceModel> 요소 아래에 <bindings> 요소를 추가합니다.
wsHttpBinding Element 또는 <basicHttpBinding> 요소를 바인딩 섹션에 추가합니다. WCF 바인딩 요소 만들기에 대한 자세한 내용은 방법: 구성에서 서비스 바인딩 지정을 참조하십시오.
security element of wsHttpBinding 또는 <security> of <basicHttpBinding>의 mode 특성을 Message, Transport 또는 TransportWithMessageCredential로 설정합니다.
message element of wsHttpBinding 또는 <transport> of <wsHttpBinding>의 clientCredentialType 특성을 설정합니다.
메시지 보안을 사용하는 경우 message element of wsHttpBinding의 clientCredentialType 특성을 UserName으로 설정합니다.
HTTP(S)를 통해 전송 수준 보안을 사용하는 경우 <transport> of <wsHttpBinding> 또는 <transport> of <basicHttpBinding>의 clientCredentialType 특성을 Basic으로 설정합니다.
참고:
WCF 서비스가 전송 수준 보안을 사용하여 IIS(인터넷 정보 서비스)에서 호스팅되고 UserNamePasswordValidationMode 속성이 Custom으로 설정되는 경우 사용자 지정 인증 스키마에서는 Windows 인증의 하위 집합을 사용합니다. 이 시나리오의 경우 WCF에서 사용자 지정 인증자를 호출하기 전에 IIS에서 Windows 인증을 수행하기 때문입니다.
WCF 바인딩 요소 만들기에 대한 자세한 내용은 방법: 구성에서 서비스 바인딩 지정을 참조하십시오.
다음 예제에서는 바인딩에 대한 구성 코드를 보여 줍니다.
<system.serviceModel> <bindings> <wsHttpBinding> <binding name="Binding1"> <security mode="Message"> <message clientCredentialType="UserName" /> </security> </binding> </wsHttpBinding> </bindings> </system.serviceModel>
사용자 지정 사용자 이름 및 암호 유효성 검사기를 사용하여 들어오는 UserNameSecurityToken 보안 토큰에 대한 사용자 이름과 암호 쌍의 유효성을 검사하도록 지정하는 동작을 구성합니다.
<behaviors> 요소를 <system.serviceModel> 요소에 대한 자식으로 추가합니다.
serviceBehaviors section를 <behaviors> 요소에 추가합니다.
<behavior> 요소를 추가하고 name 특성을 적절한 값으로 설정합니다.
<serviceCredentials> Element를 <behavior> 요소에 추가합니다.
userNameAuthentication element를 <serviceCredentials> Element에 추가합니다.
userNamePasswordValidationMode를 Custom으로 설정합니다.
참고:
userNamePasswordValidationMode 값이 설정되어 있지 않으면 WCF에서는 사용자 지정 사용자 이름 및 암호 유효성 검사기 대신 Windows 인증을 사용합니다. customUserNamePasswordValidatorType을 사용자 지정 사용자 이름 및 암호 유효성 검사기를 나타내는 형식으로 설정합니다.
다음 예제에서는 이 지점에 대한 <serviceCredentials> 단편을 보여 줍니다.
<serviceCredentials> <userNameAuthentication userNamePasswordValidationMode="Custom" customUserNamePasswordValidatorType="Microsoft.ServiceModel.Samples.CalculatorService.CustomUserNameValidator, service" /> </serviceCredentials>
예제
다음 코드 예제에서는 사용자 지정 사용자 이름 및 암호 유효성 검사기를 만드는 방법을 보여 줍니다. 프로덕션 환경에서는 Validate 메서드를 재정의하는 코드를 사용하지 않습니다. 코드를 사용자 지정 사용자 이름 및 암호 유효성 검사 스키마로 바꿉니다. 이 스키마는 데이터베이스에서 사용자 이름과 암호 쌍을 검색합니다.
Imports System
Imports System.IdentityModel.Selectors
Imports System.IdentityModel.Tokens
Imports System.Security.Principal
Imports System.ServiceModel
...
Public Class CustomUserNameValidator
Inherits UserNamePasswordValidator
' This method validates users. It allows in two users, test1 and test2
' with passwords 1tset and 2tset respectively.
' This code is for illustration purposes only and
' must not be used in a production environment because it is not secure.
Public Overrides Sub Validate(ByVal userName As String, ByVal password As String)
If Nothing = userName OrElse Nothing = password Then
Throw New ArgumentNullException()
End If
If Not (userName = "test1" AndAlso password = "1tset") AndAlso Not (userName = "test2" AndAlso password = "2tset") Then
' This throws an informative fault to the client.
Throw New FaultException("Unknown Username or Incorrect Password")
' When you do not want to throw an infomative fault to the client,
' throw the following exception.
' Throw New SecurityTokenException("Unknown Username or Incorrect Password")
End If
End Sub
End Class
using System;
using System.IdentityModel.Selectors;
using System.IdentityModel.Tokens;
using System.Security.Principal;
using System.ServiceModel;
...
public class CustomUserNameValidator : UserNamePasswordValidator
{
// This method validates users. It allows in two users, test1 and test2
// with passwords 1tset and 2tset respectively.
// This code is for illustration purposes only and
// must not be used in a production environment because it is not secure.
public override void Validate(string userName, string password)
{
if (null == userName || null == password)
{
throw new ArgumentNullException();
}
if (!(userName == "test1" && password == "1tset") && !(userName == "test2" && password == "2tset"))
{
// This throws an informative fault to the client.
throw new FaultException("Unknown Username or Incorrect Password");
// When you do not want to throw an infomative fault to the client,
// throw the following exception.
// throw new SecurityTokenException("Unknown Username or Incorrect Password");
}
}
}