ヘッダーをスキップ

Oracle Containers for J2EE セキュリティ・ガイド
10g(10.1.3.4.0)

B50832-01
目次
目次
索引
索引

戻る 次へ

9 ログイン・モジュール

この章では、OC4Jで提供されるログイン・モジュールについてと、カスタム・ログイン・モジュールを実装、インストールおよび構成する方法について説明します。内容は次のとおりです。

初期ログイン・モジュールの注意事項

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

Oracleログイン構成プロバイダの指定

デフォルトでOC4Jは、Sun社のデフォルトJAASログイン構成プロバイダの使用を上書きする、OC4J JVMからのOracleAS JAAS Providerログイン構成プロバイダ(oracle.security.jazn.spi.LoginConfigProvider)の使用を指定します。

これは、ファイルORACLE_HOME/j2ee/home/config/jazn.security.propsの次の構成で実行されます。

login.configuration.provider=oracle.security.jazn.spi.LoginConfigProvider

Oracleログイン構成プロバイダでは、ログイン・モジュール構成にsystem-jazn-data.xmlファイルを使用します。

ログイン・モジュールの注意とヒント

OC4Jでのログイン・モジュールの使用に関しては、次のことに注意してください。

OC4Jで提供されるログイン・モジュール

OC4Jでは、標準のJ2EEログイン・モジュールなど、表9-1に示すログイン・モジュールのセットが提供されます。

表9-1    OC4Jで提供されるログイン・モジュール 
ログイン・モジュール  説明 

oracle.security.jazn.login.module.
RealmLoginModule 

ファイルベース・プロバイダまたはOracle Identity Management用のOC4Jログイン・モジュール(追加情報が続きます。) 

oracle.security.jazn.login.module.db.
DBTableOraDataSourceLoginModule 

データベース内のユーザー・データ用のOC4Jログイン・モジュール(追加情報が続きます。) 

oracle.security.jazn.login.module.
LDAPLoginModule 

外部LDAPプロバイダ用のOC4Jログイン・モジュール

関連項目: 第10章「外部LDAPセキュリティ・プロバイダ」 

oracle.security.jazn.login.module.coreid.
CoreIDLoginModule 

Oracle Access Manager用のOC4Jログイン・モジュール

関連項目: 第11章「Oracle Access Manager」 


注意

  • この表には、OC4J内部の追加のログイン・モジュールは掲載していません。

  • Oracleでは現在、OC4Jの使用でSunのログイン・モジュールを検証しません。(パッケージcom.sun.security.auth.module内のこれらのログイン・モジュールは、現在にJDKに含まれていません。)

 

この項の残りの部分では、次のログイン・モジュールの追加情報を扱います。

RealmLoginModule

RealmLoginModuleクラスは、ファイルベース・プロバイダまたはOracle Identity Managementで使用するデフォルトのログイン・モジュールで、Application Server Controlからセキュリティ・プロバイダを構成するときに構成されます。この構成は、system-jazn-data.xmlファイルの<jazn-loginconfig>の下の<login-module>要素に反映されます。

RealmLoginModuleクラスでは、ユーザーがJ2EEアプリケーションにアクセスする前にユーザー・ログイン資格証明が認証されます。認証は、OC4Jコンテナベース認証(HTTP Basic、フォームベースなど)を使用して実行されます。

RealmLoginModuleは、表9-2に示すオプションをサポートします(<login-module>の下の<option>要素の<name>および<value>サブ要素に反映されます)。

表9-2    RealmLoginModuleのオプション 
オプション  説明  デフォルト 

debug 

trueに設定すると、デバッグ・メッセージが出力されます。  

false 

addRoles 

trueに設定すると、RealmLoginModuleでは、ユーザーに直接付与されているロールすべてが認証の成功後にサブジェクトに追加されます。 

true 

addAllRoles 

trueに設定すると、RealmLoginModuleでは、ユーザーに直接または間接的に付与されているロールすべてが認証の成功後にサブジェクトに追加されます。 

true 

storePrivateCredentials 

trueに設定すると、RealmLoginModuleでは、すべての秘密資格証明(パスワード資格証明など)が認証の成功後にサブジェクトに追加されます。 

false 

supportNullPassword 

(Oracle Identity Managementのみ)trueに設定すると、RealmLoginModuleでは入力されたパスワードがnullまたは空かどうかがチェックされません。falseに設定すると、入力されたパスワードがnullまたは空の場合に認証が失敗します。 

false 


注意

  • アプリケーションがOracle Single Sign-On認証を使用する場合、RealmLoginModuleを有効にする必要はありません。

  • RealmLoginModuleは、プログラムによるセキュリティではなく、宣言によるセキュリティでのみ使用されます。

  • カスタム・ログイン・モジュール、言い換えるとカスタム・セキュリティ・プロバイダとしてのRealmLoginModuleの使用は、サポートされていません。

 

関連項目

 

次に、system-jazn-data.xml内のRealmLoginModuleの構成のサンプルを示します。(RealmLoginModule構成は手動で変更しないでください。この例は単に説明用です。)

<jazn-loginconfig>
   <application>
      <name>oracle.security.jazn.tools.Admintool</name>
      <login-modules>
         <login-module>
            <class>oracle.security.jazn.realm.RealmLoginModule</class>
            <control-flag>required</control-flag>
            <options>
               <option>
                  <name>debug</name>
                  <value>false</value>
               </option>
               <option>
                  <name>addAllRoles</name>
                  <value>true</value>
               </option>
            </options>
         </login-module>
      </login-modules>
   </application>
   <application>
      <name>oracle.security.jazn.oc4j.JAZNUserManager</name>
      <login-modules>
         <login-module>
            <class>oracle.security.jazn.realm.RealmLoginModule</class>
            <control-flag>required</control-flag>
            <options>
               <option>
                  <name>addAllRoles</name>
                  <value>true</value>
               </option>
            </options>
         </login-module>
      </login-modules>
   </application>
</jazn-loginconfig>

DBTableOraDataSourceLoginModule

OC4J 10.1.3.1実装は、データベースにユーザー・アイデンティティ・ストアがある場合に使用できるログイン・モジュールを提供します。

oracle.security.jazn.login.module.db.DBTableOraDataSourceLoginModule

これにより、現在では非推奨になったcom.evermind.sql.DataSourceUserManagerクラスの前の機能が置き換えられます(このクラスは、下位互換性を維持するため引き続きサポートされ、資料を完全なものにするためにこの項の終わりに掲載されています)。また、非推奨のcom.evermind.security.Userクラスの認証機能の一部も置き換えられます。

データベース・スキーマと、データベースに接続するOracleデータソースを作成すると(『Oracle Containers for J2EEサービス・ガイド』のデータソースの章を参照)、ログイン・モジュールを構成する準備が整います。

DBTableOraDataSourceLoginModuleは、データ・ロケーション(表名や列名)やパスワード暗号化のような項目を指定するいくつかのオプションをサポートします。これらのオプションは、Application Server ControlまたはOracleAS JAAS Provider Admintoolから設定できます。設定はsystem-jazn-data.xmlファイルの<jazn-loginconfig>要素に反映されます。

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

DBTableOraDataSourceLoginModuleオプション

表9-3DBTableOraDataSourceLoginModuleがサポートするオプションを要約しています。どのオプションが必須であるかを示し、適用できるデフォルト値や適切な例などを記載しています。出荷時のOC4Jにはこのログイン・モジュールの構成はありません。ログイン・モジュールの構成に使用できるツールの詳細は、後続の「Application Server Control内のDBTableOraDataSourceLoginModuleの構成」および「AdmintoolのDBTableOraDataSourceLoginModuleの構成」の項を参照してください。

DBTableOraDataSourceLoginModuleは、データベース表内の暗号化されたパスワードをサポートします。カスタム・パスワード暗号化アルゴリズムを使用できます。この機能を使用するには、次のインタフェースを実装する必要があります。「パスワード暗号化のDBLoginModuleEncodingInterfaceの実装」を参照してください。

oracle.security.jazn.login.module.db.DBLoginModuleEncodingInterface

OracleはSHA1およびMD5アルゴリズムの実装を提供しています。

