プライマリ・コンテンツに移動
Oracle® Fusion Middleware Oracle WebLogic Serverセキュリティ・プロバイダの開発 12c
12c (12.2.1.3.0)
E90323-01
目次へ移動
目次

前
次

5 IDアサーション・プロバイダ

この章では、IDアサーション・プロバイダの概念と機能、およびカスタムIDアサーション・プロバイダの開発手順について説明します。

IDアサーション・プロバイダは、ユーザーまたはシステム・プロセスがトークンを使用してそれぞれのIDをアサートする特殊な形態(つまり境界認証)の認証プロバイダです。IDアサーション・プロバイダは、境界認証を可能にし、シングル・サインオンをサポートします。IDアサーション・プロバイダ用のLoginModuleを作成すれば、認証プロバイダのかわりにIDアサーション・プロバイダを使用できます。また、認証プロバイダのLoginModuleを使用する場合は、認証プロバイダに加えてIDアサーション・プロバイダも使用できます。

IDアサーション・プロバイダを認証プロバイダとは別に構成できるようにするには、2つのプロバイダを作成します。IDアサーション・プロバイダと認証プロバイダが独立して機能できない場合は、1つのプロバイダを作成します。

この章の内容は次のとおりです。

IDアサーションの概念

IDアサーション・プロバイダを開発する前に、次の概念を理解しておく必要があります。

IDアサーション・プロバイダとLoginModule

LoginModuleと一緒に用いると、IDアサーション・プロバイダはシングル・サインオンをサポートします。たとえば、IDアサーション・プロバイダは、デジタル証明書からトークンを生成できます。そのトークンはシステム内で順に回すことができ、ユーザーが何度もサインオンを求められないようにすることができます。

IDアサーション・プロバイダが使用するLoginModuleでは、次のことが可能です。

単純認証の場合とは異なり(「認証プロセス」を参照)、IDアサーション・プロバイダが使用するLoginModuleは証明情報(ユーザー名やパスワードなど)を検証しません(単にユーザーが存在することを検証するだけです)。

この構成のLoginModuleは以下の処理を行う必要があります。

  • WLSGroup型などの必須のプリンシパルをサブジェクトに格納します。

  • ユーザーがログインのための十分な証明を提供していると見なし、パスワードなどの証明データを要求しません。

「AuthenticationProviderV2 SSPIの実装」の説明に従って、カスタム認証プロバイダにAuthenticationProviderV2.getAssertionModuleConfigurationメソッドを実装する必要がありますこのメソッドは、X.509証明書を使用している場合などに、IDアサーションがデプロイメント記述子のrun-asタグを処理するために呼び出されます。他のシングル・サインオン方式でも、このメソッドを使用します。

注意:

「LoginModules」を参照してください。

IDアサーションとトークン

IDアサーション・プロバイダは、ユーザーまたはシステム・プロセスのIDをアサートするために使用する特定のトークン・タイプをサポートするために開発します。IDアサーション・プロバイダは複数のトークン・タイプをサポートするように開発できますが、通常はただ1つのアクティブなトークン・タイプを検証するように構成されます。同じトークン・タイプを検証する機能を備えた複数のIDアサーション・プロバイダを1つのセキュリティ・レルムに組み込むことも可能ですが、実際に検証を行うのは1つのIDアサーション・プロバイダだけです。

注意:

トークン・タイプをサポートするということは、IDアサーション・プロバイダのランタイム・クラス(IdentityAsserter SSPI実装)がそのassertIdentityメソッドでトークン・タイプを検証できるということです。「IdentityAsserterV2 SSPIの実装」を参照してください。

以下の節では、新しいトークン・タイプを使用するための手順について説明します。

新しいトークン・タイプの作成方法

カスタムIDアサーション・プロバイダを開発する場合には、新しいトークン・タイプも作成できます。トークン・タイプとは、文字列で表される1つのデータに過ぎません。どのようなトークン・タイプを作成して使用するかは、完全にユーザーに任されています。たとえば、現在WebLogic IDアサーション・プロバイダ用に定義されているトークンには、AuthenticatedUserX.509CSI.PrincipalNameCSI.ITTAnonymousCSI.X509CertChainCSI.DistinguishedNamewsse:PasswordDigestなど、様々なタイプがあります。

新しいトークン・タイプを作成するには、例5-1に示すとおり、新しいJavaファイルを作成し、String型の変数として新しいトークン・タイプを宣言します。PerimeterIdentityAsserterTokenTypes.javaファイルでは、Test 1Test 2、およびTest 3というトークン・タイプの名前が文字列として定義されています。

注意:

新しいトークン・タイプを1つだけ定義する場合は、例5-4で示されているようにIDアサーション・プロバイダのランタイム・クラスで行うこともできます。

例5-1 PerimeterIdentityAsserterTokenTypes.java

package sample.security.providers.authentication.perimeterATN;
public class PerimeterIdentityAsserterTokenTypes
{
   public final static String TEST1_TYPE = 'Test 1";
   public final static String TEST2_TYPE = 'Test 2";
   public final static String TEST3_TYPE = 'Test 3";
}

新しいトークン・タイプをIDアサーション・プロバイダの構成で利用可能にする方法

カスタムIDアサーション・プロバイダを構成する場合(「管理コンソールによるカスタムIDアサーション・プロバイダの構成」を参照)、IDアサーション・プロバイダのサポートするトークン・タイプのリストが「サポートされている種類」フィールドに表示されます。図5-1に示すとおり、サポートされているタイプの1つを「アクティブな種類」フィールドに入力します。

