方法 : カスタム ユーザー名およびパスワード検証を使用する
Windows Communication Foundation (WCF) では、認証にユーザー名とパスワードを使用すると、既定の Windows 認証を使用してユーザー名とパスワードが検証されます。ただし、WCF では、"検証コントロール" と呼ばれるカスタムのユーザー名/パスワード認証方式を使用できます。ユーザー名およびパスワードのカスタム検証を組み込むには、UserNamePasswordValidator から派生するクラスを作成して構成します。
サンプル アプリケーションについては、「ユーザー名パスワード検証」を参照してください。
カスタムのユーザー名/パスワード検証コントロールを作成するには
UserNamePasswordValidator から派生するクラスを作成します。
Public Class CustomUserNameValidator Inherits UserNamePasswordValidator
public class CustomUserNameValidator : UserNamePasswordValidator {
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"); } }
カスタムのユーザー名/パスワード検証コントロールを使用するようにサービスを構成するには
任意のトランスポート上のメッセージ セキュリティ、または HTTP(S) 上のトランスポート レベル セキュリティを使用するバインディングを構成します。
メッセージ セキュリティを使用する場合は、メッセージ セキュリティと UserName 資格情報の種類をサポートするシステム指定のバインディングのいずれか (wsHttpBinding Element や customBinding Element など) を追加します。
HTTP(S) 上のトランスポート レベル セキュリティを使用する場合は、wsHttpBinding Element と <basicHttpBinding> のいずれか、<netTcpBinding>、または HTTP(S) と Basic 認証方式を使用する customBinding Element を追加します。
注 :
.NET Framework Version 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 セキュリティ トークンのユーザー名とパスワードの組み合わせを検証する際に、カスタムのユーザー名/パスワード検証コントロールを使用することを指定する動作を構成します。
<system.serviceModel> 要素の子として <behaviors> 要素を追加します。
serviceBehaviors section を <behaviors> 要素に追加します。
<behavior> 要素を追加し、name 属性に適切な値を設定します。
<serviceCredentials> Elementを <behavior> 要素に追加します。
<serviceCredentials> Elementに userNameAuthentication 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");
}
}
}
参照
処理手順
方法 : ASP.NET メンバーシップ プロバイダーを使用する