表9-3    DBTableOraDataSourceLoginModuleオプション 
オプション  説明 

data_source_name(必須) 

データベース用のデータソースの名前。data-sources.xmlファイルで構成されます。

デフォルト: なし

例: jdbc/OracleDS 

table(必須) 

ユーザー認証情報が含まれるデータベース表の名前(ユーザー名、パスワードなど)。

デフォルト: なし

例: userinfo 

groupMembershipTableName(必須) 

ロール情報が含まれるデータベース表の名前。

デフォルト: なし

例: groupinfo 

usernameField(必須) 

tableオプションに指定された表内の、ユーザー名を含む列の名前。

デフォルト: なし

例: userName 

passwordField(必須) 

tableオプションに指定された表内の、パスワードを含む列の名前。

デフォルト: なし

例: passWord 

pw_encoding_class 

パスワード暗号化クラスの名前(パスワードの暗号化を使用する場合)。(この表の直後の説明を参照してください。)

デフォルト: oracle.security.jazn.login.module.db.util.
DBLoginModuleClearTextEncoder(暗号化なし)

例: oracle.security.jazn.login.module.db.util.
DBLoginModuleSHA1Encoder

関連項目: 「パスワード暗号化のDBLoginModuleEncodingInterfaceの実装」 

pw_key 

パスワード暗号化キー(パスワードの暗号化を使用する場合)。このキーはpw_encoding_classオプションで指定されたクラスからアクセスされます。

デフォルト: なし

例: xyz 

groupMembershipGroupFieldName(必須) 

groupMembershipTableNameオプションに指定された表内の、ロール名を含む列の名前。 

user_pk_column 

tableオプションに指定された表内の、主キーを含む列の名前。

デフォルト: usernameFieldオプションの値。

例: userName 

roles_fk_column 

groupMembershipTableNameオプションに指定された表内の、外部キーを含む列の名前。

デフォルト: usernameFieldオプションの値。

例: userName 

casing 

ログイン・ユーザー名とデータベース内の名前を比較するときに大/小文字を区別します。大/小文字を区別した比較が必要な場合はsensitive、ログイン・ユーザー名をすべて大文字に変換する場合はtoupper、ログイン・ユーザー名をすべて小文字に変換する場合はtolowerを使用します。(この3つの値以外の値が指定された場合は、デフォルト値が使用されます。)

デフォルト: sensitive

例: toupper 


注意

  • ユーザー情報とロール情報に同じ表を使用することができます。言い換えると、tableオプションとgroupMembershipTableNameオプションに同じ表を指定できます。ただし、このシナリオでは、それぞれのユーザーが保持できるロールは1つのみなので注意してください。通常は、個別の表を使用することをお薦めします。

  • DBTableOraDataSourceLoginModuleは、nullまたは空のパスワードをサポートしません。

  • パスワード暗号化を使用する場合、パスワードは非暗号化文字列ではなく、暗号化された値によって比較されます。ログインするユーザーがパスワードを入力すると、pw_encoding_classオプションに指定したクラスの暗号化メソッドによって暗号化され、データベースに格納されている暗号化されたパスワードと比較されます。データベースに格納されているパスワードの復号化を試みることはありません。

 

Application Server Control内のDBTableOraDataSourceLoginModuleの構成

「Application Server Controlでのカスタム・セキュリティ・プロバイダの構成」では、デプロイ時のカスタム・ログイン・モジュールの指定と構成、デプロイ後のカスタム・ログイン・モジュールの変更、ログイン・モジュールの追加、ログイン・モジュールの更新について説明します。ここに示す手順でDBTableOraDataSourceLoginModuleを構成できます。Application Server Controlコンソール・ログイン・モジュール構成ページでは、ログイン・モジュール・クラスを指定し、前項の「DBTableOraDataSourceLoginModuleオプション」に記載されたオプションに対応する任意の数のプロパティの名前と値を指定します。

AdmintoolのDBTableOraDataSourceLoginModuleの構成

Application Server Controlコンソールを使用する以外の方法として、OracleAS JAAS Provider AdmintoolからDBTableOraDataSourceLoginModuleを構成することもできます。ログイン・モジュールでのAdmintoolの使用は、「Admintoolを使用したログイン・モジュールの構成とRMIパーミッションの付与」を参照してください。

次に例を示します。

java -jar jazn.jar -addloginmodule application_name \
     oracle.security.jazn.login.module.db.DBTableOraDataSourceLoginModule \
     required data_source_name="jdbc/OracleDS" roles_fk_column="username" \
     table="userinfo"  groupMembershipTableName="groupinfo" \
     groupMembershipGroupFieldName="role" usernameField="username" \
     user_pk_column="username" passwordField="password" casing="sensitive"

system-jazn-data.xml内のサンプルDBTableOraDataSourceLoginModule設定

ログイン・モジュールと同様に、オプション設定およびその他の構成は、system-jazn-data.xmlファイルの<jazn-loginconfig>要素内に格納されます。次に例を示します。

<jazn-loginconfig>
   <application>
      <name>application_name</name>
      <login-modules>
         <login-module>
            <class>
              oracle.security.jazn.login.module.db.DBTableOraDataSourceLoginModule
            </class>
            <control-flag>required</control-flag>
            <options>
               <option>
                  <name>data_source_name</name>
                  <value>jdbc/OracleDS</value>
               </option>
               <option>
                  <name>table</name>
                  <value>userinfo</value>
               </option>
               <option>
                  <name>roles_fk_column</name>
                  <value>userName</value>
               </option>
               <option>
                  <name>groupMembershipGroupFieldName</name>
                  <value>role</value>
               </option>
               <option>
                  <name>user_pk_column</name>
                  <value>userName</value>
               </option>
               <option>
                  <name>passwordField</name>
                  <value>passWord</value>
               </option>
               <option>
                  <name>groupMembershipTableName</name>
                  <value>groupinfo</value>
               </option>
               <option>
                  <name>usernameField</name>
                  <value>userName</value>
               </option>
               <option>
                  <name>casing</name>
                  <value>sensitive</value>
               </option>
            </options>
         </login-module>
      </login-modules>
   </application>
   ...
</jazn-loginconfig>

関連項目

 

DBTableOraDataSourceLoginModuleのプリンシパル

DBTableOraDataSourceLoginModuleは次のプリンシパルを使用します。

DBTableOraDataSourceLoginModuleに渡されるサブジェクトには、これらプリンシパル・タイプのインスタンスが埋め込まれます。

ユーザー表内のユーザー名(tableオプションで指定された表の、usernameFieldオプションで指定された列内の名前)には、対応するDBUserPrincipalインスタンスがサブジェクト内にあります。

ロール表内のロール名(groupMembershipTableNameオプションで指定された表の、groupMembershipGroupFieldNameオプションで指定された列内の名前)には、対応するDBRolePrincipalインスタンスがサブジェクト内にあります。

ユーザーまたはロールへのパーミッションの付与には、次のようにAdmintoolを使用できます。

% java -jar jazn.jar -grantperm \
       oracle.security.jazn.login.module.db.principals.DBUserPrincipal name \
       permissionclass [permission_parameters] 

% java -jar jazn.jar -grantperm \
       oracle.security.jazn.login.module.db.principals.DBRolePrincipal name \
       permissionclass [permission_parameters] 

この構文で、nameは、DBUserPrincipalインスタンスまたはDBRolePrincipalインスタンスの名前です。permissionclassは、付与するパーミッションのパーミッション・クラスの完全修飾名です。permission_parametersはパーミッション・クラス(たとえば、RMIPermissionlogin)の該当するパラメータです。


重要

パーミッション・クラスがクラスパス内にあることを確認してください。 


パスワード暗号化のDBLoginModuleEncodingInterfaceの実装

DBTableOraDataSourceLoginModuleでパスワードを暗号化するには、暗号化を実行するための次のインタフェースの実装を使用する必要があります。

oracle.security.jazn.login.module.db.DBLoginModuleEncodingInterface

実装するクラスには、ログイン・モジュールから呼び出される次のメソッドを実装する必要があります。

