カスタム JASPI 認証プロバイダーの開発
JSR 196: Java™ Authentication Service Provider Interface for Containers 仕様に示されている必要なインターフェースを実装するクラスを作成することにより、カスタム Java Authentication SPI for Containers (JASPI) 認証プロバイダーを開発できます。
始める前に
JSR 196: Java Authentication Service Provider Interface for Containers 仕様で、JASPI 認証プロバイダーおよびモジュール用の特定のインターフェース実装要件を確認します。
このタスクについて
WebSphere® Application Server は、Java Authentication SPI for Containers (JASPI) Version 1.1 で指定されているサーブレット・コンテナー・プロファイルに準拠するサード・パーティーの認証プロバイダーの使用をサポートします。
サーブレット・コンテナー・プロファイルは、WebSphere Application Server の Web コンテナーと連携しているセキュリティー・ランタイム環境で使用されるインターフェースを定義して、アプリケーションにより Web 要求が処理される前後に認証モジュールを起動します。JASPI がセキュリティー構成内で使用可能になっていて、構成された JASPI プロバイダーが、受信した Web 要求を処理する Web モジュールに関連付けられている場合にのみ、JASPI モジュールを使用した認証が実行されます。
カスタム認証プロバイダーを開発するには、JSR 196: Java Authentication Service Provider Interface for Containers 仕様に示されている必要なインターフェースを実装するクラスを作成します。プロバイダーは 1 つ以上の認証モジュールを認証に使用できます。モジュールはコールバックを使用して認証を実行できます。あるいは、必要なユーザー ID 情報をクライアント・サブジェクトに手動で追加できます。 プロバイダーの有効範囲に応じて、アプリケーション・サーバーのさまざまなロケーションに実装クラスを保管できます。
手順
- javax.security.auth.message.config.AuthConfigProvider インターフェースを実装するクラスを作成します。 AuthConfigProvider 実装クラスでは、以下のように 2 つの引数を取る public コンストラクター、および getServerAuthConfig public メソッドを定義する必要があります。
import java.util.Map; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.message.AuthException; import javax.security.auth.message.config.AuthConfigFactory; import javax.security.auth.message.config.AuthConfigProvider; import javax.security.auth.message.config.ServerAuthConfig; public class SampleAuthConfigProvider implements AuthConfigProvider { public SampleAuthConfigProvider(Map<String, String> properties, AuthConfigFactory factory) { ... } public ServerAuthConfig getServerAuthConfig(String layer, String appContext, CallbackHandler handler) throws AuthException { ... } }
AuthConfigProvider 実装クラスのインスタンスは、アプリケーションの Web モジュールに処理される要求が到着したときに、WebSphere Application Server に使用されます。getServerAuthConfig メソッドは ServerAuthConfig インスタンスを取得するために使用されます。メソッド呼び出しの CallbackHandler 引数は認証モジュールに使用されます。
- javax.security.auth.message.config.ServerAuthConfig インターフェースを実装するクラスを作成します。 ServerAuthConfig 実装クラスでは、以下のように getAuthContextID および getAuthContext public メソッドを定義する必要があります。
import java.util.Map; import javax.security.auth.Subject; import javax.security.auth.message.AuthException; import javax.security.auth.message.MessageInfo; import javax.security.auth.message.config.ServerAuthConfig; import javax.security.auth.message.config.ServerAuthContext; public class SampleServerAuthConfig implements ServerAuthConfig { public String getAuthContextID(MessageInfo messageInfo) throws IllegalArgumentException { ... } public ServerAuthContext getAuthContext(String authContextID, Subject serviceSubject, Map properties) throws AuthException { ... } }
ServerAuthConfig 実装クラスの getAuthContextID および getAuthContext メソッドは、ServerAuthContext インスタンスを取得するために使用されます。
- javax.security.auth.message.config.ServerAuthContext インターフェースを実装するクラスを作成します。 ServerAuthContext 実装クラスでは、以下のように validateRequest および secureResponse public メソッドを定義する必要があります。
import javax.security.auth.Subject; import javax.security.auth.message.AuthException; import javax.security.auth.message.AuthStatus; import javax.security.auth.message.MessageInfo; import javax.security.auth.message.config.ServerAuthContext; public class SampleServerAuthContext implements ServerAuthContext { public AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject) throws AuthException { ... } public AuthStatus secureResponse(MessageInfo messageInfo, Subject serviceSubject) throws AuthException { ... } }
ServerAuthContext 実装クラスの validateRequest メソッドは、受信した Web 要求メッセージを認証するモジュールを起動するために使用されます。認証結果が成功の場合、Web コンテナーは、ターゲット Web モジュールがアプリケーション内で処理する、受信した Web 要求メッセージをディスパッチします。認証結果が成功ではない場合、要求は拒否され、該当する応答状況が示されます。
- javax.security.auth.message.module.ServerAuthModule インターフェースを実装するクラスを作成します。 ServerAuthModule 実装クラスでは、以下のように initialize、validateRequest、および secureResponse public メソッドを定義する必要があります。
import javax.security.auth.Subject; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.message.AuthException; import javax.security.auth.message.AuthStatus; import javax.security.auth.message.MessageInfo; import javax.security.auth.message.MessagePolicy; import javax.security.auth.message.module.ServerAuthModule; public class SampleAuthModule implements ServerAuthModule { public void initialize(MessagePolicy requestPolicy, MessagePolicy responsePolicy, CallbackHandler handler, Map options) throws AuthException { ... } public AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject) throws AuthException { ... } public AuthStatus secureResponse(MessageInfo messageInfo, Subject serviceSubject) throws AuthException { ... } }
ServerAuthModule 実装クラスの initialize メソッドは、ServerAuthContext 実装クラスにより呼び出され、認証モジュールを初期化して ServerAuthContext インスタンスに関連付けます。
このクラスの validateRequest および secureResponse メソッドはそれぞれ、受信した javax.security.auth.message.MessageInfo に含まれる javax.servlet.http.HttpServletRequest および javax.servlet.http.HttpServletResponse を認証するために使用されます。 これらのメソッドは、initialize メソッドで受信された CallbackHandler インスタンスを使用し、WebSphere セキュリティー・ランタイムと対話してユーザー・パスワードを検証したり、アクティブ・ユーザー・レジストリーと対話してユーザーの固有 ID およびメンバーシップ・グループを取得したりできます。取得したデータは、クライアント・サブジェクトのプライベート・クレデンシャル・セットの Hashtable に保管されます。WebSphere Application Server での CallbackHandler の実装は、以下の 3 つのコールバックをサポートします。- CallerPrincipalCallback
- GroupPrincipalCallback
- PasswordValidationCallback
CallbackHandler が認証モジュールに使用されずに validateRequest が成功状況を戻した場合、WebSphere Application Server では、カスタム・ログインを実行してユーザーのクレデンシャルを取得できるように、Hashtable インスタンスがユーザー ID 情報を備えた clientSubject に含まれている必要があります。以下の例のように、この Hashtable をクライアント・サブジェクトに追加することができます。import java.util.Hashtable; import java.util.String; import javax.security.auth.Subject; import javax.security.auth.message.AuthException; import javax.security.auth.message.AuthStatus; import javax.security.auth.message.MessageInfo; import com.ibm.wsspi.security.registry.RegistryHelper; import com.ibm.wsspi.security.token.AttributeNameConstants.AttributeNameConstants; public AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject) throws AuthException { ... UserRegistry reg = RegistryHelper.getUserRegistry(null); String uniqueid = reg.getUniqueUserID(username); Hashtable hashtable = new Hashtable(); hashtable.put(AttributeNameConstants.WSCREDENTIAL_UNIQUEID, uniqueid); hashtable.put(AttributeNameConstants.WSCREDENTIAL_SECURITYNAME, username); hashtable.put(AttributeNameConstants.WSCREDENTIAL_PASSWORD, password); hashtable.put(AttributeNameConstants.WSCREDENTIAL_GROUPS, groupList); //optional clientSubject.getPrivateCredentials().add(hashtable); ... }
Hashtable 要件およびカスタム・ログインについて詳しくは、『JAAS のシステム・ログイン構成用のカスタム・ログイン・モジュールの開発』を参照してください。
Java Servlet 3.0 仕様の認証メソッドをサポートするには、以下のロジックを ServerAuthModule 実装クラスの validateRequest メソッドに追加する必要があります。import java.util.Map; import javax.security.auth.Subject; import javax.security.auth.message.AuthException; import javax.security.auth.message.AuthStatus; import javax.security.auth.message.MessageInfo; import javax.servlet.http.HttpServletRequest; public AuthStatus validateRequest(MessageInfo messageInfo, Subject clientSubject, Subject serviceSubject) throws AuthException { ... Map msgMap = messageInfo.getMap(); if ("authenticate".equalsIgnoreCase(msgMap.get("com.ibm.websphere.jaspi.request"))) { // this request is for the authenticate method String authHeader = ((HttpServletRequest) messageInfo.getRequestMessage()).getHeader("Authorization"); if (authHeader == null) { // The user has not provided a username and password yet, return // AuthStatus.SEND_CONTINUE to challenge } else { // Authenticate using the user name and password in the authentication header. } } else { // This is not a Servlet 3.0 authenticate request; handle as usual. } ... }
- 新規に作成したクラスをすべてコンパイルします。 新規クラスを正常にコンパイルするため、WebSphere Application Server インストール済み環境にある以下の JAR ファイルをクラスパスに指定する必要があります。
- app_server_root/dev/JavaEE/j2ee.jar
- app_server_root/dev/was_public.jar (WebSphere のパブリック API が使用されている場合)
- コンパイルされたクラスを使用して JAR ファイルを作成します。 要件に応じて、JAR ファイルを以下の 3 つのロケーションのいずれかに格納できます。
- app_server_root/lib
このロケーションは常に、WebSphere Application Server クラス・ローダーのクラスパス上にあります。 このロケーションを使用して、すべての Web モジュールおよびアプリケーションに対するセルまたはドメインのデフォルト・プロバイダーとして、一連の Web モジュールまたはアプリケーションにプロバイダーを登録することができ、このプロバイダーを手動でパーシスタント・プロバイダーとして登録できます。
- 共有ライブラリー
プロバイダー JAR ファイルを WebSphere Application Server システムの任意の場所に格納します。JAR を指している共有ライブラリーを構成して、その共有ライブラリーをアプリケーションまたはサーバーのクラスパスに追加します。共有ライブラリーでは、一連の Web モジュールまたはアプリケーションにプロバイダーを登録できますが、このプロバイダーはセルまたはドメインのデフォルト・プロバイダーとして使用できません。また、サーバー始動中は共有ライブラリーがプロバイダー登録用のクラスパス内にないため、パーシスタント・プロバイダーとして登録することもできません。共有ライブラリーの構成について詳しくは、『共有ライブラリーの作成』を参照してください。
- アプリケーション内に組み込む
プロバイダー JAR ファイルをユーティリティー JAR としてアプリケーションの EAR ファイルに組み込むか、コンパイルされたクラス・ファイルを Web モジュール WAR に組み込みます。クラスが Web モジュールのクラスパスに含まれている限り、アプリケーションの Web モジュールに組み込みプロバイダーを登録することができます。このプロバイダーは、セルまたはドメインのデフォルト・プロバイダーとして使用できず、パーシスタント・プロバイダーとして登録することもできません。アプリケーションのクラスは、サーバー始動中はプロバイダー登録に使用できません。
- app_server_root/lib
- 管理コンソールまたは管理スクリプトを使用して、セキュリティー構成のプロバイダーを構成します。
詳しくは、 管理コンソールを使用した新規 JASPI 認証プロバイダーの構成 または AdminTask オブジェクトの JaspiManagement コマンド・グループを参照してください。


http://www14.software.ibm.com/webapp/wsbroker/redirect?version=cord&product=was-nd-mp&topic=tsec_jaspi_develop
ファイル名:tsec_jaspi_develop.html