方法 : カスタム ユーザー名およびパスワード検証を使用する

Windows Communication Foundation (WCF) では、認証にユーザー名とパスワードを使用すると、既定の Windows 認証を使用してユーザー名とパスワードが検証されます。ただし、WCF では、"検証コントロール" と呼ばれるカスタムのユーザー名/パスワード認証方式を使用できます。ユーザー名およびパスワードのカスタム検証を組み込むには、UserNamePasswordValidator から派生するクラスを作成して構成します。

サンプル アプリケーションについては、「ユーザー名パスワード検証」を参照してください。

カスタムのユーザー名/パスワード検証コントロールを作成するには

  1. UserNamePasswordValidator から派生するクラスを作成します。

    Public Class CustomUserNameValidator
        Inherits UserNamePasswordValidator
    
    public class CustomUserNameValidator : UserNamePasswordValidator
    {
    
  2. Validate メソッドをオーバーライドして、カスタム認証方式を実装します。

    次の例のコードは、Validate メソッドをオーバーライドします。稼働環境では、このようなコードを使用しないでください。このコードをカスタムのユーザー名/パスワード検証方式に置き換えます。この場合、ユーザー名とパスワードの組み合わせをデータベースから取得する必要があります。

    クライアントに認証エラーを返すには、Validate メソッドで FaultException をスローします。

    ' 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");
        }
    }
    

カスタムのユーザー名/パスワード検証コントロールを使用するようにサービスを構成するには

  1. 任意のトランスポート上のメッセージ セキュリティ、または HTTP(S) 上のトランスポート レベル セキュリティを使用するバインディングを構成します。

    メッセージ セキュリティを使用する場合は、メッセージ セキュリティと UserName 資格情報の種類をサポートするシステム指定のバインディングのいずれか (wsHttpBinding ElementcustomBinding Element など) を追加します。

    HTTP(S) 上のトランスポート レベル セキュリティを使用する場合は、wsHttpBinding Element<basicHttpBinding> のいずれか、<netTcpBinding>、または HTTP(S) と Basic 認証方式を使用する customBinding Element を追加します。

    Aa702565.note(ja-jp,VS.100).gif注 :
    .NET Framework Version 3.5 以降を使用する場合は、メッセージおよびトランスポート セキュリティでカスタムのユーザー名/パスワード検証コントロールを使用できます。.NET Framework 3.0 では、カスタムのユーザー名/パスワード検証コントロールを使用できるのは、メッセージ セキュリティだけです。

    Aa702565.Tip(ja-jp,VS.100).gifヒント :
    このコンテキストでの <netTcpBinding> の使用方法の詳細については、「<security> of <netTcpBinding>」を参照してください。

    1. 構成ファイルの <system.ServiceModel> 要素の下に、<bindings> 要素を追加します。

    2. バインディング セクションに、wsHttpBinding Elementまたは <basicHttpBinding> 要素を追加します。WCF のバインド要素の作成詳細情報、「方法 : 構成でサービス バインディングを指定する」を参照してください。

    3. security element of wsHttpBindingまたは <security> of <basicHttpBinding>mode 属性を MessageTransport、または TransportWithMessageCredential に設定します。

    4. message element of wsHttpBindingまたは <transport> of <wsHttpBinding>clientCredentialType 属性を設定します。

      メッセージ セキュリティを使用する場合は、message element of wsHttpBindingclientCredentialType 属性を UserName に設定します。

      HTTP(S) 上でトランスポート レベルのセキュリティを使用する場合は、<transport> of <wsHttpBinding> または <transport> of <basicHttpBinding>clientCredentialType 属性を Basic に設定します。

      Aa702565.note(ja-jp,VS.100).gif注 :
      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>
    
  2. 受信 UserNameSecurityToken セキュリティ トークンのユーザー名とパスワードの組み合わせを検証する際に、カスタムのユーザー名/パスワード検証コントロールを使用することを指定する動作を構成します。

    1. <system.serviceModel> 要素の子として <behaviors> 要素を追加します。

    2. serviceBehaviors section<behaviors> 要素に追加します。

    3. <behavior> 要素を追加し、name 属性に適切な値を設定します。

    4. <serviceCredentials> Element<behavior> 要素に追加します。

    5. <serviceCredentials> ElementuserNameAuthentication elementを追加します。

    6. userNamePasswordValidationModeCustom に設定します。

      Aa702565.Important(ja-jp,VS.100).gif 注 :
      userNamePasswordValidationMode 値が設定されていない場合、WCF では、カスタムのユーザー名/パスワード検証コントロールの代わりに Windows 認証が使用されます。

    7. 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");
                }
            }
        }

参照

処理手順

方法 : ASP.NET メンバーシップ プロバイダーを使用する

リファレンス

UserNamePasswordValidator

その他のリソース

認証