このメソッドは、暗号化するテキスト文字列(パスワードなど)、および(適用可能な場合)ログイン・モジュールのpw_keyオプションに設定されているようなキーを指定する文字列を取ります。このメソッドは、(指定されている場合はキーを使用して)所定のアルゴリズムでテキスト文字列を暗号化し、必要に応じて、所定のエンコード規格(たとえば、Base64Encoding)で暗号化後のバイナリ・データをフォーマットします。暗号化されたダイジェスト文字列を出力します。

MD5やSHA1など、キーを使用しないアルゴリズムでは、キーを渡しても無視されます。pw_keyオプションが設定されていない場合、値はnullとなり、nullが渡されます。

Oracleでは、oracle.security.jazn.login.module.db.utilパッケージに次の実装を提供します。

前の機能: DataSourceUserManager(非推奨)

OC4J 10.1.3.1実装でDBTableOraDataSourceLoginModuleを実装する以前は、com.evermind.sql.DataSourceUserManagerクラスによって同等の機能が使用できていました。この機能は下位互換性を維持するために現在でもサポートされていますが、非推奨であり、将来のリリースではサポートされなくなります。かわりにDBTableOraDataSourceLoginModuleを使用してください。

しかし、資料を完全なものにするため、DataSourceUserManager機能についても資料に記載しています。


注意

  • この場合、データベースをデータソースとして指定し、構成内にはこのデータソース用のJNDIロケーションを提供する必要があります。構成には、関連するデータベース表とフィールドも指定します。

  • OC4J 10.1.3.x実装では、DataSourceUserManager により、データベースからグループ情報のみが取得されますが、これは以前の実装における動作とは異なっています。したがって、必要に応じてデータベース内のユーザーにグループをマップする必要があります。

 

DataSourceUserManager(後述)を構成する際、必要に応じて表9-4に記載するプロパティの値を指定できます。DataSourceUserManagerインスタンスでは、これらのプロパティを使用して、現行の各ユーザーと関連する資格証明がリストされているユーザー定義のデータベース表にアクセスします。

表9-4    DataSourceUserManagerのプロパティ 
プロパティ  説明 

dataSource 

使用するインストール済データソース(データベース)のJNDIロケーション。 

table 

ユーザー・データが含まれるデータベース表の名前。 

usernameField 

データベース表におけるユーザー名用の列名。 

passwordField 

データベース表におけるパスワード用の列名 

certificateIssuerField 

証明書発行者の識別子(必要な場合)。 

certificateSerialField 

証明書発行者のシリアルID(必要な場合)。 

localeField 

ロケール(必要な場合)。 

defaultGroups 

ユーザーがメンバーとなるグループのカンマ区切りリスト。 

groupMembershipTableName 

defaultGroupsの使用では不十分な場合に、ユーザーをグループにマップするオプションのデータベース表の名前。 

groupMembershipUserNameFieldName 

グループ・メンバーシップ・データベース表におけるユーザー名用の列名(必要な場合)。 

groupMembershipGroupFieldName 

グループ・メンバーシップ・データベース表におけるグループ名用の列名。 

staleness 

フェッチされたユーザー・データ・セットが有効な期間のミリ秒数。デフォルト設定は-1(永久的)です。 

casing 

DataSourceUserManagerによるデータベース内の既知ユーザーのリストとのユーザー名(グループ名ではない)の照合時に、ユーザー名に対する大/小文字の処理方法を制御するフラグ。

デフォルトのsensitive設定では、大/小文字を区別して照合が行われます。toupperおよびtolower設定では、名前は照合用にそれぞれすべて大文字またはすべて小文字に変換されます。 

debug 

デバッグ情報の出力を有効にするフラグ。 

DataSourceUserManagerを使用するには、orion-application.xmlファイルの<user-manager>要素で構成します。これは<orion-application>のサブ要素であり、手動で構成する必要があります。Application Server Control 10.1.3.x実装では、UserManagerはサポートされていません。

<user-manager>class属性にDataSourceUserManagerの完全修飾名を指定します。<property>サブ要素を使用して、設定する各プロパティの名前と値を指定します。

次に例を示します。

<orion-application ... >
   ...
   <user-manager class="com.evermind.sql.DataSourceUserManager">
      <property name="dataSource" value="jdbc/OracleCoreDS" />
      <property name="table" value="j2ee_users" />
      <property name="usernameField" value="username" />
      <property name="passwordField" value="password" />
      <property name="groupMembershipTableName" value="second_table" />
      <property name="groupMembershipGroupFieldName" value="group" />
      <property name="groupMembershipUserNameFieldName" value="userId" />
   </user-manager>
   ...
</orion-application>

カスタムJAASログイン・モジュールの概要

OC4JでサポートされるJAASはJAAS 1.0仕様に完全準拠しているので、ユーザーは、必要に応じてJAAS準拠LoginModule実装をプラグインできます。(OC4Jには、デフォルトのログイン・モジュール実装としてRealmLoginModuleクラスが組み込まれています。このクラスは、ファイルベース・プロバイダまたはOracle Identity Managementと、J2EEセキュリティ制約を結び付けます。)

ユーザーとロールが外部リポジトリで定義されている場合などは、カスタム・ログイン・モジュールの使用をお薦めします。カスタム・ログイン・モジュールの作成時に、次の前提事項を考慮してください。

カスタム・ログイン・モジュールをアプリケーションと関連付ける場合(後述する構成によって)、サブジェクトおよびそれに含まれるプリンシパルは、J2EEセキュリティ制約の評価などの認可タスクすべてに対する唯一の基礎として使用される必要があります。認可時にすべての関連プリンシパルを必ず考慮に入れるために、ログイン・モジュールでは、認証プロセスのコミット・フェーズで、関連プリンシパル(認証済ユーザーが属するすべてのロールなど)をサブジェクトに追加する必要があります。(サブジェクトベースの認可は、role.mapping.dynamicプロパティと関係があります。詳細は「<jazn>のログイン・モジュール用設定」を参照してください。)

カスタム・ログイン・モジュール・フレームワークでは、J2EEの宣言によるセキュリティ・モデルをサポートします。つまり、サブジェクトベースの認可により、アプリケーション・デプロイメント・ディスクリプタ(web.xmlおよびejb-jar.xmlなど)に宣言されているJ2EEのセキュリティ制約が施行されます。

カスタム・ログイン・モジュールはOC4Jのsystem-jazn-data.xmlファイルを介して構成しますが、このファイルは、Application Server ControlコンソールやOracleAS JAAS Provider Admintoolなどのツールを使用して自動的に更新できます。ログイン・モジュールをorion-application.xmlによって構成することもできます。この場合、構成はsystem-jazn-data.xmlにコピーされます。

関連項目

  • 「JAAS認証: ログイン・モジュール」

  • カスタム・ログイン・モジュール開発の一般情報は、次のURLにあるSun社のJAASドキュメントを参照してください。

    http://java.sun.com/j2se/1.4.2/docs/guide/security/jaas/
    JAASLMDevGuide.html
 

ログイン・モジュールのパッケージ化の選択の概要

OC4JまたはJ2SEで提供されるデフォルト・ログイン・モジュールを1つ以上使用する場合、追加の構成は必要ありません。OracleAS JAAS Providerは、デフォルト・ログイン・モジュールを検出できます。

1つ以上のカスタム・ログイン・モジュールとともにアプリケーションをデプロイする場合は、ログイン・モジュールをデプロイし、そのモジュールを実行時に検出できるようにOracleAS JAAS Providerを適切に構成する必要があります。以降の各項では、その実行方法について説明します。

この項では、これらのオプションの詳細を説明します。


重要

アプリケーションがカスタム・ログイン・モジュールを使用して構成されるがログイン・モジュールがクラスパス内に見つからない場合、「クラスが見つかりません」という例外がスローされ、「警告 LoginModuleクラスが見つかりません。欠落したクラスはXxxxxx...」という内容のメッセージが出力されます。 


J2EEアプリケーション内のログイン・モジュールのパッケージ化

ログイン・モジュールが単一のJ2EEアプリケーションでしか使用されない場合は、アプリケーションEARファイルにログイン・モジュールJARファイルを追加して、ログイン・モジュールをアプリケーションの一部としてそのままパッケージ化できます。