図5-1 サンプルIDアサーション・プロバイダの構成

図5-1の説明が続きます
「図5-1 サンプルIDアサーション・プロバイダの構成」の説明

「サポートされている種類」フィールドの内容は、カスタムIDアサーション・プロバイダのMBeanタイプを生成するために使用するMBean定義ファイル(MDF)のSupportedTypes属性から取得されます。サンプルIDアサーション・プロバイダの例を例5-2に示します。(「WebLogic MBeanMakerを使用してMBeanタイプを生成する」を参照してください。)

例5-2 SampleIdentityAsserter MDF : SupportedTypes属性

<MBeanType>
...
   <MBeanAttribute 
    Name = "SupportedTypes"
    Type = "java.lang.String[]"
    Writeable = "false"
    Default = "new String[] {&quot;SamplePerimeterAtnToken&quot;}"
   />
...
</MBeanType>

同様に、「アクティブな種類」フィールドの内容はMBean定義ファイル(MDF)のActiveTypes属性から取得されます。MDFファイルのActiveTypes属性をデフォルトに設定すると、WebLogic Server管理コンソールで手動設定する必要がなくなります。サンプルIDアサーション・プロバイダの例を例5-3に示します。

例5-3 SampleIdentityAsserter MDF: Defaultを使用したActiveTypes属性

<MBeanAttribute 
 Name= "ActiveTypes"
 Type= "java.lang.String[]"
 Default = "new String[] { &quot;SamplePerimeterAtnToken&quot; }"
/>

ActiveTypes属性のデフォルト化は便利ですが、他のIDアサーション・プロバイダがそのトークン・タイプを検証することがない場合にのみ行うようにします。それ以外の場合、無効なセキュリティ・レルムが構成されることになるおそれがあります(複数のIDアサーション・プロバイダが同じトークン・タイプを検証しようとします)。一番よいのは、IDアサーション・プロバイダのすべてのMDFがデフォルトでそのトークン・タイプをオフにすることです。その場合、そのトークン・タイプを検証するIDアサーション・プロバイダを構成して手作業でアクティブにすることができます。

注意:

IDアサーション・プロバイダが目的のトークン・タイプを検証して受け入れるように開発および構成されていない場合、認証プロセスは失敗します。IDアサーション・プロバイダの構成の詳細は、「管理コンソールによるカスタムIDアサーション・プロバイダの構成」を参照してください。

境界認証用のトークンの渡し

IDアサーション・プロバイダは、境界認証のためにJavaクライアントからサーブレットにトークンを渡すことができます。トークンは、HTTPヘッダー、Cookie、SSL証明書などのメカニズムを用いて渡すことができます。たとえば、HTTPヘッダーを使用すれば、Base64でコード化された文字列(バイナリ・データの送信が可能)をサーブレットに送信することができます。この文字列の値は、ユーザー名などのユーザーのIDを表す文字列です。境界認証に使用されるIDアサーション・プロバイダは、その文字列を受け取り、そこからユーザー名を抽出できます。

トークンがHTTPヘッダーまたはCookieを通じて渡される場合には、そのトークンはヘッダーまたはCookieの名前に等しく、リソース・コンテナはWebLogicセキュリティ・フレームワークの認証を処理するパートにトークンを渡します。WebLogicセキュリティ・フレームワークは、そのトークンをそのままIDアサーション・プロバイダに渡します。

WebLogic Serverは、IDアサーションのサポートを介して境界までシングル・サインオン概念を拡張できるよう設計されています。IDアサーションを使用すると、WebLogic Serverは、SAML (Security Assertion Markup Language)、SPNEGO (Simple and Protected GSS-API Negotiation)、またはCommon Secure Interoperability (CSI) v2などのプロトコルに対する拡張といった境界認証方式によって提供される認証メカニズムを使用して、この機能を実現できます。

Common Secure Interoperability Version 2 (CSIv2)

WebLogic Serverでは、IIOP (Internet Inter-ORB) (GIOPバージョン1.2)およびCORBA CSIv2 (Common Secure Interoperability version 2)仕様に基づいたEJB (Enterprise JavaBean)相互運用性プロトコルをサポートしています。WebLogic ServerでCSIv2をサポートすることにより、以下のことが可能になります。

  • Java EE (Java 2 Enterprise Edition)バージョン1.4の参照実装と相互運用できます。

  • WebLogic Server IIOPクライアントでT3クライアントの場合と同じようにユーザー名とパスワードを指定できるようになります。

  • GSSAPI (Generic Security Services Application Programming Interface)初期コンテキスト・トークンをサポートできるようになります。今回のリリースでは、ユーザー名/パスワードとGSSUP (Generic Security Services Username Password)トークンのみがサポートされています。

    注意:

    WebLogic ServerにおけるCSIv2実装は、Java EE CTS (Compatibility Test Suite)適合性テストに合格しています。

CSIv2実装への外部インタフェースは、CORBAオブジェクトのユーザー名とパスワードを取得するJAAS LoginModuleです。JAAS LoginModuleは、WebLogic Javaクライアント、あるいは別のJava EEアプリケーション・サーバーに対するクライアントの役目をするWebLogic Serverインスタンスで使用することができます。CSIv2サポート用のJAAS LoginModuleはUsernamePasswordLoginModuleという名前で、weblogic.security.auth.loginパッケージに格納されています。