ログイン・モジュールは、次の2箇所にあるいずれかの<jazn-loginconfig>設定を介して構成する必要があります。

カスタム・ログイン・モジュールは、アプリケーションのデプロイ時、または後で(セキュリティ・プロバイダをカスタムに変更する場合)、Application Server Controlコンソールを使用して構成できます。構成を行うと、system-jazn-data.xmlが自動的に更新されます。

また、OracleAS JAAS Provider Admintoolを介してカスタム・ログイン・モジュールの管理を行った場合にも、system-jazn-data.xml設定が自動的に更新されます。


注意

別のアプリケーションに同じログイン・モジュールが必要になった場合は、ログイン・モジュールと関連クラスを新規アプリケーションとともに再度パッケージ化するか、オプション・パッケージまたは共有ライブラリとして使用可能にする必要があります。 


関連項目

 

オプション・パッケージとしてのログイン・モジュールの提供

ログイン・モジュールをオプション・パッケージ(旧称「標準拡張機能」)としてデプロイすると、それをOracleAS JAAS Providerで検出できます。追加構成は不要です。この方法でデプロイしたログイン・モジュールは、複数のアプリケーションで共有できます。

オプション・パッケージとしてデプロイするには、次の2つの方法があります。

また、ログイン・モジュールは、system-jazn-data.xml内にも構成する必要があります(「system-jazn-data.xml内のログイン・モジュール設定」を参照)。

関連項目

  • 標準「オプション・パッケージ」のデプロイの一般情報は、次のURLを参照してください。

    http://java.sun.com/j2se/1.4.2/docs/guide/extensions
    
 

OC4J共有ライブラリとしてのログイン・モジュールの提供

OracleAS JAAS Providerは、OC4Jのクラス・ロード・アーキテクチャと統合されています。このため、ログイン・モジュールは、OC4J共有ライブラリとしてロードすることで、アプリケーションで使用できるようになります。「ライブラリを共有するためのタスク」を参照してください。

Application Server Controlでのカスタム・セキュリティ・プロバイダの構成

この項では、Application Server Controlコンソールを使用したカスタム・セキュリティ・プロバイダ(カスタム・ログイン・モジュール)の次の管理タスクについて説明します。

デプロイ時のカスタム・セキュリティ・プロバイダの指定および構成

カスタム・セキュリティ・プロバイダの使用を計画している場合は、Application Server Controlを介してアプリケーションをデプロイする際に、カスタム・ログイン・モジュールを構成できます。

「デプロイ: デプロイ設定」ページで、次の手順を実行します(このページへのナビゲート方法は、「Application Server Controlを介したアプリケーションのデプロイ」を参照してください)。

  1. 「セキュリティ・プロバイダの選択」タスクを選択します。

  2. 表示される「デプロイ設定: セキュリティ・プロバイダの選択」ページで、「セキュリティ・プロバイダ」ドロップダウン・リストから「カスタム」を選択します。

  3. 「カスタム・セキュリティ・プロバイダの構成」(「カスタム」を選択すると表示される)で、アプリケーションに対して検出されたカスタム・ログイン・モジュールを編集または削除、あるいは新規のカスタム・ログイン・モジュールを追加できます。

  4. 再表示される「デプロイ設定: セキュリティ・プロバイダの選択」ページで、「OK」を選択して、セキュリティ・プロバイダの選択を終了します。

  5. 「デプロイ: デプロイ設定」ページが再表示されるので、「デプロイ」を選択してデプロイを完了するか、または必要に応じて他のタスクを選択します。タスクのリストは、「Application Server Controlを介したアプリケーションのデプロイ」を参照してください。

Application Server Controlからカスタム・ログイン・モジュールをデプロイまたは構成すると、orion-application.xmlファイルに次の設定が自動的に挿入されます。

<jazn provider="XML">
   <property name="role.mapping.dynamic" value="true" />
   <property name="custom.loginmodule.provider" value="true" />
</jazn>


注意

  • カスタム・ログイン・モジュールの権限はsystem-jazn-data.xmlに格納されていますが、Application Server Controlを介しては構成できません。

  • 規則上、カスタム・ログイン・モジュールの使用時には、provider="XML"<jazn>設定があります。

  • カスタム・ログイン・モジュールの構成設定の反映先は、system-jazn-data.xmlファイルの<jazn-loginconfig>要素の下です(「system-jazn-data.xml内のログイン・モジュール設定」を参照)。

 

関連項目

 

デプロイ時のカスタム・ログイン・モジュール構成の編集

カスタム・セキュリティ・プロバイダを使用するアプリケーションのデプロイ時にカスタム・ログイン・モジュールを編集するには、「デプロイ設定: セキュリティ・プロバイダの選択」ページ(このページへのナビゲート方法は、前述の「デプロイ時のカスタム・セキュリティ・プロバイダの指定および構成」を参照)の「カスタム・セキュリティ・プロバイダの構成」を選択して、次の手順を実行します。

  1. ログイン・モジュール・クラスのリストで、目的のログイン・モジュールに対して「編集」タスクを選択します。

  2. 「デプロイ設定: セキュリティ・プロバイダの選択: ログイン・モジュールの編集」ページで、次を行います。

    • ドロップダウン・リストから「ログイン・モジュール制御フラグ」の値(Required、Requisite、Optional、Sufficientのいずれか)を指定します。表9-5で、この設定について説明します。

    • (オプション)プロパティを作成する場合は、「行の追加」を選択します。

    • (オプション)「プロパティ」リスト内の任意のプロパティの名前または値を編集します。

    • (オプション)プロパティを削除する場合は、そのプロパティに対して「削除」タスクを使用します。

    • 「続行」を選択して「デプロイ設定: セキュリティ・プロバイダの選択」ページに戻り、「デプロイ時のカスタム・セキュリティ・プロバイダの指定および構成」に記載のデプロイ手順に戻ります。

      表9-5    ログイン・モジュール制御フラグ 
      フラグ  意味 

      Required 

      ログイン・モジュールの成功は表面上必要です。成功するかどうかに関係なく、認証はログイン・モジュール・リストの下位に進みます。  

      Requisite 

      ログイン・モジュールは表面上成功する必要があります。成功すると、認証は引き続きログイン・モジュール・リストの下位に進みます。失敗すると、制御は即時にアプリケーションに戻ります(認証はログイン・モジュール・リストの下位に進みません)。  

      Sufficient 

      ログイン・モジュールの成功は必須ではありません。成功すると、制御は即時にアプリケーションに戻り、認証はログイン・モジュール・リストの下位に進みません。失敗すると、認証は引き続きログイン・モジュール・リストの下位に進みます。  

      Optional 

      ログイン・モジュールの成功は必須ではありません。成功するかどうかに関係なく、認証はログイン・モジュール・リストの下位に進みます。  

これらの制御フラグはjavax.security.auth.login.Configurationクラスの標準機能によって使用されます。全体の認証は、RequiredおよびRequisiteのログイン・モジュールがすべて成功した場合にのみ成功します。ただし、Sufficientのログイン・モジュールが構成されていて成功した場合には、ログイン・モジュール・リスト内のSufficientのログイン・モジュールの前にあるRequiredおよびRequisiteのログイン・モジュールのみ成功する必要があります。

デプロイ時のカスタム・ログイン・モジュールの追加

カスタム・セキュリティ・プロバイダを使用するアプリケーションのデプロイ時にカスタム・ログイン・モジュールを追加するには、「デプロイ設定: セキュリティ・プロバイダの選択」ページ(このページへのナビゲート方法は、前述の「デプロイ時のカスタム・セキュリティ・プロバイダの指定および構成」を参照)の「カスタム・セキュリティ・プロバイダの構成」を選択して、次の手順を実行します。

  1. 「ログイン・モジュールの追加」を選択します。

  2. 「デプロイ設定: セキュリティ・プロバイダの選択: ログイン・モジュールの追加」ページで、次を行います。

    • ログイン・モジュールのパッケージとクラス名を指定します。

    • ドロップダウン・リストから「ログイン・モジュール制御フラグ」の値(Required、Requisite、Optional、Sufficientのいずれか)を指定します。この設定の詳細は、前項、表9-5を参照してください。

    • (オプション)プロパティを作成する場合は、「行の追加」を選択します。

    • (オプション)「プロパティ」リスト内の任意のプロパティの名前または値を編集します。

    • (オプション)プロパティを削除する場合は、そのプロパティに対して「削除」タスクを使用します。

    • 「続行」を選択して「デプロイ設定: セキュリティ・プロバイダの選択」ページに戻り、「デプロイ時のカスタム・セキュリティ・プロバイダの指定および構成」に記載のデプロイ手順に戻ります。