CSIv2は以下のように動作します。

  1. IOR (Interoperable Object Reference)へのセキュリティ拡張機能の作成時に、WebLogic Serverは、CORBAオブジェクトでサポートされるセキュリティ・メカニズムを識別するタグ付きコンポーネントを追加します。このタグ付きコンポーネントには、トランスポート情報、クライアント認証情報、およびID証明トークン/認可トークン情報が入っています。

  2. クライアントは、IOR内のセキュリティ・メカニズムを評価し、サーバーが必要とするオプションをサポートするメカニズムを選択します。

  3. クライアントはSASプロトコルを用いて、WebLogic Serverとのセキュリティ・コンテキストを確立します。SASプロトコルはリクエストとレスポンスからなるサービス・コンテキスト内に含まれるメッセージを定義します。コンテキストはステートフルでもステートレスでもかまいません。

CSIv2の利用については、Oracle WebLogic Serverのセキュリティの理解のCommon Secure Interoperability Version 2を参照してください。「LoginModules」を参照してください。

IDアサーション・プロセス

境界認証では、WebLogic Serverの外部にあるシステムがトークンを通じて信頼を確立します(これは、WebLogic Serverがユーザー名とパスワードを通じて信頼を確立する、「認証プロセス」で説明されているタイプの認証とは対照的です)。IDアサーション・プロバイダは、次の図のように機能する境界認証プロセスの一部として使用されます(図5-2を参照)。

  1. WebLogic Serverの外部のトークンが、そのタイプのトークンの検証を担当し、アクティブとして構成されているIDアサーション・プロバイダに渡されます。

  2. そのトークンの有効性が問題なく検証されれば、IDアサーション・プロバイダはそのトークンをWebLogic Serverユーザー名にマップし、そのユーザー名をWebLogic Serverに送り返します。その後WebLogic Serverでは、「認証プロセス」で説明した方法で認証プロセスを続行します。具体的には、ユーザー名がJAAS (Java Authentication and Authorization Service) CallbackHandlerを通じて送信され、構成されている各認証プロバイダのLoginModuleに渡されて、サブジェクト内に適切なプリンシパルを格納できるようになります。

図5-2でも示されているように、境界認証では「認証プロセス」で説明されている認証プロセスと同じ構成要素が必要ですが、そこにIDアサーション・プロバイダも追加されます。

カスタムIDアサーション・プロバイダを開発する必要があるか

WebLogic IDアサーション・プロバイダでは、X509証明書を使用した証明書認証、SPNEGOトークン、SAMLアサーション・トークン、およびCSIv2 (CORBA Common Secure Interoperability Version 2) IDアサーションがサポートされています。

LDAP X509 IDアサーション・プロバイダは、X509証明書を受け取り、その証明書に関連付けられたユーザーのLDAPオブジェクトをルックアップして、LDAPオブジェクトの証明書が提示された証明書と一致することを確認し、LDAPオブジェクトから認証用にユーザーの名前を取得します。

ネゴシエーションIDアサーション・プロバイダは、SPNEGOプロトコルをサポートするMicrosoftクライアントでのSSOに使用します。ネゴシエーションIDアサーション・プロバイダは、SPNEGOトークンをデコードしてKerberosトークンを入手し、このKerberosトークンを検証してWebLogicユーザーにマップします。ネゴシエーションIDアサーション・プロバイダは、Kerberosを介したGSSのセキュリティ・コンテキストの受け入れにJava GSS (Generic Security Service) API (Application Programming Interface)を利用します。ネゴシエーションIDアサーション・プロバイダは、Windows NT統合ログイン用です。

SAML IDアサーション・プロバイダは、WebLogic ServerがSAML宛先サイトとして動作するときにSAMLアサーション・トークンを処理します。SAML IDアサーション・プロバイダは、SAMLアサーション・トークンを消費および検証し、アサーションを信頼するかどうかを決定します(SOAPメッセージの証明データ、クライアント証明書、またはその他の構成インジケータを使用)。

デフォルトのWebLogic IDアサーション・プロバイダはトークン・タイプを検証し、X509デジタル証明書とX501識別名をWebLogicユーザー名にマップします。また、CSIv2 IDアサーションに使用する信頼性のあるクライアント・プリンシパルのリストも指定します。ワイルドカード文字(*)を使用すると、すべてのプリンシパルに信頼性があると指定できます。クライアントが信頼性のあるクライアント・プリンシパルのリストにない場合は、CSIv2 IDアサーションが失敗し、呼出しが拒否されます。

注意:

X.501およびX.509証明書に対してWebLogic IDアサーション・プロバイダを使用するには、WebLogic Server製品に付属しているデフォルトのユーザー名マッパー(weblogic.security.providers.authentication.DefaultUserNameMapperImpl)を使用するか、または独自のweblogic.security.providers.authentication.UserNameMapperインタフェースの実装を用意するかのいずれかの方法があります。

このインタフェースは、必要に応じた方式に従って、X.509証明書をWebLogic Serverのユーザー名にマップします。また、このインタフェースを使用してX.501識別名をユーザー名にマップすることもできます。WebLogic Server管理コンソールを使用してIDアサーション・プロバイダを構成するときに、このインタフェースの実装を指定します。