デプロイ後のカスタム・セキュリティ・プロバイダへの変更

アプリケーションで使用するセキュリティ・プロバイダは、前述のようにデプロイ時に選択できます。また、デプロイ後に、異なるセキュリティ・プロバイダに変更することもできます。カスタム・セキュリティ・プロバイダには次の手順で変更できます。

  1. 「アプリケーションの「セキュリティ・プロバイダ」ページへのナビゲート」の説明に従って、アプリケーションの「セキュリティ・プロバイダ」ページを表示します。

  2. 「セキュリティ・プロバイダ」ページで、「セキュリティ・プロバイダの変更」を選択します。

  3. 「セキュリティ・プロバイダの変更」ページで、ドロップダウンから「カスタム・セキュリティ・プロバイダ」を選択します。

  4. 「ログイン・モジュール」(ドロップダウンの「カスタム・セキュリティ・プロバイダ」を選択すると表示される)で、使用する最初のログイン・モジュールを次のように指定します。後で「セキュリティ・プロバイダ」に戻って、ログイン・モジュールを追加することもできます(次項、「カスタム・セキュリティ・プロバイダへのログイン・モジュールの追加」を参照)。

    • ログイン・モジュールのパッケージとクラス名を指定します。

    • ドロップダウン・リストから「ログイン・モジュール制御フラグ」の値(Required、Requisite、Optional、Sufficientのいずれか)を指定します。この設定の詳細は、
      表9-5を参照してください。

    • (オプション)プロパティを作成する場合は、「行の追加」を選択します。

    • (オプション)「プロパティ」リスト内の任意のプロパティの名前または値を編集します。

    • (オプション)プロパティを削除する場合は、そのプロパティに対して「削除」タスクを使用します。

    • 「OK」を選択し、変更を終了します。

ここで、「セキュリティ・プロバイダ」ページに戻り、変更を反映するためにアプリケーションを再起動するよう求められます。

カスタム・セキュリティ・プロバイダへのログイン・モジュールの追加

デプロイ時またはデプロイ後にカスタム・セキュリティ・プロバイダを設定後、カスタム・ログイン・モジュールを追加するには次のようにします。

  1. 「アプリケーションの「セキュリティ・プロバイダ」ページへのナビゲート」の説明に従って、アプリケーションの「セキュリティ・プロバイダ」ページを表示します。

  2. 「セキュリティ・プロバイダ」ページの「ログイン・モジュール」で、「作成」を選択します。

  3. 「ログイン・モジュールの追加」ページで、次を行います。

    • ログイン・モジュールのパッケージとクラス名を指定します。

    • ドロップダウン・リストから「ログイン・モジュール制御フラグ」の値(Required、Requisite、Optional、Sufficientのいずれか)を指定します。この設定の詳細は、
      表9-5を参照してください。

    • (オプション)プロパティを作成する場合は、「行の追加」を選択します。

    • (オプション)「プロパティ」リスト内の任意のプロパティの名前または値を編集します。

    • (オプション)プロパティを削除する場合は、そのプロパティに対して「削除」タスクを使用します。

    • 「OK」を選択し、変更を終了します。

「セキュリティ・プロバイダ」ページが再表示されます。このページで設定を確認できます。

カスタム・セキュリティ・プロバイダのログイン・モジュールの更新

デプロイ時またはデプロイ後にカスタム・セキュリティ・プロバイダを設定後、カスタム・ログイン・モジュールを更新するには次のようにします。

  1. 「アプリケーションの「セキュリティ・プロバイダ」ページへのナビゲート」の説明に従って、アプリケーションの「セキュリティ・プロバイダ」ページを表示します。

  2. 「セキュリティ・プロバイダ」ページでログイン・モジュール・クラスのリストから、更新するログイン・モジュールについて「編集」タスクを選択します。

  3. 「ログイン・モジュールの編集」ページで、次を行います。

    • (オプション)ドロップダウン・リストから「ログイン・モジュール制御フラグ」の値(Required、Requisite、Optional、Sufficientのいずれか)を更新します。この設定の詳細は、表9-5を参照してください。

    • (オプション)プロパティを作成する場合は、「行の追加」を選択します。

    • (オプション)「プロパティ」リスト内の任意のプロパティの名前または値を編集します。

    • (オプション)プロパティを削除する場合は、そのプロパティに対して「削除」タスクを使用します。

    • 「適用」を選択して変更を終了します。

これにより、引き続き「ログイン・モジュールの編集」ページが表示されます。ページ上部のブレッドクラムを使用すると、「セキュリティ・プロバイダ」ページに戻れます。

カスタム・セキュリティ・プロバイダからのログイン・モジュールの削除

デプロイ時またはデプロイ後にカスタム・セキュリティ・プロバイダを設定後、カスタム・ログイン・モジュールを削除するには次のようにします。

  1. 「アプリケーションの「セキュリティ・プロバイダ」ページへのナビゲート」の説明に従って、アプリケーションの「セキュリティ・プロバイダ」ページを表示します。

  2. 「セキュリティ・プロバイダ」ページでログイン・モジュール・クラスのリストから、削除するログイン・モジュールについて「削除」タスクを選択します。

  3. 「確認」ページで「はい」を選択します。

「セキュリティ・プロバイダ」ページが再表示されます。このページでログイン・モジュールが削除されたことを確認できます。

Admintoolを使用したログイン・モジュールの構成とRMIパーミッションの付与

この項では、次の状況でOracleAS JAAS Provider Admintoolを使用する方法について説明します。

Admintoolを介したログイン・モジュールの構成

カスタム・ログイン・モジュールの追加および構成用の推奨ツールはApplication Server Controlですが、OracleAS JAAS Provider Admintoolを使用することもできます。次の情報を参照してください。

これらのコマンドは、Admintoolシェルから実行することもできます。


重要

OC4Jを再起動して、変更を有効にします。 


関連項目

 

AdmintoolによるRMIパーミッションの付与

アプリケーションにEJBが含まれる場合、RMIを介してEJBにアクセスするには、適切なユーザー、ロールまたはプリンシパルに対してRMIパーミッションのloginを付与する必要があります。これには、次の例に示すようにAdmintoolを使用できます。

% java -jar jazn.jar -grantperm myrealm -role managers \
       com.evermind.server.rmi.RMIPermission login

% java -jar jazn.jar -grantperm oracle.security.jazn.samples.SamplePrincipal \
       managers com.evermind.server.rmi.RMIPermission login

(ユーザーまたはロールにパーミッションを付与するときには常にレルムを指定しますが、プリンシパルにパーミッションを付与するときには指定しません。)

Oracle Application Server環境に複数のOC4Jインスタンスがある場合、該当のOC4Jインスタンス用のsystem-jazn-data.xmlファイルが更新されるように、適用するOC4Jインスタンスに対して該当のインスタンス名(および該当のホーム・ディレクトリ)を指定する必要があります。環境に応じて適切に%oracleas.oc4j.instance%を設定します。

% java -jar -Doracle.j2ee.home=%ORACLE_HOME%/j2ee/%oracleas.oc4j.instance% \
       jazn.jar -grantperm myrealm -role managers \
       com.evermind.server.rmi.RMIPermission login 

% java -jar -Doracle.j2ee.home=%ORACLE_HOME%/j2ee/%oracleas.oc4j.instance% \
       jazn.jar -grantperm oracle.security.jazn.samples.SamplePrincipal managers \
       com.evermind.server.rmi.RMIPermission login 


重要

OC4Jを再起動して、変更を有効にします。 


関連項目

 

各OC4J構成ファイル内のログイン・モジュール構成の概要

この項では、カスタム・ログイン・モジュールの構成を含む各ファイルについて説明します。

system-jazn-data.xml内のログイン・モジュール設定

system-jazn-data.xmlファイルは、ログイン・モジュール構成のリポジトリです。

Application Server ControlまたはOracleAS JAAS Provider Admintoolを介してログイン・モジュールの管理を行うと、system-jazn-data.xmlの設定が自動的に更新されます。


注意

複数のOC4Jインスタンスがある場合は、ログイン・モジュール構成がインスタンス固有のsystem-jazn-data.xmlファイルに追加されます。ORACLE_HOME/j2ee/home/system-jazn-data.xmlには追加されません。 


<jazn-loginconfig>要素には、アプリケーションをログイン・モジュールに関連付ける情報が含まれます。

デプロイ時にこの情報がorion-application.xmlファイルにある場合(「orion-application.xml内の<jazn-loginconfig>での設定」を参照)、system-jazn-data.xmlファイルはそれに応じて更新されます。

例9-1    jazn-loginconfig要素の例

<jazn-data>
  ..
  <jazn-loginconfig>
    <application>
      <name>myapp</name>
      <login-modules>
        <login-module>
          <class>mypath.MyLoginModule</class>
          <control-flag>required</control-flag>
          <options>
            <option>
              <name>myoptionname</name>
              <value>myoptionvalue</value>
            </option>
          </options>
        </login-module>
      </login-modules>
    </application>
  </jazn-loginconfig> 
  ..
</jazn-data>

このフラグメントはログイン・モジュールMyLoginModuleとアプリケーションmyappを関連付けます。


注意

system-jazn-data.xmlファイルからRealmLoginModuleのログイン構成情報を削除しないでください。 


関連項目

 

orion-application.xml内のログイン・モジュール設定

この項では、OC4Jアプリケーション・レベルのディスクリプタorion-application.xml内のログイン・モジュール向けの設定について説明します。内容は次のとおりです。

orion-application.xml内の<jazn-loginconfig>での設定

system-jazn-data.xml内の<jazn-loginconfig>要素での設定は、前述の「system-jazn-data.xml内のログイン・モジュール設定」を参照してください。この要素はデプロイの前にorion-application.xmlに追加でき、行った設定はsystem-jazn-data.xmlファイルに自動的に書き込まれます。また、アプリケーションをアンデプロイすると、<jazn-loginconfig>設定はsystem-jazn-data.xmlから自動的に削除されます。

<jazn>のログイン・モジュール用設定

次の<jazn>のプロパティはログイン・モジュール構成固有です。

これらのプロパティは、orion-application.xml<jazn-loginconfig>要素があるとき、または「デプロイ時のカスタム・セキュリティ・プロバイダの指定および構成」の説明のようにApplication Server Controlコンソールを使用してカスタム・ログイン・モジュールをデプロイして構成するときは、次の例に示すようにorion-application.xml内で自動的にtrueに設定されます。

<jazn provider="XML" ... >
   <property name="role.mapping.dynamic" value="true" />
   <property name="custom.loginmodule.provider" value="true" />
</jazn>

JNDIコンテキストへのアクセス用の<namespace-access>の設定

アプリケーションにEJBが含まれている場合は、アプリケーションのサーバー・サイドJNDIコンテキストでオブジェクトの読取り(検索)および書込み(バインド)を行うためのネームスペース・アクセス権を、必要に応じてリモート・クライアントに付与する必要があります。

orion-application.xmlから抜粋した次の例では、読取り操作を行うためのネームスペース・アクセス権をmanagersおよびdevelopersロールに付与する方法を示しています。

<orion-application ... >
   ...
   <namespace-access>
      <read-access>
         <namespace-resource root="">
            <security-role-mapping name="sr_developer">
               <group name="developers"/>
            </security-role-mapping>
            <security-role-mapping name="sr_manager">
               <group name="managers"/>
            </security-role-mapping>
         </namespace-resource>
      </read-access>
   </namespace-access>
   ...
</orion-application>

ここでは、示されたロール・マッピングがすでにorion-application.xml内で設定されていることを前提にしています。

関連項目

 

マッピング属性の指定

ログイン・モジュール用に、Oracle Internet Directory(OID)プロバイダのマッピング属性は、デフォルトで"DN"に設定されます。

このデフォルト値は、mapping.attributeプロパティの値を構成して変更できます。

  1. $Oracle_Home/j2ee/<oc4j_inst>/config/jazn.xmlファイルを探します。

  2. mapping.attributeプロパティ構成を<jazn>タグに追加します。次に例を示します。

    <jazn provider... > 
    ... 
       <property name = "mapping.attribute" value="cn"/> 
    ... 
    </jazn> 
    
    
  3. OC4Jインスタンスを再起動します。

jazn.xmlファイルのmapping.attribute属性に依存するログイン・モジュールは、次のとおりです。

これらのログイン・モジュールのマッピング属性は、前述のようにjazn.xmlファイルで設定する必要があります。

oc4j-ra.xmlでのログイン・モジュール設定(J2EE Connector Architecture)

リソース・アダプタを構成するとき、次の例のように、oc4j-ra.xmlファイルの各<connector-factory>要素では、異なるJAASログイン・モジュールを指定できます。この例では、Oracle JDBCを介してデータベースに接続するための<config-property>の設定も示しています。

<oc4j-connector-factories ... >
  ...
  <connector-factory connector-name="myBlackbox" location="eis/myEIS1"> 
     <config-property name="connectionURL"
                      value="jdbc:oracle:thin:@localhost:5521/myservice" />
     <security-config use="jaas-module">
        <jaas-module>
           <jaas-application-name>JAASModuleDemo</jaas-application-name>
        </jaas-module>
     </security-config>
  </connector-factory>
  ...
</oc4j-connector-factories>

関連項目

  • リソース・アダプタの構成の詳細は、『Oracle Containers for J2EEリソース・アダプタ管理者ガイド』を参照してください。

 

手順: カスタム・ログイン・モジュールとOC4Jの統合

ログイン・モジュールの開発作業は、標準的な開発、パッケージ化およびデプロイのサイクルをたどります。EJBを含むアプリケーションでは、RMIパーミッションを付与し、必要に応じてネームスペース・アクセス権を構成する必要があります。以降の各項では、このサイクルの各ステップについて説明します。

  1. ログイン・モジュールの開発

  2. ログイン・モジュールの構成とパッケージ化

  3. ネームスペース・アクセス権とロール・マッピングの構成(必要な場合)

  4. ログイン・モジュールのデプロイ

  5. RMIパーミッションの付与(適用可能な場合)

  6. JNDIプロパティの設定(適用可能な場合)

ログイン・モジュールの開発

JAASサービス・プロバイダ・インタフェースに従ってJAAS準拠のLoginModule実装を開発します。

ログイン・モジュールをアプリケーションと関連付けるとき(前述の<jazn-loginconfig>構成で実行)、OC4Jはサブジェクトに設定されたプリンシパルを使用して、要求されたJ2EEリソースへのアクセス権をクライアントが持っているかどうかを調べます。したがって、ログイン・モジュールはロール、ユーザーがメンバーとなっているロールをすべて正しく設定する必要があります。

次の例では、ログイン・モジュールはdeveloperユーザーを認証します。ユーザーが正常に認証された後、ユーザーに関連付けられたロールに対応するプリンシパルが、現在認証されたサブジェクトに追加されます。developerユーザーがdevelopersロールのメンバーであることを想定しています。

if(username.equals("developer") && password.equals("welcome")) 
{
   _succeeded = true;
   _name = "developer";
   _password = password.toCharArray();
   _authPrincipals = new SamplePrincipal[2];
   //Adding username as principal to the subject
   _authPrincipals[0] = new SamplePrincipal("developer");
   //Adding role developers to the subject
   _authPrincipals[1] = new SamplePrincipal("developers");
}

関連項目

 

ログイン・モジュールの構成とパッケージ化

「ログイン・モジュールのパッケージ化の選択の概要」では、アプリケーションにアクセスできるようにログイン・モジュールをパッケージ化する様々な方法をまとめています。各選択肢を次に示します。

ログイン・モジュールの構成を指定できる方法にはいくつかの選択肢があります。