WebLogic IDアサーション・プロバイダでは、以下のトークン・タイプがサポートされています。

  • AU_TYPE - WebLogic AuthenticatedUserがトークンとして使用される場合に使用します。

  • X509_TYPE - X509クライアント証明書がトークンとして使用される場合に使用します。

  • CSI_PRINCIPAL_TYPE - CSIv2プリンシパル名IDがトークンとして使用される場合に使用します。

  • CSI_ANONYMOUS_TYPE - CSIv2匿名IDがトークンとして使用される場合に使用します。

  • CSI_X509_CERTCHAIN_TYPE - CSIv2 X509証明書チェーンIDがトークンとして使用される場合に使用します。

  • CSI_DISTINGUISHED_NAME_TYPE - CSIv2識別名IDがトークンとして使用される場合に使用します。

  • AUTHORIZATION_NEGOTIATE - SPNEGO内部トークンがトークンとして使用される場合に使用します。

  • SAML_ASSERTION_B64_TYPE - Base64エンコードSAML.アサーションがトークンとして使用される場合に使用します。

  • SAML_ASSERTION_DOM_TYPE - SAML DOM要素がトークンとして使用される場合に使用します。

  • SAML_ASSERTION_TYPE - SAML文字列XML形式がトークンとして使用される場合に使用します。

  • SAML2_ASSERTION_DOM_TYPE - SAML2 DOM要素がトークンとして使用される場合に使用します。

  • SAML2_ASSERTION_TYPE - SAML2文字列XML形式がトークンとして使用される場合に使用します。

  • SAML_SSO_CREDENTIAL_TYPE - TARGETパラメータで構成されるSAML文字列がアサーション自体と連結され、トークンとして使用される場合に使用します。

  • WSSE_PASSWORD_DIGEST_TYPE - パスワード・ダイジェストのパスワード・タイプを持つユーザー名トークンがトークンとして使用される場合に使用します。

  • WWW_AUTHENTICATE_NEGOTIATE - SPNEGO内部トークンがトークンとして使用される場合に使用します。

追加的なIDアサーション・タスクを実行したい場合、または新しいトークン・タイプを作成したい場合は、カスタムIDアサーション・プロバイダを開発する必要があります。

カスタムIDアサーション・プロバイダの開発方法

WebLogic IDアサーション・プロバイダが開発者のニーズを満たさない場合、次の手順でカスタムIDアサーション・プロバイダを開発することができます。

  1. 適切なSSPIによるランタイム・クラスの作成

  2. 「WebLogic MBeanMakerを使用してMBeanタイプを生成する」で説明されている手順を実行してカスタムIDアサーション・プロバイダのMBeanタイプを生成

  3. 管理コンソールによるカスタムIDアサーション・プロバイダの構成

  4. 「チャレンジIDアサーション」の説明に従って、チャレンジIDアサーションを実装する必要があるかどうかを考慮

適切なSSPIによるランタイム・クラスの作成

ランタイム・クラスを作成する前に、以下の作業が必要です。

この情報を理解し、設計に関する判断を下したら、次の手順でカスタムIDアサーション・プロバイダのランタイム・クラスを作成します。

カスタムIDアサーション・プロバイダのランタイム・クラスの作成例については、「例:サンプルIDアサーション・プロバイダのランタイム・クラスの作成」を参照してください。

AuthenticationProviderV2 SSPIの実装

注意:

AuthenticationProvider SSPIは、このリリースのWebLogic Serverでは非推奨になっています。AuthenticationProviderV2 SSPIをかわりに使用してください。

AuthenticationProviderV2 SSPIを実装するには、Provider SSPIの目的についてで説明されているメソッドおよび次のメソッドの実装を提供する必要があります。

  • getLoginModuleConfiguration

    public AppConfigurationEntry getLoginModuleConfiguration()
    

    getLoginModuleConfigurationメソッドは、認証プロバイダの関連付けられたLoginModuleに関する情報を取得します。その情報は、AppConfigurationEntryとして返されます。AppConfigurationEntryは、LoginModuleのクラス名、認証プロバイダの関連するMBeanを通じて渡されたLoginModuleの制御フラグ、および他の構成情報をLoginModuleに渡すことを可能にするLoginModuleの構成オプション・マップの格納されたJAAS (Java Authentication and Authorization Service)クラスです。

    (javax.security.auth.loginパッケージ内にある)AppConfigurationEntryクラスとLoginModulesの制御フラグ・オプションの詳細は、AppConfigurationEntryクラスに関する項(http://docs.oracle.com/javase/8/docs/api/javax/security/auth/login/AppConfigurationEntry.html)およびConfigurationクラスに関する項(http://docs.oracle.com/javase/8/docs/api/javax/security/auth/login/Configuration.html)を参照してください。LoginModuleの詳細は、「LoginModule」を参照してください。セキュリティ・プロバイダとMBeanの詳細は、「MBeanタイプが必要な理由について」を参照してください。

  • getAssertionModuleConfiguration

    public AppConfigurationEntry
    getAssertionModuleConfiguration()
    

    getAssertionModuleConfigurationメソッドは、IDアサーション・プロバイダの関連付けられたLoginModuleに関する情報を取得します。その情報は、AppConfigurationEntryとして返されます。AppConfigurationEntryは、LoginModuleのクラス名、IDアサーション・プロバイダの関連するMBeanを通じて渡されたLoginModuleの制御フラグ、および他の構成情報をLoginModuleに渡すことを可能にするLoginModuleの構成オプション・マップの格納されたJAASクラスです。

    この構成のLoginModuleは、WLSGroup型などの必須のプリンシパルをサブジェクトに格納する必要があります。また、ユーザーがログインのための十分な証明を提供していると見なし、パスワードなどの証明データを要求しません。

    注意:

    IDアサーション・プロバイダのassertIdentity()メソッドは、IDアサーションが発生するたびに呼び出されますが、サブジェクトがキャッシュされている場合、LoginModuleは呼び出されないことがあります。-Dweblogic.security.identityAssertionTTLフラグを使うと、この動作を変更する(たとえば、5分というデフォルトTTLを変更する、またはフラグを -1に設定してキャッシュを無効にする)ことができます。

    トークンが有効なだけでなく、ユーザーも引続き有効であること(ユーザーが削除されていないことなど)を確認するのは、IDアサーション・プロバイダの役割です。

  • getPrincipalValidator

    public PrincipalValidator getPrincipalValidator()
    

    getPrincipalValidatorメソッドは、プリンシパル検証プロバイダのランタイム・クラス(PrincipalValidator SSPI実装)の参照を取得します。詳細は、「プリンシパル検証プロバイダ」を参照してください。

  • getIdentityAsserter

    public IdentityAsserterV2 getIdentityAsserter()
    

    getIdentityAsserterメソッドは、IDアサーション・プロバイダのランタイム・クラス(IdentityAsserterV2 SSPI実装)の参照を取得します。詳細は、「IdentityAsserterV2 SSPIの実装」を参照してください。

    注意:

    IDアサーション・プロバイダ用のLoginModuleが既存の認証プロバイダ用のLoginModuleと同じである場合、IDアサーション・プロバイダ用のAuthenticationProviderV2 SSPI内のメソッドの実装(getIdentityAsserterメソッドを除く)はnullを戻す場合があります。この場合の例については、例5-4に示します。

AuthenticationProvider SSPIと前述のメソッドの詳細は、Oracle WebLogic Server Java APIリファレンスを参照してください。

IdentityAsserterV2 SSPIの実装

注意:

IdentityAsserterV2 SSPIには、追加のトークン・タイプと、IDアサーション時に必要に応じて追加情報の取得に使用できるassertIdentityメソッドに対するhandlerパラメータが含まれます。IdentityAsserter SSPIもサポートされていますが、かわりにIdentityAsserterV2 SSPIの使用を検討してください。

IdentityAsserterV2 SSPIを実装するには、次のメソッドの実装を提供する必要があります。

  • assertIdentity

    public CallbackHandler assertIdentity(String type, Object token, ContextHandler handler) throws IdentityAssertionException;
    

    assertIdentityメソッドは、提供されたトークンのID情報に基づいてIDを断定します。言い換えれば、このメソッドの目的は、現時点で「信頼性のない」トークンがあれば、それを信頼性のあるクライアント・プリンシパルに照らし合わせて検証することです。typeパラメータは、IDアサーション(IDの断定)に使用するトークン・タイプを表します。IDアサーション・タイプでは、大文字/小文字は区別されません。また、tokenパラメータには実際のID情報が格納されています。handlerパラメータは、IDアサーションで使用可能な追加情報を取得する際に必要に応じて使用できるContextHandlerオブジェクトです。assertIdentityメソッドから返されるCallbackHandlerは、アサートされたユーザー名を格納している必要があり、プリンシパル・マッピングを行うために構成されているすべての認証プロバイダのLoginModuleに渡されます。CallbackHandlernullの場合、匿名ユーザーを使用することを意味します。

    CallbackHandlerは、可変個の引数を複合オブジェクトとしてメソッドに渡すことができるようにする高度に柔軟なJAAS規格です。CallbackHandlerの詳細は、CallbackHandlerインタフェースに関する項(http://docs.oracle.com/javase/8/docs/api/javax/security/auth/callback/CallbackHandler.html)を参照してください。

    注意:

    IDアサーション・プロバイダのassertIdentity()メソッドは、IDアサーションが発生するたびに呼び出されますが、サブジェクトがキャッシュされている場合、LoginModuleは呼び出されないことがあります。-Dweblogic.security.identityAssertionTTLフラグを使うと、この動作を変更する(たとえば、5分というデフォルトTTLを変更する、またはフラグを -1に設定してキャッシュを無効にする)ことができます。

    トークンが有効なだけでなく、ユーザーも引続き有効であること(ユーザーが削除されていないことなど)を確認するのは、IDアサーション・プロバイダの役割です。

IdentityAsserterV2 SSPIと前述のメソッドの詳細は、Oracle WebLogic Server Java APIリファレンスを参照してください。

例:サンプルIDアサーション・プロバイダのランタイム・クラスの作成

例5-4は、サンプルIDアサーション・プロバイダのランタイム・クラスであるSampleIdentityAsserterProviderImpl.javaクラスを示しています。このランタイム・クラスには次の実装が含まれています。

  • initializegetDescriptionおよびshutdownというSecurityProviderインタフェースから継承した3つのメソッド(Provider SSPIの目的についてを参照。)

  • getLoginModuleConfigurationgetAssertionModuleConfigurationgetPrincipalValidatorおよびgetIdentityAsserterというAuthenticationProviderV2 SSPIの4つのメソッド(「AuthenticationProviderV2 SSPIの実装」を参照)。

  • assertIdentityというIdentityAsserterV2 SSPIのメソッド(「IdentityAsserterV2 SSPIの実装」を参照)。

    注意:

    例5-4の太字のコードは、クラス宣言とメソッド・シグネチャを示しています。

例5-4 SampleIdentityAsserterProviderImpl.java

package examples.security.providers.identityassertion.simple;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.login.AppConfigurationEntry;
import weblogic.management.security.ProviderMBean;
import weblogic.security.service.ContextHandler;
import weblogic.security.spi.AuthenticationProviderV2;
import weblogic.security.spi.IdentityAsserterV2;
import weblogic.security.spi.IdentityAssertionException;
import weblogic.security.spi.PrincipalValidator;
import weblogic.security.spi.SecurityServices;
public final class SimpleSampleIdentityAsserterProviderImpl implements AuthenticationProviderV2,
IdentityAsserterV2
{
   final static private String TOKEN_TYPE   = "SamplePerimeterAtnToken";
   final static private String TOKEN_PREFIX = "username=";
   private String description; 
   public void initialize(ProviderMBean mbean, SecurityServices services)
   {
      System.out.println("SimpleSampleIdentityAsserterProviderImpl.initialize");
      SimpleSampleIdentityAsserterMBean myMBean = (SimpleSampleIdentityAsserterMBean)mbean;
      description = myMBean.getDescription() + "\n" + myMBean.getVersion();
   }
   public String getDescription()
   {
      return description;
   }
   public void shutdown()
   {
      System.out.println("SimpleSampleIdentityAsserterProviderImpl.shutdown");
   }
   public IdentityAsserterV2 getIdentityAsserter()
   {
      return this;
   }
   public CallbackHandler assertIdentity(String type, Object token, ContextHandler context) throws 
   IdentityAssertionException
   {
      System.out.println("SimpleSampleIdentityAsserterProviderImpl.assertIdentity");
      System.out.println("\tType\t\t= "  + type);
      System.out.println("\tToken\t\t= " + token);
      if (!(TOKEN_TYPE.equals(type))) {
         String error = "SimpleSampleIdentityAsserter received unknown token type \"" 
            + type + "\"." + " Expected " + TOKEN_TYPE;
         System.out.println("\tError: " + error);
         throw new IdentityAssertionException(error);
      }
      if (!(token instanceof byte[])) {
         String error = "SimpleSampleIdentityAsserter received unknown token class \"" 
            + token.getClass() + "\"." + " Expected a byte[].";
         System.out.println("\tError: " + error);
         throw new IdentityAssertionException(error);
      }
      byte[] tokenBytes = (byte[])token;
      if (tokenBytes == null || tokenBytes.length < 1) {
         String error = "SimpleSampleIdentityAsserter received empty token byte array";
         System.out.println("\tError: " + error);
         throw new IdentityAssertionException(error);
      }
      String tokenStr = new String(tokenBytes);
      if (!(tokenStr.startsWith(TOKEN_PREFIX))) {
         String error = "SimpleSampleIdentityAsserter received unknown token string \"" 
            + type + "\"." + " Expected " + TOKEN_PREFIX + "username";
         System.out.println("\tError: " + error);
         throw new IdentityAssertionException(error);
      }
      String userName = tokenStr.substring(TOKEN_PREFIX.length());
      System.out.println("\tuserName\t= " + userName);
      return new SimpleSampleCallbackHandlerImpl(userName);
   }
   public AppConfigurationEntry getLoginModuleConfiguration()
   {
      return null;
   }
   public AppConfigurationEntry getAssertionModuleConfiguration()
   {
      return null;
   }
   public PrincipalValidator getPrincipalValidator()
   {
      return null;
   }
}

例5-5は、SampleIdentityAsserterProviderImpl.javaランタイム・クラスとともに使用するCallbackHandlerのサンプル実装を示しています。このCallbackHandlerの実装は、認証プロバイダのLoginModuleにユーザー名を送り返すために使用します。

例5-5 SampleCallbackHandlerImpl.java

package examples.security.providers.identityassertion.simple;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;
/*package*/ class SimpleSimpleSampleCallbackHandler implements CallbackHandler
{
   private String userName;
   /*package*/ SimpleSampleCallbackHandlerImpl(String user)
   {
      userName = user;
   }
   public void handle(Callback[] callbacks) throws UnsupportedCallbackException
   {
      for (int i = 0; i < callbacks.length; i++) {
            Callback callback = callbacks[i];
            if (!(callback instanceof NameCallback)) {
               throw new UnsupportedCallbackException(callback, "Unrecognized 
                  Callback");
            }
            NameCallback nameCallback = (NameCallback)callback;
            nameCallback.setName(userName);
      }
   }
}

管理コンソールによるカスタムIDアサーション・プロバイダの構成

カスタムIDアサーション・プロバイダを構成するということは、そのカスタムIDアサーション・プロバイダをセキュリティ・レルムに追加するということです。追加されたカスタムIDアサーション・プロバイダには、IDアサーション・サービスを必要とするアプリケーションからアクセスできます。

カスタム・セキュリティ・プロバイダの構成は管理タスクですが、カスタム・セキュリティ・プロバイダの開発者が行うこともできます。

注意:

WebLogic Server管理コンソールを使用してカスタムのIDアサーション・プロバイダを構成する手順は、Oracle WebLogic Serverセキュリティの管理のWebLogicセキュリティ・プロバイダの構成を参照してください。

チャレンジIDアサーション

チャレンジIDアサーション・インタフェースは、複数のチャレンジ、レスポンス・メッセージ、および状態を必要とするチャレンジ・レスポンス・スキームをサポートします。チャレンジIDアサーション・プロバイダ・インタフェースを使用すると、IDアサーション・プロバイダは、MicrosoftのWindows NTチャレンジ/レスポンス(NTLM)やSPNEGO (Simple and Protected GSS-API Negotiation)などのチャレンジ/レスポンス認証メカニズムを採用した認証プロトコルをサポートできます。

JavaサーブレットAPI 2.3環境におけるチャレンジ/レスポンスの制限

WebLogicセキュリティ・フレームワークを使用すると、カスタム認証プロバイダおよびカスタムIDアサーション・プロバイダを利用できます。ただし、JavaサーブレットAPI 2.3の仕様により、認証プロセス時は、認証プロバイダとクライアントまたは他のサーバーとの間の対話はアーキテクチャで制限されます。これにより、認証メカニズムは、サーブレット・コンテナが提供する認証メカニズムと互換性のある基本、フォーム、証明書の形式に制限されます。

サーブレット認証フィルタ(「サーブレット認証フィルタ」を参照)には、アーキテクチャ依存の制限はほとんどありません。つまり、サーブレット認証フィルタは、サーブレット・コンテナが提供する認証メカニズムに依存していません。認証プロセスを開始するコンテナの前にフィルタを呼び出せるようにすれば、セキュリティ・レルムは、より柔軟な認証メカニズムを実装できます。たとえば、サーブレット認証フィルタを使用すると、認証用のSAMLプロバイダ・サイトにユーザーをリダイレクトできます。

サーブレット認証フィルタでは、ユーザーの環境にチャレンジ/レスポンス・プロトコルを簡単に実装できます。フィルタを使用すると、ユーザーのチャレンジ/レスポンス・メカニズムでチャレンジを完了するまで必要なだけチャレンジIDアサーション・インタフェースをループさせることができます。

weblogic.security.services.Authenticationクラスのフィルタと役割

サーブレット認証フィルタを使用すると、サーブレット・コンテナと互換性のある認証メカニズムに制限されることなくチャレンジ/レスポンス・プロトコルを実装できます。ただし、サーブレット認証フィルタは、セキュリティ・フレームワークで提供されている認証環境の外側で機能するので、セキュリティ・フレームワークを利用してプロバイダのコンテキストを判別することはできません。また、サーブレット認証フィルタでは、APIでチャレンジ回数が複数のIDアサーション・プロセスを駆動させる必要があります。

weblogic.security.services.Authenticationクラスが拡張され、サーブレット認証フィルタからの複数のチャレンジ/レスポンスIDアサーションが可能になりました。メソッドおよびインタフェースでは、ChallengeIdentityAsserterV2インタフェースとProviderChallengeContextインタフェースのラッパーが提供されるので、サーブレット認証フィルタから呼び出すことができます。

これ以外に、セキュリティ・フレームワークのコンテキスト内でサーブレット認証フィルタから複数のチャレンジ/レスポンス・ダイアログを実行する方法はドキュメント化されていません。サーブレット認証フィルタは、ChallengeIdentityAsserterV2インタフェースおよびProviderChallengeContextインタフェースを直接呼び出すことはできません。

そのため、ChallengeIdentityAsserterV2インタフェースとProviderChallengeContextインタフェースを実装し、weblogic.security.services.AuthenticationのメソッドとAppChallengeContextインタフェースを使用してサーブレット認証フィルタからそれらのインタフェースを呼び出す必要があります。

ChallengeIdentityAsserterV2インタフェースの実装

ChallengeIdentityAsserterV2インタフェースは、IdentityAsserterV2 SSPIを拡張します。IdentityAsserterV2 SSPIに加えて、ChallengeIdentityAsserterV2インタフェースを実装する必要があります。

すべてのIdentityAsserterV2メソッドおよび次のメソッドの実装を提供します。

  • assertChallengeIdentity

    ProviderChallengeContext assertChallengeIdentity(String tokenType, Object token, ContextHandler handler)
    

    提供されているクライアント・トークンを使用し、場合によっては複数回のチャレンジでクライアントIDを確立します。このメソッドは、ProviderChallengeContextインタフェースの実装を返します。ProviderChallengeContextインタフェースには、チャレンジの状態を問い合せる手段があります。

  • continueChallengeIdentity

    void continueChallengeIdentity(ProviderChallengeContext context, String tokenType, Object token, 
    ContextHandler handler) 
    

    提供されているプロバイダ・コンテキストとクライアント・トークンを使用して、クライアントIDの確立を続行します。

  • getChallengeToken

    Object getChallengeToken(String type, ContextHandler handler) 
    

    このメソッドは、IDアサーション・プロバイダのチャレンジ・トークンを返します。

ProviderChallengeContextインタフェースの実装

ProviderChallengeContextインタフェースには、チャレンジの状態を問い合せる手段があります。ChallengeIdentityAsserterV2インタフェースのassertChallengeIdentityメソッドおよびcontinueChallengeIdentityメソッドを使用し、コールバック・ハンドラか、クライアントが応答する必要がある新しいチャレンジを返すことができます。

ProviderChallengeContextインタフェースを実装するには、以下のメソッドの実装を提供する必要があります。

  • getCallbackHandler

    CallbackHandler getCallbackHandler() 
    

    このメソッドは、チャレンジIDアサーションのコールバック・ハンドラを返します。hasChallengeIdentityCompletedメソッドがtrueを返した場合にのみ、このメソッドを呼び出します。

  • getChallengeToken

    Object getChallengeToken() 
    

    このメソッドは、チャレンジIDアサーションのチャレンジ・トークンを返します。hasChallengeIdentityCompletedメソッドがfalseを返した場合にのみ、このメソッドを呼び出します。

  • hasChallengeIdentityCompleted

    boolean hasChallengeIdentityCompleted 
    

    このメソッドは、チャレンジIDアサーションが完了したかどうかを返します。このメソッドは、チャレンジIDアサーションが完了した場合はtrue、完了していない場合はfalseを返します。trueの場合、呼出し側はgetCallbackHandlerメソッドを使用する必要があります。falseの場合、呼出し側はgetChallengeTokenメソッドを使用する必要があります。

weblogic.security.servicesのチャレンジIDメソッドの呼出し

ChallengeIdentityAsserterV2 SSPIを直接呼び出すのではなく、サーブレット認証フィルタからweblogic.security.services.Authenticationの次のメソッドを呼び出します。

  • assertChallengeIdentity

    AppChallengeContext assertChallengeIdentity(String tokenType, Object token, AppContext appContext) 
    

    提供されているクライアント・トークンを使用し、場合によっては複数回のチャレンジでクライアントIDを確立します。このメソッドは、チャレンジIDアサーションのコンテキストを戻します。この結果には、認証されたサブジェクトか、クライアントが応答する必要がある追加チャレンジが含まれる可能性があります。AppChallengeContextインタフェースには、チャレンジの状態を問い合せる手段があります。

  • continueChallengeIdentity

    void continueChallengeIdentity(AppChallengeContext context, String tokenType,
     Object token, AppContext appContext) 
    

    提供されているプロバイダ・コンテキストとクライアント・トークンを使用して、クライアントIDの確立を続行します。

  • getChallengeToken

    Object getChallengeToken 
    

    このメソッドは、チャレンジIDアサーションの初期チャレンジ・トークンを返します。

weblogic.security.servicesのAppChallengeContextメソッドの呼出し

ProviderChallengeContextインタフェースを直接呼び出すのではなく、サーブレット認証フィルタからAppChallengeContextの次のメソッドを呼び出します。

  • getAuthenticatedSubject

    Subject getAuthenticatedSubject() 
    

    このメソッドは、チャレンジIDアサーションで認証されたサブジェクトを返します。hasChallengeIdentityCompletedメソッドがtrueを返した場合にのみ、このメソッドを呼び出します。

  • getChallengeToken

    Object getChallengeToken() 
    

    このメソッドは、チャレンジIDアサーションのチャレンジ・トークンを返します。hasChallengeIdentityCompletedメソッドがfalseを返した場合にのみ、このメソッドを呼び出します。

  • hasChallengeIdentityCompleted

    boolean hasChallengeIdentityCompleted() 
    

    このメソッドは、チャレンジIDアサーションが完了したかどうかを返します。このメソッドは、チャレンジIDアサーションが完了した場合はtrue、完了していない場合はfalseを返します。trueの場合、呼出し側はgetCallbackHandlerメソッドを使用する必要があります。falseの場合、呼出し側はgetChallengeTokenメソッドを使用する必要があります。

フィルタからのチャレンジIDアサーションの実装

以下のコード・フローでは、サーブレット認証フィルタ(「サーブレット認証フィルタ」を参照)は、HTTPレベルの対話(AuthorizationおよびWWW-Authenticate)を処理するとともに、weblogic.security.services.Authenticationメソッドとインタフェースを呼び出してチャレンジIDアサーション・プロセスを駆動させる役割も果たしています。

  1. ブラウザがリクエストを送信します。

  2. フィルタは、リクエストを認識してAuthorizationヘッダーがないことを判別すると、weblogic.security.services.Authentication getChallengeTokenメソッドを呼び出して初期トークンを取得し、WWW-Authenticateネゴシエーション・ヘッダー付きの401レスポンスを返します。

  3. ブラウザは、WWW-Authenticate付きの401を認識し、新しいリクエストと認証ネゴシエーション・トークン付きの応答を返します。

    1. フィルタがこれを認識して、 weblogic.security.services.Authentication assertChallengeIdentityメソッドを呼び出します。assertChallengeIdentityはトークンを入力として受け取り、アサーション・プロセスで従う必要があるルールに従ってそれを処理し(たとえばNTLMの場合は、トークンの処理用NTLMによるに必要なことを実行します)、それが成功したかどうかを判断します。assertChallengeIdentityAppChallengeContextインタフェースの実装を返します。

    2. フィルタはappChallengeContext hasChallengeCompletedメソッドを呼び出します。AppChallengeContext hasChallengeIdentityCompletedメソッドを使用して、チャレンジが完了したかどうかを確認します。たとえば、このメソッドは、コールバック・ハンドラがnullでない(つまりユーザー名が含まれている)かどうかを判別し、trueを返すことができます。ここでは、falseが返されるので、別のチャレンジをクライアントに発行する必要があります。フィルタは、次にAppChallengeContext getChallengeTokenを呼び出し、チャレンジを再試行するためのトークンを取得します。

    3. フィルタは、おそらくセッション属性などにAppChallengeContextを格納しています。

    4. フィルタは、WWW-Authenticateネゴシエーションと新しいトークン付きの401レスポンスを送信します。

  4. ブラウザは、新しいチャレンジを認識し、Authorizationヘッダーを付けて再び応答します。

    1. フィルタは、これを認識してweblogic.security.services.Authentication continueChallengeIdentityメソッドを呼び出します。

    2. フィルタはAppChallengeContext hasChallengeCompletedメソッドを呼び出します。falseが返された場合は、別のチャレンジが用意されるので、AppChallengeContext getChallengeTokenメソッドを呼び出して、チャレンジを再試行するためのトークンを取得します(以降、falseの場合は同じ処理が繰り返されます)。trueが返された場合、チャレンジは完了したことになり、フィルタは次にAppChallengeContext getAuthenticatedSubjectメソッドを呼び出し、runAs(subject, request)を実行します。