次の項では、キーの構成を中心に説明します。

ログイン・モジュールの使用を有効にする構成

OC4Jでは、セキュリティ・チェックを実行するカスタム・ログイン・モジュールを使用するためにorion-application.xmlファイルに次の構成を必要とします。これは、Application Server Controlまたはorion-application.xmlでログイン・モジュール構成を指定すると、自動的に実行されます。

<jazn provider="XML" > 
   <property name="role.mapping.dynamic" value="true"/> 
   <property name="custom.loginmodule.provider" value="true"/>
</jazn>

デプロイ後にorion-application.xmlファイルを調べてこれを確認できます。

ログイン・モジュールの構成

次の構成は、「カスタム・ログイン・モジュールの例」に示すログイン・モジュールのサンプルです。

<!-- Configuring a Login Module in an Application EAR file.  -->
<jazn-loginconfig>
  <application>
    <name>cutomjaas</name>
    <login-modules>
      <login-module>
        <class>oracle.security.jazn.samples.SampleLoginModule</class>
        <control-flag>required</control-flag>
        <options>
          <option>
            <name>debug</name>
            <value>true</value>
          </option>
        </options>
      </login-module>
    </login-modules>
  </application>
</jazn-loginconfig>

デプロイ前にこの構成を手動でorion-application.xmlファイル内に配置することも、Application Server Controlからアプリケーションをデプロイする場合に、デプロイ中にプロンプトに応じてパラメータ(クラス名、制御フラグ、オプション名および値)を設定することもできます。いずれの場合も、構成は自動的にsystem-jazn-data.xmlに書き込まれます。

ネームスペース・アクセス権とロール・マッピングの構成(必要な場合)

アプリケーションにEJBが含まれる場合、orion-application.xml内にネームスペース・アクセス権を構成します。これは、アプリケーションのサーバー・サイドJNDIコンテキストのオブジェクトで、必要に応じて、リモート・クライアントが読取り(検索)操作または書込み(バインド)操作のJNDIバインディングにアクセスできるようにします。次の例に、ネームスペース・アクセス権をmanagersおよびdevelopersという名前のロールに付与する方法を示します。

<orion-application ... >
   ...
   <namespace-access>
      <read-access>
         <namespace-resource root="">
            <security-role-mapping name="sr_developer">
               <group name="developers"/>
            </security-role-mapping>
            <security-role-mapping name="sr_manager">
               <group name="managers"/>
            </security-role-mapping>
         </namespace-resource>
      </read-access>
   </namespace-access>
   ...
</orion-application>

これは、次のorion-application.xmlの例に示すように、ロール・マッピング(アプリケーション内で定義された論理ロールの、カスタム・ログイン・モジュールでサポートされるロールへのマッピング)が適切に定義されていることを前提としています。

<orion-application ... >
   ...
   <!-- Mapping the logical roles to the container roles -->
   <security-role-mapping name="sr_manager">
      <group name="managers" />
   </security-role-mapping>
   <security-role-mapping name="sr_developer">
      <group name="developers" />
   </security-role-mapping>
   ...
</orion-application>

ロール・マッピングはApplication Server Controlから指定できます。「セキュリティ・ロールのマッピング」を参照してください。これにより、orion-application.xmlのエントリが自動的に追加されます。

ログイン・モジュールのデプロイ

「ログイン・モジュールのパッケージ化の選択の概要」では、ログイン・モジュールをアプリケーションとともに、または個別に(オプション・パッケージまたは共有ライブラリとして)デプロイする方法について説明します。

「デプロイ時のカスタム・セキュリティ・プロバイダの指定および構成」では、アプリケーションのデプロイ時にApplication Server Controlによってログイン・モジュールを構成してデプロイする方法について説明します。

RMIパーミッションの付与(適用可能な場合)

アプリケーションにEJBが含まれる場合、RMIを介してEJBにアクセスするには、適切なユーザー、ロールおよびプリンシパルに対してRMIパーミッションのloginを付与する必要があります。これには、Admintoolを使用できます。「AdmintoolによるRMIパーミッションの付与」を参照してください。

JNDIプロパティの設定(適用可能な場合)

JNDIを通じてリソースにアクセスするには、jndi.propertiesファイルを構成し、環境に応じてプロバイダURL、プリンシパルおよび資格証明などのプロパティを設定する必要があります。次に例を示します。

java.naming.factory.initial=
                    oracle.j2ee.naming.ApplicationClientInitialContextFactory
java.naming.provider.url=ormi://localhost:23791/customjaas
#java.naming.provider.url=opmn:ormi://localhost:6003:home/customjaas
java.naming.security.principal=manager
java.naming.security.credentials=welcome

ormiプロトコルはスタンドアロンOC4J用、opmn:ormiプロトコルはOracle Application Server環境用です。適切な方をコメント解除します。)

カスタム・ログイン・モジュールの例

この項では、次の場所でのOC4Jの使用方法のサンプルとしてログイン・モジュールのコードとプリンシパルのコードを示します。

http://www.oracle.com/technology/tech/java/oc4j/1013/how_to/index.html

「J2EE Security / JAAS」の下のログイン・モジュールの使用方法を参照してください。

SampleLoginModuleコード

この項では、サンプル・ログイン・モジュールのコードを示します。

package oracle.security.jazn.samples;
 
import java.util.Set;
import java.util.Iterator;
import java.util.Map;
import java.security.Principal;
import javax.security.auth.Subject;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;
 
public class SampleLoginModule implements LoginModule {
 
    // initial state
    protected Subject _subject;
    protected CallbackHandler _callbackHandler;
    protected Map _sharedState;
    protected Map _options;
 
    // configuration options
    protected boolean _debug; 
 
    // the authentication status
    protected boolean _succeeded;
    protected boolean _commitSucceeded;
 
    // username and password
    protected String _name;
    protected char[] _password;
 
    protected Principal[] _authPrincipals;
 
    /*
     * Initialize this LoginModule.
     *
     * subject         the Subject to be authenticated.
     * callbackHandler a CallbackHandler for communicating
     *                 with the end user (prompting for usernames and
     *                 passwords, for example).
     * sharedState     shared LoginModule state.
     * options         options specified in the login
     *                 Configuration for this particular
     *                 LoginModule.
     */
    public void initialize(Subject subject,
                           CallbackHandler callbackHandler,
                           Map sharedState,
                           Map options) {
        this._subject = subject;
        this._callbackHandler = callbackHandler;
        this._sharedState = sharedState;
        this._options = options;
 
        // initialize any configured options
        _debug = "true".equalsIgnoreCase((String) _options.get("debug"));
 
        if (debug()) {
            printConfiguration(this);
        }
    }
 
    final public boolean debug() {
        return _debug;
    }
 
    protected Principal[] getAuthPrincipals() {
        return _authPrincipals;
    }
 
    /*
     * Authenticate the user by prompting for a username and password.
     *
     * return true if the authentication succeeded, or false if this
     *        LoginModule should be ignored.
     * throws FailedLoginException if the authentication fails.
     * throws LoginException       if this LoginModule
     *                             is unable to perform the authentication.
     */
    public boolean login() throws LoginException {
        if (debug())
            System.out.println("\t\t[SampleLoginModule] login");
 
        if (_callbackHandler == null)
            throw new LoginException("Error: no CallbackHandler available " +
                    "to garner authentication information from the user");
 
        // Setup default callback handlers.
        Callback[] callbacks = new Callback[] {
            new NameCallback("Username: "),
            new PasswordCallback("Password: ", false)
        };
 
        try {
            _callbackHandler.handle(callbacks);
        } catch (Exception e) {
            _succeeded = false;
            throw new LoginException(e.getMessage());
        }
 
        String username = ((NameCallback)callbacks[0]).getName();
        String password = 
                   new String(((PasswordCallback)callbacks[1]).getPassword());
 
        if (debug())
        {
            System.out.println("\t\t[SampleLoginModule] username : " + username);
        }
 
        // Authenticate the user. On successfull authentication add principals 
        // to the Subject. The name of the principal is used for authorization by
        // OC4J by mapping it to the value of the name attribute of the group 
        // element in the security-role-mapping for the application.
        if(username.equals("developer") && password.equals("welcome")) 
        {
            _succeeded = true;
            _name = "developer";
            _password = password.toCharArray();
            _authPrincipals = new SamplePrincipal[2];
            //Adding username as principal to the subject
            _authPrincipals[0] = new SamplePrincipal("developer");
            //Adding role developers to the subject
            _authPrincipals[1] = new SamplePrincipal("developers");
        }
        if(username.equals("manager") && password.equals("welcome")) 
        {
            _succeeded = true;
            _name = "manager";
            _password = password.toCharArray();
            _authPrincipals = new SamplePrincipal[3];
            //Adding username as principal to the subject
            _authPrincipals[0] = new SamplePrincipal("manager");
            //Adding roles developers and managers to the subject
            _authPrincipals[1] = new SamplePrincipal("developers");
            _authPrincipals[2] = new SamplePrincipal("managers");
        }
 
      if (username.equals("sirish") && password.equals("sirish"))
      {
            _succeeded = true;
            _password = password.toCharArray();
            _name = "sirish";
            _authPrincipals = new SamplePrincipal[1];
            _authPrincipals[0] = new SamplePrincipal("sirish");
       }
 
        ((PasswordCallback)callbacks[1]).clearPassword();
        callbacks[0] = null;
        callbacks[1] = null;
 
        if (debug())
        {
            System.out.println("\t\t[SampleLoginModule] success : " + _succeeded);
        }
 
        if (!_succeeded)
            throw new LoginException
                            ("Authentication failed: Password does not match");
 
        return true; 
    }
 
    /*
     * This method is called if the LoginContext's
     * overall authentication succeeded
     * (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules
     * succeeded).
     * 
     * If this LoginModule's own authentication attempt
     * succeeded (checked by retrieving the private state saved by the
     * login method, then this method associates a
     * Principal with the Subject located in the
     * LoginModule.  If this LoginModule's own
     * authentication attempted failed, then this method removes
     * any state that was originally saved.
     *
     * return true if this LoginModule's own login and commit
     *        attempts succeeded, or false otherwise.
     * throws LoginException if the commit fails.
     */
    public boolean commit()
            throws LoginException {
        try {
 
            if (_succeeded == false) {
                return false;
            }
 
            if (_subject.isReadOnly()) {
                throw new LoginException("Subject is ReadOnly");
            }
 
            // add authenticated principals to the Subject
            if (getAuthPrincipals() != null) {
                for (int i = 0; i < getAuthPrincipals().length; i++) {
                    if(!_subject.getPrincipals().contains(getAuthPrincipals()[i]))
{
                        _subject.getPrincipals().add(getAuthPrincipals()[i]);
                    }
                }
            }
 
            // in any case, clean out state
            cleanup();
            if (debug()) {
                printSubject(_subject);
            }
 
            _commitSucceeded = true;
            return true;
 
        } catch (Throwable t) {
            if (debug()) {
                System.out.println(t.getMessage());
                t.printStackTrace();
            }
            throw new LoginException(t.toString());
        }
    }
 
    /*
     * This method is called if the LoginContext's
     * overall authentication failed.
     * (the relevant REQUIRED, REQUISITE, SUFFICIENT and OPTIONAL LoginModules
     * did not succeed).
     * 
     * If this LoginModule's own authentication attempt
     * succeeded (checked by retrieving the private state saved by the
     * login and commit methods),
     * then this method cleans up any state that was originally saved.
     *
     * return false if this LoginModule's own login and/or commit attempts
     *        failed, and true otherwise.
     * throws LoginException if the abort fails.
     */
    public boolean abort() throws LoginException {
        if (debug()) {
            System.out.println
                     ("\t\t[SampleLoginModule] aborted authentication attempt.");
        }
 
        if (_succeeded == false) {
            cleanup();
            return false;
        } else if (_succeeded == true && _commitSucceeded == false) {
            // login succeeded but overall authentication failed
            _succeeded = false;
            cleanup();
        } else {
            // overall authentication succeeded and commit succeeded,
            // but someone else's commit failed
            logout();
        }
        return true;
    }
 
    protected void cleanup() {
        _name = null;
        if (_password != null) {
            for (int i = 0; i < _password.length; i++) {
                _password[i] = ' ';
            }
            _password = null;
        }
    }
 
    protected void cleanupAll() {
        cleanup();
 
        if (getAuthPrincipals() != null) {
            for (int i = 0; i < getAuthPrincipals().length; i++) {
                _subject.getPrincipals().remove(getAuthPrincipals()[i]);
            }
        }
    }
 
    /*
     * Logout the user.
     * 
     * This method removes the Principal
     * that was added by the commit method.
     *
     * return true in all cases since this LoginModule
     *        should not be ignored.
     * throws LoginException if the logout fails.
     */
    public boolean logout() throws LoginException {
        _succeeded = false;
        _commitSucceeded = false;
        cleanupAll();
        return true;
    }
 
    // helper methods //
 
    protected static void printConfiguration(SampleLoginModule slm) {
        if (slm == null) {
            return;
        }
        System.out.println("\t\t[SampleLoginModule] configuration options:");
        if (slm.debug()) {
            System.out.println("\t\t\tdebug = " + slm.debug());
        }
    }
 
    protected static void printSet(Set s) {
        try {
            Iterator principalIterator = s.iterator();
            while (principalIterator.hasNext()) {
                Principal p = (Principal) principalIterator.next();
                System.out.println("\t\t\t" + p.toString());
            }
        } catch (Throwable t) {
        }
    }
 
    protected static void printSubject(Subject subject) {
        try {
            if (subject == null) {
                return;
            }
            Set s = subject.getPrincipals();
            if ((s != null) && (s.size() != 0)) {
                System.out.println
                     ("\t\t[SampleLoginModule] added the following Principals:");
                printSet(s);
            }
 
            s = subject.getPublicCredentials();
            if ((s != null) && (s.size() != 0)) {
                System.out.println
              ("\t\t[SampleLoginModule] added the following Public Credentials:");
                printSet(s);
            }
        } catch (Throwable t) {
        }
    }
}

SamplePrincipalコード

この項では、サンプル・プリンシパルのコードを示します。

ログイン・モジュールは、現在のSubjectインスタンス内のSamplePrincipalインスタンスを設定します。SamplePrincipalインスタンスを作成するために、ログイン・モジュールは直接SamplePrincipalコンストラクタを呼び出します。そのため、コンストラクタはパブリックとして定義します。

package oracle.security.jazn.samples;
 
import java.security.Principal;
 
/*
 * This class implements the Principal interface
 * and represents a Sample user.
 *
 * Principals such as this SamplePrincipal
 * may be associated with a particular Subject
 * to augment that Subject with an additional
 * identity.  Authorization decisions can then be based upon 
 * the Principals associated with a Subject.
 * 
 */ 
public class SamplePrincipal implements Principal {
 
    private String _name = null;
        
 
    /*
     * Create a SamplePrincipal with a Sample username.
     *
     */ 
    public SamplePrincipal(String name) {
       if (name == null) 
       throw new NullPointerException("name cannot be null");
        _name = name;
    }
 
    /*
     * Return a string representation of this SamplePrincipal.
     *
     */
    public String getName() {
        return _name;
    }
 
    /*
     * Return a hash code for this SamplePrincipal.
     *
     */
    public int hashCode() {
        return _name.hashCode();
    }
 
    /*
     * Return a string representation of this SamplePrincipal.
     *
     */
    public String toString() {
        return "[SamplePrincipal] : " + _name;
    }
 
    /*
     * Compares the specified Object with this SamplePrincipal
     * for equality.  Returns true if the given object is also a
     * SamplePrincipal and the two SamplePrincipals
     * have the same username.
     *
     */
    public boolean equals(Object o) {
      if (o == null)
          return false;
 
        if (this == o)
            return true;
 
        if (!(o instanceof SamplePrincipal))
            return false;
        SamplePrincipal that = (SamplePrincipal)o;
 
      if (this.getName().equals(that.getName()))
          return true;
      return false;
    }
}

戻る 次へ
Oracle
Copyright © 2003, 2008 Oracle Corporation.

All Rights Reserved.
目次
目次
索引
索引