プライマリ・コンテンツに移動
Oracle® Fusion Middleware Oracle Access Management開発者ガイド
11gリリース2 (11.1.2.3.0) for All Platforms
E67354-04
  ドキュメント・ライブラリへ移動
ライブラリ
製品リストへ移動
製品
目次へ移動
目次

前
 
次
 

2 アクセス・クライアントの開発

Oracle Access Management Access Manager (Access Manager)では、カスタム・アクセス・クライアントを作成するための純粋なJavaソフトウェア開発キット(SDK)およびアプリケーション・プログラミング・インタフェース(API)を提供しています。

この章では、カスタム・アクセス・クライアントの開発方法と次の項目について説明します。

2.1 アクセス・クライアントの開発について

WebGateは、リソースに対するHTTPリクエストを捕捉して、認証と認可のためにOAMサーバーに転送するWebサーバー・プラグインです。WebGateは、アクセス・リクエストに対する実際の強制ポイントとして機能するWebサーバー・エージェントです。複数のWebGateがそのまま使用できる状態で用意されており、アクセス・リクエストを捕捉するOracle HTTP Serverにインストールできます。

アクセス・クライアントとは、11g Access SDKおよびAPIを使用して開発されたカスタムWebGateのことです。標準のWebGateが適切でない場合は、カスタム・アクセス・クライアントを記述してデプロイすることにより、WebリソースまたはWeb以外のリソース(HTTP以外)に対するユーザーまたはアプリケーションからのリクエストを処理できます。

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

2.1.1 Access SDKおよびAPIについて

11g Access SDKは、密結合されている高パフォーマンスの統合の開発においてJavaアプリケーション開発者が使用するためのものです。Access SDKは、オラクル社が様々なエンタープライズ・プラットフォーム(32ビットおよび64ビットの両方のモードを使用)およびハードウェアの組合せで認証した、プラットフォーム非依存パッケージです。これは、Oracle Fusion Middlewareアプリケーション間でサポートされているJDKバージョンで提供されています。詳細は、このガイドの他にOracle Fusion Middleware Oracle Access Management Access Manager Access SDK Java APIリファレンスを参照してください。


注意:

10g (10.1.4.3)のcom.oblix.accessパッケージおよびクラスは非推奨です。非推奨APIは、機能改良などの理由から使用が推奨されておらず、通常はそれにかわるAPIが提供されます。非推奨APIは今後の実装で削除される可能性があります。

開発者はあらゆる新規開発において11g Access SDKを使用することを強くお薦めします。


次のAccess APIが含まれています。

  • oracle.security.am.asdk: 11g OAMサーバー機能を利用するための拡張機能を提供する認証および認可API。11g Access SDK APIは、Oracle Access Manager 10gR3 (10.1.4.3)またはOracle Access Manager 11gR1 (11.1.1.5+)バージョンのサーバーで使用できます。


    注意:

    oracle.security.am.asdkパッケージでは、11g Java APIを提供しています。11gバージョンは10g JNI APIとよく似ていますが、11g OAMサーバーで使用するための拡張機能が備わっています。11g Access SDKは、10gベースのcom.oblix.accessインタフェースをサポートすることで下位互換性を提供しています。機能的な観点からすると、11g Access SDKは10g (10.1.4.3) Access SDKのパリティを維持しており、11g APIレイヤーを使用して既存のカスタム・コードを記述しなおすことができます。

  • com.oblix.access: これは10gバージョンの認証および認可APIに11gリリース用の拡張機能をいくつか加えたものです。10g JNI ASDKで記述されたプログラムとの下位互換性を保つために用意されています。

11g Access SDKには、認証および認可機能が組み込まれています。ただし、管理APIは組み込まれていません(たとえば、11gポリシー・マネージャAPIはありません)。

Access SDKの最も一般的な用途は、Access Managerとその他のアプリケーション(Oracleまたはサード・パーティ)とのカスタム統合の開発を可能にすることです。使用例を次に示します。

  • Oracleがデフォルトで統合を提供していないWebサーバーまたはアプリケーション・サーバー用のカスタム・アクセス・クライアントの開発。

  • Access Manager認証プロセスの一部として格納される可能性があるセッション情報へのアクセス。

  • ユーザー・プリンシパルのHTTPヘッダーを信頼せず、Access ManagerセッションCookieの有効性を確認。

表2-1では、11g Access SDKの主な機能について説明します。

表2-1 11g Access SDKの機能

機能 説明

インストール

クライアント・パッケージ: oamasdk-api.jarおよび11gエージェントの動作に必要なその他のJPS jarファイルを格納した1個のzipファイルで構成されています。サポート・ファイル(署名およびTLSネゴシエーション用)は含まれておらず、個別に生成する必要があります。

サーバー関連コード: コアAccess Managerサーバー・インストールの一部として組み込まれています。

注意: Oracle Access Manager 10g (10.1.4.3)で開発されたアクセス・クライアントおよびプラグインは11gリリースで使用できます。Oracle Access Manager 10g (10.1.4.3)バンドル・パッチは、11gで使用するためのJava SDKコード拡張機能を配布する目的で使用します。

組込みバージョニング

次のことが可能です。

  • インストールされているAccess SDKバージョンの判別

  • 連動できる互換バージョンの検証(Oracle Access Manager 10g (10.1.4.3)および11g)

    一致しない場合、Access SDK関数が停止し、情報メッセージがログに記録され、表示されます。

ロギング

Access SDKロギング・メカニズムにより、ローカル・ファイルに表示する詳細のレベル(情報、警告およびエラーの各レベル)を指定できます。メッセージは、問題を解決するための十分な詳細を提供します。たとえば、互換性のないAccess SDKパッケージが使用されている場合、ログ・メッセージには、バージョン不一致に関する詳細と、遵守する必要があるバージョン基準が含まれます。

SDKが指定期間内に大量のログを生成した場合、ファイル制限または期間に基づいてログのロールオーバーを構成できます。たとえば、ファイル制限に達した場合(または一定時間が経過した場合)、ログ・ファイルはアーカイブ・ディレクトリにコピーされ、新規ログ・ファイルが開始されます。


2.1.2 カスタム・アクセス・クライアントについて

Access SDKを使用すると、認証、認可、監査など保護されたリソースへのアクセスを制御する目的で、Access Managerとのカスタム統合を開発できます。通常このアクセス制御を実現するには、Access SDKランタイムとインタフェースするためのAccess Client APIを起動するアプリケーションまたはプラグインであるカスタム・アクセス・クライアントを開発およびデプロイします。

アクセス・クライアント側のキャッシュがAccess SDKランタイム内で内部的に使用され、処理オーバーヘッドがさらに抑えられます。Access SDKランタイムとOAMサーバーの連携により、動的構成管理が透過的に実行され、それによって、管理コンソールで行ったアクセス・クライアント構成の変更が、対象となるAccess SDKランタイムに自動的に反映されます。

アクセス・クライアントAPIのすべてまたはサブセットを使用することで、目的の機能に応じて、様々なタイプのカスタム・アクセス・クライアントを開発できます。APIは通常、ユーザーとの通信に使用される保護されたリソースおよびネットワーク・プロトコルのタイプは認識しません。たとえば、HTTPプロトコルの詳細およびHTTP Cookieの用途はAccess SDKの範囲外です。非HTTPリソースを保護するアクセス・クライアントは、HTTPリソースを保護するエージェントと同じくらい容易に開発できます。

カスタム・アクセス・クライアント単独で、または他のアクセス・クライアントと組み合せて実行できる一般的な機能は、次のとおりです。

  • 資格証明をAccess Managerおよびその構成済ユーザー・リポジトリに対して検証してユーザーを認証します。

  • ユーザーを認証し、リソースへのアクセスについて認可の有無をチェックします。

  • ユーザーを認証し、セッション・トークンで表された一意のAccess Managerセッションを作成します。

  • ユーザーにより提供されたセッション・トークンを検証し、保護されたリソースへのユーザーのアクセス権を認可します。

  • セッション・トークンまたは名前付きセッション識別子がある場合は、Access Managerセッションを終了します。

  • 名前付きユーザー識別子を指定し、指定ユーザーのAccess Managerセッションを列挙します。

  • Access Managerのカスタム・セッション属性を保存または取得します。

アクセス・クライアントの一部の操作は、指定されたアクセス・クライアント・インスタンスによる使用に制限されています。例は、Oracle Fusion Middleware Oracle Access Management Access Manager Access SDK Java APIリファレンスOperationNotPermittedを参照してください。

アクセス・クライアントは、OAMサーバーで保護されたLDAPドメイン内のリソースへのユーザーのアクセス・リクエストを処理します。一般的には、リソース・リクエストを受け取るサーブレット(プラグイン)またはスタンドアロン・アプリケーションにカスタム・アクセス・クライアント・コードを埋め込みます。このコードは、Access Manager APIライブラリを使用して、OAMサーバー上での認証および認可サービスを実行します。

リソースが保護されていない場合、アクセス・クライアントはリクエストされたリソースに対する自由なアクセスをユーザーに許可します。リソースが保護されていて、ユーザーがアクセスを得るために特定の資格証明を提示できるように認可されている場合は、アクセス・クライアントがそのユーザー資格証明の取得を試み、OAMサーバーが資格証明を確認できるようにします。ユーザーの認証とリソースへの認可が成功すると、アクセス・クライアントは、ユーザーがリソースを利用できるようにします。アクセス・クライアントには、表2-2に示すように各種要素に応じてバリエーションがあります。

表2-2 アクセス・クライアントのバリエーション

バリエーション 説明

アプリケーションのタイプ

スタンドアロン・アプリケーション対サーバー・プラグインです。

開発言語

各開発言語により、APIの基礎となる機能へのインタフェースを選択できます。

11gでは、Javaがカスタム・アクセス・クライアントの唯一の開発言語です。

リソース・タイプ

HTTPおよびHTTP以外の両方のリソースを保護します。

資格証明の取得

他のメソッド間における、HTTPフォーム・ベース入力、セッション・トークンの使用およびコマンド行入力を有効にします。


記述およびデプロイされたカスタム・アクセス・クライアントは、標準のWebGateと同じようにOracle Access Management管理者が管理します。管理コンソールによるカスタム・アクセス・クライアントの管理の詳細は、『Oracle Fusion Middleware Oracle Access Management管理者ガイド』を参照してください。詳細は、次の各項を参照してください。

2.1.2.1 カスタム・アクセス・クライアントを作成するケース

一般に、Oracle Access Managerによってまだデフォルト・ソリューションが用意されていないリソースへのアクセスを制御する必要がある場合に、標準のWebゲートのかわりに、カスタム・アクセス・クライアントをデプロイします。これには次のような場合が含まれます。

  • HTTP以外のリソースの保護。

  • 特殊機能を実装するために開発したカスタムWebサーバーの保護(リバース・プロキシなど)。

  • HTTPとHTTP以外のリソースの組合せを保護するためのシングル・サインオン(SSO)の実装。

    たとえば、Oracle WebLogic ServerクラスタおよびOracle WebLogic Server以外のリソースが含まれる企業環境内でのSSOを容易にするアクセス・クライアントを作成できます。

2.1.2.2 アクセス・クライアントのアーキテクチャ

各アクセス・クライアントは、次の3種類のリソースから構築されます。

  1. カスタム・アクセス・クライアント・コード

    サーブレットまたはスタンドアロン・アプリケーションに組み込まれます。11gリリースでは、Java言語プラットフォームを使用してアクセス・クライアント・コードを記述します。

  2. 構成情報

    • ObAccessClient.xmlファイル: プライマリ構成ファイル。アクセス・クライアント・プロファイルを構成する構成情報が格納されています。

    • cwallet.ssoおよびjps-config.xmlファイル: 11gエージェントの場合のみ。

    • トランスポート・セキュリティ・モードが簡易または証明書の場合、次のファイルが必要です。

      • oamclient-truststore.jks: 証明書発行局のCA証明書が含まれるJKS形式の信頼ストア・ファイル。

      • oamclient-keystore.jks: アクセス・クライアントに対して発行された証明書および秘密鍵が含まれるJKS形式のキー・ストア・ファイル。

      • password.xml: グローバル・パス・フレーズの値を保持するXMLファイル。秘密鍵ファイルを保護する際にも同じパスワードが使用されます。

  3. Access Manager APIライブラリ

    アクセス・クライアントとOAMサーバー間の連携を可能にします。

図2-1は、ホスト・サーバーにインストールされたアクセス・クライアント・コンポーネント間の関係を示しています。

図2-1 アクセス・クライアントのアーキテクチャの詳細

図2-1の説明が続きます
「図2-1 アクセス・クライアントのアーキテクチャの詳細」の説明

2.1.3 アクセス・クライアントのリクエスト処理について

第2.1.2.2項「アクセス・クライアントのアーキテクチャ」で説明しているリソースのタイプにより生じる多様性にかかわらず、アクセス・クライアントの多くは同じ基本ステップに従ってユーザー・リクエストを処理します。ユーザーまたはアプリケーションが、アクセス・クライアントがインストールされているサーバー上で動作するサーブレットまたはアプリケーションに対してリソース・リクエストを発行すると、そのサーブレットまたはアプリケーションに埋め込まれたアクセス・クライアント・コードが図2-2に示す基本プロセスを開始します。図の下に、プロセス概要の詳細の説明を示します。

図2-2 プロセスの概要: リソース・リクエストの処理

図2-2の説明が続きます
「図2-2 プロセスの概要: リソース・リクエストの処理」の説明

  1. アクセス・クライアント・コードが埋め込まれているアプリケーションまたはサーブレットが、ユーザーのリソース・リクエストを受け取ります。

  2. アクセス・クライアントにより、ResourceRequest構造体が構成されます。この構造体は、リクエストされたリソースが保護されているかどうかをアクセス・クライアント・コードがOAMサーバーに問い合せるために使用されます。

  3. OAMサーバーが応答します。

  4. 状況に応じて、次のいずれかが発生します。

    • リソースが保護されていない場合、アクセス・クライアントはDenyOnNotProtectedフラグの値に基づいて、リソースに対するアクセス権を付与または拒否します。デフォルト値はtrueです。

      Access Manager 11gエージェントの場合、DenyOnNotProtectedフラグは常にtrueであり、変更できません。

    • リソースが保護されている場合、アクセス・クライアントがAuthenticationScheme構造体を構成、使用して、ユーザーがどの資格証明を提示する必要があるかをOAMサーバーに問い合せます。このステップは、アクセス・クライアントでリソース別の認証スキームを使用できる場合にのみ必要です。

  5. OAMサーバーが応答します。

  6. アプリケーションは、フォームまたはその他の手段を使用してユーザー資格証明を要求します。場合によっては、ユーザー資格証明が次の一部としてすでに発行されていることがあります。

    • 有効なセッション・トークン

    • Webブラウザからの入力

    • アクセス・クライアント・アプリケーションを起動したコマンド行スクリプトの引数またはキーボード入力

  7. ユーザーがアプリケーションに応答します。

  8. アクセス・クライアントによりUserSession構造体が構成され、この構造体を通して、OAMサーバーはユーザー資格証明を取得し、資格証明をOracle Access Managerユーザー・ディレクトリ内のユーザー・プロファイルにマップします。

  9. 資格証明が有効と判定されると、アクセス・クライアントがユーザーのセッション・トークンを作成し、認可リクエストをOAMサーバーに送信します。このリクエストには、ユーザーID、ターゲット・リソースの名前およびリクエストされた操作が含まれています。

    Access SDKを使用して開発されたアクセス・クライアントの場合、SSOトークンが名前なしの文字列型として発行されます。既存のUserSessionオブジェクトに対してgetSessionToken()を使用すると、そのセッションのトークンが返されます。既存のトークンがある場合は、そのトークンを使用してユーザー・セッション・オブジェクトを構成できます。トークンは暗号化されおり、ユーザーには理解できませんが、内部的には10g形式または11g形式になっています。

  10. アクセス・クライアントはリソースへのアクセス権をユーザーに付与しますが、これはユーザーがリクエストした特定のリソースに対する操作を行う権限がある場合に限られます。

図2-2に示したフローは、認可プロセスのメイン・パスのみを表しています。その後に分岐する次の場合については、通常、サーブレットまたはアプリケーション内の追加コード部分によって処理されます。

  • リクエストされたリソースが保護されていない場合。

  • 保護されたリソースに関連付けられている認証チャレンジ・メソッドがアプリケーションでサポートされていない場合。

  • ユーザーが、指定された条件で有効な資格証明を提示できなかった場合。

  • その他のエラー状態が発生した場合。

  • 特殊な状況や機能を処理するために、開発者がアクセス・クライアントに追加のカスタム・コードを組み込んである場合。

カスタム・アクセス・クライアントを記述する場合、ユーザーをバックチャネル経由で認証できます。

2.2 Access SDKのインストール

Java Access SDK Client for Access Manager 11gをインストールするには、次の手順を実行します。

  1. Oracle Technology Networkからoam-java-asdk.zipファイルをダウンロードします。

  2. ファイルoam-java-asdk.zipの中身をローカル・ディレクトリに展開します。

  3. oamasdk-api.jarをCLASSPATHに追加します。

Access SDKのインストール後は、サブディレクトリおよびファイルの相対的な場所を変更しないでください。変更すると、APIが正しくビルドおよび操作できなくなります。

2.3 アクセス・クライアントの開発

この項で説明する項目は、次のとおりです。

2.3.1 アクセス・クライアントの構造

一般的なアクセス・クライアント・アプリケーションの構造は、アクセス・クライアント・セッションの設定に必要な一連のイベントを大まかにミラー化しています。

  1. 必要なライブラリをインクルードまたはインポートします。

  2. リソースを取得します。

  3. 認証スキームを取得します。

  4. 認証スキームに必要となるユーザー資格証明を収集します。

  5. ユーザー・セッションを作成します。

  6. リソースに対するユーザー認可をチェックします。

  7. クリーン・アップします(Javaは自動ガベージ・コレクションを使用)。

  8. 停止します。

2.3.2 アクセス・クライアントの一般的な実行フロー

HTTPフォーム・ベースのアクセス・クライアントのアプリケーションとプラグインは、すべて同じ基本パターンを実行します。図2-3は、フォーム・ベースのアプリケーションのプロセス・フローを示しています。図の下に詳細の説明を示します。

図2-3 フォーム・ベースのアプリケーションのプロセス・フロー

図2-3の説明が続きます
「図2-3 フォーム・ベースのアプリケーションのプロセス・フロー」の説明

  1. ライブラリをインポートします。

  2. SDKを初期化します。

  3. ResourceRequestオブジェクトを作成します。

  4. リクエストされたリソースが保護されているかどうかを判別します。

    リソースが保護されていない場合: リソースが保護されていない場合、アクセス・クライアントはDenyOnNotProtectedフラグの値に基づいて、リソースに対するアクセス権を付与または拒否します。デフォルト値はtrueです。Access Manager 11gエージェントの場合、DenyOnNotProtectedフラグは常にtrueであり、変更できません。

  5. リクエストされたリソースが保護されている場合: AuthenticationSchemeオブジェクトを作成します。

  6. HTTPフォーム・ベースの認証スキームの場合: ユーザーIDとパスワードを含む構造体を作成し、UserSessionオブジェクトを作成して、ユーザーが認証されるかどうかを判定します。

  7. HTTPフォーム・ベースでない認証スキームの場合: アクセスを拒否して理由を報告し、APIを停止し、プログラムを終了します。

  8. ユーザーが認証された場合: ユーザーが認可されるかどうかを判定します(ステップ10)。

  9. ユーザーが認証されていない場合: アクセスを拒否して理由を報告し、APIを停止し、プログラムを終了します。

  10. ユーザーが認可された場合: アクセスを許可し、APIを停止し、プログラムを終了します。

  11. ユーザーが認可されなかった場合: アクセスを拒否して理由を報告し、APIを停止し、プログラムを終了します。


注意:

このテスト・アプリケーション、あるいはその他のいずれかの例を実行する場合、アクセス・システムが正しくインストールおよび設定されていることを確認してください。特に、サンプル・プログラムで必要とされるURLと認証スキームに完全に一致するリソースが保護されるように構成されているかどうかを確認してください。アプリケーション・ドメインの作成およびアプリケーション・ドメインによるリソースの保護の詳細は、『Oracle Fusion Middleware Oracle Access Management管理者ガイド』を参照してください。

2.3.3 サンプル・コード: 簡単なアクセス・クライアント

この例は、簡易アクセス・クライアント・プログラムです。これは、動作中のアクセス・クライアントに必要な最小限のタスクの実装方法を示しています。

  • OAMサーバーに接続します。

  • HTTPフォーム・チャレンジ・メソッドを採用した認証スキームを使用してログインします。

  • HTTP GETリクエストを使用してリソースの認証を確認します。

  • Access SDK APIの例外を捕捉およびレポートします。

通常、このコール順序は、フォーム・チャレンジ・メソッドを使用するアクセス・クライアントに共通です。フォーム・メソッドのアクセス・クライアント間の主な違いは、認証に必要な資格証明と保護するリソース・タイプです。

JAccessClient.javaの完全なリストは例2-1に示しています。このコードをテキスト・ファイルJAccessClient.javaに一字一句すべてコピーし、Access Manager SDKがインストールされているコンピュータ上でこれを実行できます。

この例の注釈付きバージョンは、第2.3.4項「注釈付きサンプル・コード: 簡単なアクセス・クライアント」を参照してください。これにより、11g Java Access Manager APIコールに慣れることができます。

例2-1 JAccessClient.java

import java.util.Hashtable;
import oracle.security.am.asdk.*;

public class JAccessClient {
   public static final String ms_resource = "//Example.com:80/secrets/
         index.html";         
   public static final String ms_protocol = "http";
   public static final String ms_method = "GET";
   public static final String ms_login = "jsmith";
   public static final String ms_passwd = "j5m1th";
   public static final String m_configLocation = "/myfolder";
   public static void main(String argv[]) {
          AccessClient ac = null; 
      try {
          ac = AccessClient.createDefaultInstance(m_configLocation,
 AccessClient.CompatibilityMode.OAM_10G);
          
         ResourceRequest rrq = new ResourceRequest(ms_protocol, ms_resource,
               ms_method);
         if (rrq.isProtected()) {
            System.out.println("Resource is protected.");
            AuthenticationScheme authnScheme = new AuthenticationScheme(rrq);
            if (authnScheme.isForm()) {
               System.out.println("Form Authentication Scheme.");
               Hashtable creds = new Hashtable();
               creds.put("userid", ms_login);
               creds.put("password", ms_passwd);
               UserSession session = new UserSession(rrq, creds);
               if (session.getStatus() == UserSession.LOGGEDIN) {
                  if (session.isAuthorized(rrq)) {
                     System.out.println("User is logged in and authorized for the"
                           +"request at level " + session.getLevel());
                  } else {
                     System.out.println("User is logged in but NOT authorized");
                  }
                        //user can be loggedout by calling logoff method on the session object
               } else {
                  System.out.println("User is NOT logged in");
               }
            } else {
               System.out.println("non-Form Authentication Scheme.");
            }
         } else {
            System.out.println("Resource is NOT protected.");
         }
      }
      catch (AccessException ae) {
         System.out.println("Access Exception: " + ae.getMessage());
      }
      ac.shutdown();
   }
}

2.3.4 注釈付きサンプル・コード: 簡単なアクセス・クライアント

資格証明を保持する標準Javaライブラリ・クラス・ハッシュテーブルをインポートします。

import java.io.Hashtable;

Access SDK APIクラスのJava実装が含まれるライブラリをインポートします。

import oracle.security.am.asdk.*;

このアプリケーションにJAccessClientと命名します。

public class JAccessClient {

このアプリケーションは最も単純な例のため、リソースへのユーザー・アクセス・リクエストに関連したパラメータを表すためにグローバル定数を宣言することとします。

このパラメータ・セットは、実際のアプリケーションでは通常、リクエスト元アプリケーション、HTTPフォーム入力またはコマンド行入力から渡される文字列の配列として受信されます。次に例を示します。

public static final String ms_resource = "//Example.com:80/secrets/index.html";
   public static final String ms_protocol = "http";
   public static final String ms_method = "GET";
   public static final String ms_login = "jsmith";
   public static final String ms_passwd = "j5m1th";

Javaインタプリタ上でメイン・メソッドを起動します。argvという名前の文字列配列がメイン・メソッドに渡されます。この例では、jsmithというユーザーが、j5m1thというパスワードを使用して、HTTPリソースの//Example.com:80/secrets/index.htmlをリクエストします。GETは、リクエスト先リソースに対して実行するHTTP操作です。サポートされているHTTP操作およびアプリケーション・ドメインによるリソースの保護の詳細は、『Oracle Fusion Middleware Oracle Access Management管理者ガイド』を参照してください。

 public static void main(String argv[]) {

メイン・メソッド内のすべての関連するプログラム文をtryという大きなブロック内に配置し、プログラム終了までにすべての例外をこの捕捉用ブロックで捕捉できるようにします。

AccessClient ac = null;

 try {

Access SDKを初期化するために、ObAccessClient.xml構成ファイルのディレクトリの場所を指定して、AccessClientインスタンスを作成します。Access SDKを初期化するための構成場所を指定するには複数の方法があります。詳細は、Oracle Fusion Middleware Oracle Access Management Access Manager Access SDK Java APIリファレンスを参照してください。

AccessClientのインスタンスによってAccess SDK APIが初期化されます。AccessClientインスタンスがOAM_10Gモードで作成される場合は、10gエージェント・プロファイルを使用する必要があります。同様に、AccessClientインスタンスがOAM_11Gモードで作成される場合は、11gエージェント・プロファイルを使用する必要があります。AccessClient.CompatibilityMode.OAM_10Gは、10gと11g両方のサーバーと互換性のある古い10gエージェント・モードで動作するようにAccess SDKを初期化することを示しています。デフォルトでは、この互換性モードを指定しないと、デフォルトのOAM_11Gが使用されます。この場合、エージェントは11gエージェント・モードで動作し、11g OAMサーバーとしか対話できません。

 ac = AccessClient.createDefaultInstance(m_configLocation ,
 AccessClient.CompatibilityMode.OAM_10G); 

ResourceRequestコンストラクタを次の3つのパラメータとともに使用して、rrqという名前の新規のリソース・リクエスト・オブジェクトを作成します。

  • ms_protocol: リクエストするリソースのタイプを示します。未指定の場合、デフォルト値はHTTPです。使用可能な値としてEJBもありますが、ここでの例にはこれは使用しません。カスタム・タイプを作成することもできます。詳細は、『Oracle Fusion Middleware Oracle Access Management管理者ガイド』を参照してください。

  • ms_resource: リソース名です。この特定の例でリクエストされたリソース・タイプはHTTPであるため、次のようにリソース名の先頭にホスト名およびポート番号を追加することは有効です。

    //Example.com:80/secrets/index.html
    
  • ms_method: リソースに対して実行する操作のタイプです。リソース・タイプがHTTPの場合、指定可能な操作はGETとPOSTです。EJBタイプのリソースでは、操作はEXECUTEにかぎります。カスタム・リソース・タイプの場合、リソース・タイプを設定する際に、許可する操作を定義します。リソース・タイプの定義およびアプリケーション・ドメインによるリソースの保護の詳細は、『Oracle Fusion Middleware Oracle Access Management管理者ガイド』を参照してください。

ResourceRequest rrq = new ResourceRequest(ms_protocol,
   ms_resource, ms_method);

リクエスト先リソースrrqが認証スキームによって保護されているかどうかを確認します。

 if (rrq.isProtected()) {

リソースが保護されている場合は、そのことをレポートします。

 System.out.println("Resource is protected.");

AuthenticationSchemeコンストラクタを使用して、authnSchemeという名前の認可スキーム・オブジェクトを作成します。リソース・リクエストrrqを指定し、この特定のリソースに特定の認可スキームが関連付けられているかどうかを、AuthenticationSchemeに確認させます。

 AuthenticationScheme authnScheme =new AuthenticationScheme(rrq);

フォーム・ベースの認可スキームが使用されているかどうかを判別します。

 if (authnScheme.isForm()) {

認可スキームがチャレンジ・メソッドとしてHTTPフォームを使用している場合、そのことを報告してから、ユーザー名(userid)およびユーザー・パスワード(password)を表すname:valueペアを保持するための、credsという名前のハッシュテーブルを作成します。ms_loginおよびms_passwdの値をハッシュテーブルに読み込みます。

System.out.println("Form Authentication Scheme.");
Hashtable creds = new Hashtable();
creds.put("userid", ms_login);
creds.put("password", ms_passwd);

UserSessionコンストラクタを使用して、sessionという名前のユーザー・セッション・オブジェクトを作成します。リソース・リクエストをrrqに、認証スキームをcredsに指定して、認証試行が成功したかどうかを示す状態情報が含まれる新規の構造体をUserSessionが戻すようにします。

UserSession session = new UserSession(rrq, creds);

UserSession状態情報に対してgetStatusメソッドを起動し、ユーザーが正常にログインできたか(認証されたか)どうかを確認します。

if (session.getStatus() == UserSession.LOGGEDIN) {

ユーザーが認証されている場合は、リソース・リクエスト構造体rrqに指定したリソースへのアクセスをユーザーが認可されるかどうかを確認します。

if (session.isAuthorized(rrq)) {
  System.out.println(
    "User is logged in " +
    "and authorized for the request " +

sessionという名前のユーザー・セッションに対してgetLevelメソッドによって戻される認可レベルを確認します。

 "at level " + session.getLevel());

rrqに指定されたリソースに対してユーザーが認可されていない場合は、ユーザーは認証されているが、リクエストしたリソースへのアクセスは認可されていないことを報告します。

} else {
  System.out.println("User is logged in but NOT authorized");

ユーザーが認証されていない場合は、そのことを報告します。(実際のアプリケーションでは、ユーザーに認証のための機会をさらに与える場合があります)。

} else {
  System.out.println("User is NOT logged in");

認証スキームでHTTPフォーム・ベースのチャレンジ・メソッドが使用されていない場合は、そのことを報告します。実際のアプリケーションでは、このようなとき、basic (useridpasswordのみを要求する)、certificate (SSL over HTTPSまたはTLS over HTTPS)、またはsecure(リダイレクトURLによるHTTPS)など、認可スキームに指定されている他のチャレンジ・メソッドを提供するように分岐する場合があります。チャレンジ・メソッドおよびユーザー認証の構成の詳細は、『Oracle Fusion Middleware Oracle Access Management管理者ガイド』を参照してください。

} else {
  System.out.println("non-Form Authentication Scheme.");
}

リソースが保護されていない場合は、そのことを報告します。(アクセス・クライアントはリソースを保護しようとしなくなるので、ユーザーはリクエストしたリソースへのアクセスを自動的に取得します)

} else {
  System.out.println("Resource is NOT protected.");
}
}

前述のtryブロック内でエラーが発生した場合は、オブジェクトaeから関連テキスト・メッセージを取得して、これを報告します。

catch (AccessException ae) {
  System.out.println(
  "Access Exception: " + ae.getMessage());
}

アプリケーションにおいてユーザーのログアウトが必要な場合は、UserSessionクラスのオブジェクト上でログオフ・メソッドを起動できます。

これで、OAMサーバーへのコールが終了になるため、APIを停止して、このコールでAPIが保持してきたメモリーを解放します。

  ac.shutdown();
}
}

プログラムを終了します。このアプリケーションで作成した構造体が使用するメモリーは、不要になった時点でJava Garbage Collectionにより自動的にクリーンアップされるので、割当て解除する必要はありません。

2.3.5 サンプル・コード: Javaログイン・サーブレット

この例では、第2.3.3項「サンプル・コード: 簡単なアクセス・クライアント」で説明した、アクセス・クライアントを定義するAPIコールの基本パターンを実行しています。ただしこの例は、Webサーバーまたはアプリケーション・サーバー内で実行されるJavaサーブレットとして実装されています。アクセス・クライアント・サーブレットは、この環境では、Webアプリケーションのユーザーに対してさらに重要な役割を果すことができます。サーブレットは、セッション・トークンをユーザーのHTTPセッション内に格納することで、ユーザーがシングル・サインオンできるようにします。つまり、最初のリクエストで確立された認証済OAMサーバー・セッション情報は、1回認可確認した後でも破棄されません。格納されたセッション・トークンは、破棄されずに、Beanやその他のサーブレットなどのサーバー側アプリケーション・コンポーネントで利用できるようになり、これらのコンポーネントが同じ資格証明をリクエストするためにユーザーに繰り返し割り込む必要がなくなります。セッション・トークン、ObSSOCookiesおよびシングル・サインオンの構成の詳細は、『Oracle Fusion Middleware Oracle Access Management管理者ガイド』を参照してください。


注意:

このJavaサーブレットの例では、mod_osso、Access Manager WebGateまたはOpenSSO Policy Agentによって保護されたリソースに対してSSOを提供していません。

このサンプル・ログイン・サーブレットは、カスタム・ログイン・ページ上のフォームでuserid/passwordパラメータを受け付け、ユーザーにAccess Managerへのログインの機会を提供します。ログインが成功した場合、サーブレットは、セッション・トークンをUserSessionオブジェクト内に格納します。これにより、同じHTTPセッション内の後続のリクエストは認証ステップをバイパスし(後続のリクエストが最初のリクエストと同じ認証スキームを使用する場合)、シングル・サインオンを実現します。

Javaログイン・サーブレットの完全なリストは、例2-2に示しています。このコードは、Webサーバーまたはアプリケーション・サーバーに組み込むプラグインのベースとして使用できます。第2.3.6項「注釈付きサンプル・コード: Javaログイン・サーブレット」は、このコードの注釈付きバージョンです。

例2-2 Javaログイン・サーブレットの例

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import oracle.security.am.asdk.*;
 
public class LoginServlet extends HttpServlet {
 
   public void init(ServletConfig config) throws ServletException {
      try {
          
           AccessClient ac = AccessClient.createDefaultInstance("/myfolder" ,
 AccessClient.CompatibilityMode.OAM_10G);                  
      } catch (AccessException ae) {
         ae.printStackTrace();
      }
   }
 
   public void service(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {
      AuthenticationScheme authnScheme = null;
      UserSession user = null;
      ResourceRequest resource = null;
       response.setContentType("text/html");
      PrintWriter out = response.getWriter(); 
      out.println("<HTML>");
      out.println("<HEAD><TITLE>LoginServlet: Error Page</TITLE></HEAD>");
      out.println("<BODY>");
      HttpSession session = request.getSession( false);
      String requestedPage = request.getParameter("request");
      String reqMethod = request.getMethod();
      Hashtable cred = new Hashtable();
      try {
         if (requestedPage == null || requestedPage.length()==0) {
            out.println("<p>REQUESTED PAGE NOT SPECIFIED\n");
            out.println("</BODY></HTML>");
            return;
         }
         resource = new ResourceRequest("http", requestedPage, "GET");
         if (resource.isProtected()) {
            authnScheme = new AuthenticationScheme(resource);
            if (authnScheme.isBasic()) {
               if (session == null) {
                  String sUserName = request.getParameter("userid");
                  String sPassword = request.getParameter("password");
                  if (sUserName != null) {
                     cred.put("userid", sUserName);
                     cred.put("password", sPassword);
                     user = new UserSession(resource, cred);
                     if (user.getStatus() == UserSession.LOGGEDIN) {
                        if (user.isAuthorized(resource)) {
                           session = request.getSession( true);
                           session.putValue( "user", user);
                           response.sendRedirect( requestedPage );
                        } else {
                           out.println("<p>User " + sUserName + " not" +
                                " authorized for " + requestedPage + "\n");
                        }
                     } else {
                        out.println("<p>User" + sUserName + "NOT LOGGED IN\n");
                     }
                  } else {
                     out.println("<p>USERNAME PARAM REQUIRED\n");
                  }
               } else {
                  user = (UserSession)session.getValue("user");
                  if (user.getStatus() == UserSession.LOGGEDIN) {
                     out.println("<p>User " + user.getUserIdentity() + " already"+
                           "LOGGEDIN\n");
                  }
               }
            } else {
               out.println("<p>Resource Page" + requestedPage + " is not"+
                    " protected with BASIC\n");
            }
         } else {
            out.println("<p>Page " + requestedPage + " is not protected\n");
         } 
      } catch (AccessException ex) {
          out.println(ex);
      }
   out.println("</BODY></HTML>");
   }
} 

2.3.6 注釈付きサンプル・コード: Javaログイン・サーブレット

システム入出力および基本機能を実装する標準Javaパッケージをインポートします。

import java.io.*;
import java.util.*;

サーブレット関連機能を実装する2つのJava拡張機能パッケージをインポートします。

import javax.servlet.*;
import javax.servlet.http.*;

Access SDK APIのJava実装であるoracle.security.am.asdk.jarパッケージをインポートします。

import oracle.security.am.asdk.*;

このサーブレットは、Java Enterprise Editionでサポートされている汎用HttpServletの機能をベースにビルドされており、LoginServletという名前です。

public class LoginServlet extends HttpServlet {

サーブレット・エンジンはinitメソッドを1回コールして、アクセス・クライアントを初期化します。initメソッドでは、構成ファイルObAccessClient.xmlの場所を渡し、AccessClientをインスタンス化してAccess SDKを初期化できます。アクセス・クライアントの作成の詳細は、Oracle Fusion Middleware Oracle Access Management Access Manager Access SDK Java APIリファレンスを参照してください。OAM_10G互換性フラグを指定すると、Access SDKは10gおよび11gの両方のサーバーと互換性のあるモードで初期化されます。OAM_10G互換性フラグを指定すると、Access SDKは古い10gエージェント・モードで初期化されます。このモードは、10gおよび11gの両方のサーバーと互換性があります。デフォルトでは、この互換性モードを指定しないと、デフォルトのOAM_11Gが使用されます。この場合、エージェントは11gエージェント・モードで動作し、11g OAMサーバーとしか対話できません。


注意:

AccessClientインスタンスがOAM_10Gモードで作成される場合は、10gエージェント・プロファイルを使用する必要があります。同様に、AccessClientインスタンスがOAM_11Gモードで作成される場合は、11gエージェント・プロファイルを使用する必要があります。

初期化に失敗した場合は、そのことを該当のエラー・メッセージとともに報告します。

public void init() { 
      AccessClient ac =
 AccessClient.createDefaultInstance("/myfolder" ,
 AccessClient.CompatibilityMode.OAM_10G);
   } catch (AccessException ae) { 
         ae.printStackTrace(); 
   } 
} 

javax.servlet.serviceメソッドを起動し、ユーザーのリソース・リクエストを処理します。

public void service(HttpServletRequest request, HttpServletResponse response)
  throws IOException, ServletException {

メンバーをnullとして初期化します。これらはリソース・リクエストの処理に使用するアクセス構造を格納し、このアプリケーションが使用するレスポンス・タイプをtext/htmlに設定します。

AuthenticationScheme authnScheme = null;
UserSession user = null;
ResourceRequest resource = null;
response.setContentType("text/html");

LoginServlet: Error Pageという名前の出力ストリームを開き、ユーザーのブラウザにリダイレクトします。

PrintWriter out = response.getWriter();
out.println("<HTML>");
out.println("<HEAD><TITLE>LoginServlet: Error Page</TITLE></HEAD>");
out.println("<BODY>");

このユーザーのセッションがすでに存在するかどうかを確認します。パラメータとしてfalseを指定してgetSessionメソッドを起動すると、既存のサーブレット・セッション(UserSessionではない)の値が戻され(セッションが存在する場合)、存在しない場合はNULLが戻されます。

 HttpSession session = request.getSession(false);

ターゲット・リソースの名前を取得して、これをrequestedPage変数に代入し、リクエストに使用されたHTTPメソッド(GET、POST、PUTなど)の名前を取得して、これをreqMethod変数に代入します。

String requestedPage = request.getParameter(Constants.REQUEST);
String reqMethod = request.getMethod();

credという名前のハッシュテーブルを作成し、ユーザーの資格証明を格納します。

 Hashtable cred = new Hashtable();

requestedPage変数が空のまま戻された場合は、ターゲット・リソースの名前が正しく指定されていないことを報告し、サーブレットを終了します。

try { 
   if (requestedPage == null) { 
out.println("<p>REQUESTED PAGE NOT SPECIFIED\n"); 
out.println("</BODY></HTML>"); 
return; 
   } 

リクエストしたページの名前が戻された場合は、ResourceRequest構造体を作成して、次を設定します。

  • リソース・タイプ: HTTP

  • HTTPメソッド: GET

  • resource: requestedPage変数に設定されている値

 resource = new ResourceRequest("http", requestedPage, "GET");

ターゲット・リソースが保護されている場合は、リソース・リクエスト用にAuthenticationScheme構造体を作成し、名前をauthnSchemeとします。

if (resource.isProtected()) {
   authnScheme = new AuthenticationScheme(resource);

ターゲット・リソースに関連付けられている認証スキームがHTTP basicで、現在ユーザー・セッションが存在しない場合は、javax.servlet.servletrequest.getParameterを起動してユーザーの資格証明であるユーザー名とパスワードを戻し、それぞれsUserNamesPasswordの変数に代入します。

次の文でauthnScheme.isBasicコールを正しく動作させるには、次のように、ユーザー名とパスワードをユーザーのHTTPリクエストの問合せ文字列内に含める必要があります。

http://host.example.com/resource?username=bob&userpassword=bobspassword

ここで、resourceは、リクエスト先のリソース、bobはリクエスト元のユーザー、bobspasswordはユーザーのパスワードです。

if (authnScheme.isBasic()) { 
   if (session == null) { 
      String sUserName = request.getParameter(Constants.USERNAME); 
      String sPassword = request.getParameter(Constants.PASSWORD); 

ユーザー名が存在する場合は、credという名前のハッシュテーブルに、関連パスワードとあわせて読み取ります。

if (sUserName != null) {
   cred.put("userid", sUserName);
   cred.put("password", sPassword);

注意:

authnScheme.isBasicのかわりにauthnScheme.isFormを使用する場合は、追加コードを記述して、次のステップを実装する必要があります。
  1. 元のリクエストを処理して、フォーム・ベースのログインが必要なことを判断します。

  2. ログイン・フォームに関する302リダイレクト・レスポンスを送信し、HTTPセッションに元のリソース情報を保存します。

  3. ユーザー名とパスワードとともにポストされたフォーム・データを処理して、ユーザーを認証します。

  4. HTTPリソースから元のリソースを取得し、そのリソースに関する302リダイレクト・レスポンスを送信します。

  5. 元のリクエストをもう1回処理しますが、今回はHTTPセッション内に格納されているUserSessionを使用して処理します。


resourceという名前のResourceRequest構造体とcredハッシュテーブルの情報に基づいて、ユーザー・セッションを作成します。

 user = new UserSession(resource, cred);

戻されたユーザーのステータス・コードがLOGGEDINの場合、そのユーザーの認証は成功しています。

 if (user.getStatus() == UserSession.LOGGEDIN) {

ターゲット・リソースへのアクセスをユーザーが認可されるかどうかを確認します。

 if (user.isAuthorized(resource)) {

サーブレット・ユーザー・セッション(UserSessionと混同しないでください)を作成し、そこにユーザーの名前を追加します。

 session = request.getSession( true);
session.putValue( "user", user);

ユーザーのブラウザをターゲット・ページにリダイレクトします。

 response.sendRedirect(requestedPage);

ターゲット・リソースへのアクセスをユーザーが認可されなかった場合は、そのことを報告します。

 } else {
    out.println("<p>User " + sUserName + " not authorized
      for " + requestedPage + "\n");
 }

ユーザーが正しく認可されていない場合は、そのことを報告します。

} else {
    out.println("<p>User" + sUserName + "NOT LOGGED IN\n");
}

ユーザー名が入力されていない場合は、そのことを報告します。

 } else {
out.println("<p>USERNAME PARAM REQUIRED\n");
}

セッションがすでに存在する場合は、USERを取得し、これをuserセッション変数に代入します。

 } else {
    user = (UserSession)session.getValue("user");

ユーザーがログインできた場合、つまりユーザーの認証が成功した場合は、そのことをユーザー名とともに報告します。

 if (user.getStatus() == UserSession.LOGGEDIN) { 
      out.println("<p>User " + user.getUserIdentity() + " already 
      LOGGEDIN\n"); 
 }
}

ターゲット・リソースがbasic認証スキームで保護されていない場合は、そのことを報告します。

} else {
   out.println("<p>Resource Page" + requestedPage + " is not protected
         with BASIC\n");
}

ターゲット・リソースがどの認証スキームによっても保護されていない場合は、そのことを報告します。

} else {
   out.println("<p>Page " + requestedPage + " is not protected\n");
} 

エラーが発生した場合は、トレースバックを報告します。

 } catch (AccessException ex) {
   oe.println(ex);
}

出力をユーザーのブラウザにストリームとして送信します。

    out.println("</BODY></HTML>");
  }
}

2.3.7 サンプル・コード: その他のメソッド

次のサンプルは、第2.3.3項「サンプル・コード: 簡単なアクセス・クライアント」で説明した、サンプル・アプリケーションJAccessClient.javaで確立されている基本パターンをベースとして構築されており、追加でいくつかのOAMサーバー・メソッドを呼び出しています。たとえば、セッション・オブジェクトを点検して、現在の認証スキームに関連付けられているポリシー・ルール内にどのアクションおよび名前付きレスポンスが現在構成されているかを確認します。

このデモを実行するには、アプリケーションを実行する前にOAMサーバーによりいくつかのアクションを構成する必要があります。認証アクションおよびユーザー認証の構成の詳細は、『Oracle Fusion Middleware Oracle Access Management管理者ガイド』を参照してください。

例2-3には、このサンプル・アプリケーションの完全なリストが記載されています。このコードの注釈付きバージョンは、第2.3.8項「注釈付きサンプル・コード: その他のメソッド」を参照してください。

例2-3 access_test_java.java

import java.util.*;
import oracle.security.am.asdk.*;
 
public class access_test_java {
 
  public static void main(String[] arg) {
    String userid, password, method, url, configDir, type,
 location;
    ResourceRequest res;
    Hashtable parameters = null;
    Hashtable cred = new Hashtable();
    AccessClient ac = null; 
    if (arg.length < 5) {
      System.out.println("Usage: EXPECTED: userid password Type
 HTTP-method"
          +" URL [Installdir [authz-parameters] [location]]]");
      return;
    } else {
      userid    = arg[0];
      password  = arg[1];
      type      = arg[2];
      method    = arg[3];
      url      = arg[4];
    }
    if (arg.length >= 6) {
      configDir = arg[5];
    } else {
      configDir = null;
    }
    if (arg.length >= 7 && arg[6] != null) {
      parameters = new Hashtable();
      StringTokenizer tok1 = new StringTokenizer(arg[6], "&");
      while (tok1.hasMoreTokens()) {
        String nameValue = tok1.nextToken();
        StringTokenizer tok2 = new StringTokenizer(nameValue,
 "=");
        String name = tok2.nextToken();
        String value = tok2.hasMoreTokens() ? tok2.nextToken() :
 "";
        parameters.put(name, value);
      }
    }
    location = arg.length >= 8 ? arg[7] : null;
    try {
      ac = AccessClient.createDefaultInstance(configDir ,
 AccessClient.CompatibilityMode.OAM_10G);
          
    } catch (AccessException ae) {
      System.out.println("OAM Server SDK Initialization
 failed");
      ae.printStackTrace();
      return;
    }
    cred.put("userid", userid);
    cred.put("password", password);
    try {
      res = new ResourceRequest(type, url, method);
      if (res.isProtected()) {
        System.out.println("Resource " + type + ":" + url + "
 protected"); 
      } else {
        System.out.println("Resource " + type + ":" + url + "
 unprotected");
      }
    } catch (Throwable t) {
      t.printStackTrace();
      System.out.println("Failed to created new resource
 request");
      return;
    }
    UserSession user = null;
    try {
      user = new UserSession(res, cred);
    } catch (Throwable t) {
      t.printStackTrace();
      System.out.println("Failed to create new user session");
      return;
    }
    try {
    if (user.getStatus() == UserSession.LOGGEDIN) {
      if (location != null) user.setLocation(location);
      System.out.println("user status is " + user.getStatus());
      
        if (parameters != null ? user.isAuthorized(res,
 parameters) :
              user.isAuthorized(res)) {
          System.out.println("Permission GRANTED");
          System.out.println("User Session Token =" +
              user.getSessionToken());
          if (location != null) {
            System.out.println("Location = " +
 user.getLocation());
          } 
        } else {
          System.out.println("Permission DENIED");
          if (user.getError() == UserSession.ERR_NEED_MORE_DATA)
 {
            int nParams =
 res.getNumberOfAuthorizationParameters();
            System.out.print("Required Authorization Parameters
 (" + 
                nParams + ") :");
            Enumeration e =
 res.getAuthorizationParameters().keys();
            while (e.hasMoreElements()) {
              String name = (String) e.nextElement();
              System.out.print(" " + name);
            }
            System.out.println();
          }
        }      
   } 
   else 
   {      
           System.out.println("user status is " + user.getStatus());  
   } 
    } catch (AccessException ae)
    {    
          System.out.println("Failed to get user authorization");      
    }
   String[] actionTypes = user.getActionTypes();   
   for(int i =0; i < actionTypes.length; i++) 
   {      
           Hashtable actions = user.getActions(actionTypes[i]);
           Enumeration e = actions.keys();
           int item = 0; 
           System.out.println("Printing Actions for type " +
 actionTypes[i]);
           while(e.hasMoreElements())
           {
                   String name = (String)e.nextElement();
                   System.out.println("Actions[" + item +"]: Name " + name + "
 value " +  actions.get(name));
                   item++;   
           }
        }
   AuthenticationScheme auths;
   try 
   {
           auths = new AuthenticationScheme(res);
       if (auths.isBasic())
       {
             System.out.println("Auth scheme is Basic");
       }
       else 
       {
             System.out.println("Auth scheme is NOT Basic");
       }
   }
   catch (AccessException ase)
   {   
           ase.printStackTrace();
           return;
   }
   try 
   {      
           ResourceRequest resNew = (ResourceRequest) res.clone();   
           System.out.println("Clone resource Name: " +
 resNew.getResource());
   } 
   catch (Exception e) 
   {    
           e.printStackTrace(); 
   }  
   res = null;  
   auths = null; 
   ac.shutdown();
   }
  }

2.3.8 注釈付きサンプル・コード: その他のメソッド

基本ユーティリティ、列挙およびトークン処理機能を実装する標準のJavaライブラリをインポートします。

import java.util.*;

Access SDK APIライブラリをインポートします。

import oracle.security.am.asdk.*;

このクラスにaccess_test_javaという名前を付けます。

public class access_test_java {

argという名前の配列で渡される値を格納する、7つの変数文字列を宣言します。

public static void main(String[] arg) {
   String userid, password, method, url, configDir, type, location;

現在のResourceRequestをresに設定します。

ResourceRequest res;

まだ空になっていない可能性を考慮して、ハッシュテーブル・パラメータをnullに初期化します。

Hashtable parameters = null;

credという名前の新規のハッシュテーブルを作成します。

Hashtable cred = new Hashtable();

AccessClient参照をnullに初期化します。

AccessClient ac = null;

argという名前の配列に含まれている文字列が5個未満の場合、コマンド行入力で予期している構文と内容を報告します。これは順序が指定された5個の必須引数、およびオプションの変数であるconfigDirauthz-parametersおよびlocationです。

if (arg.length < 5) {
  System.out.println("Usage: EXPECTED: userid password type
    HTTP-method URL [configDir [authz-parameters] [location]]]");

最初に指定された引数が5個未満の場合、メイン・メソッドを終了することで事実上プログラムの実行を終了します。

 return;
} else {

argという名前の配列に5個以上の文字列がある場合は、最初の5個の引数(arg[0]からarg[4])をuseridpasswordtypemethodurlの変数に代入します。

  userid = arg[0];
  password = arg[1];
  type = arg[2];
  method = arg[3];
  url = arg[4];
}

argに6個以上の引数がある場合は、配列内の6番目の文字列をconfigDir変数に代入します。

if (arg.length >= 6)
  configDir = arg[5];

argに6個以上の引数がない場合、つまり、5個未満ではないことをすでに確認し、ちょうど5個の引数があることがわかっている場合は、configDirをNULLに設定します。

else
  configDir = null;

argに7個以上の文字列があり、arg[6] (authz-parameters変数に暗黙のうちに割り当てられる)が空ではない場合、parametersという名前の新規のハッシュテーブルを作成します。authz-parameters文字列の構文の形式: p1=v1&p2=v2&...

if (arg.length >= 7 && arg[6] != null) {
  parameters = new Hashtable();

デリミタとしてアンパサンド記号(&)を使用して、tok1という名前の文字列トークン関数を作成し、arg[6]を解析します。これにより、arg[6]がpn=vnの形式でトークンの配列に分解されます(nはトークンの連番)。

 StringTokenizer tok1 = new StringTokenizer(arg[6], "&");

tok1のすべてのアイテムについて、直後のトークンをnameValue変数として戻します。このようにして、nameValueに文字列pn=vnが代入されます(nはトークンの連番)。

while (tok1.hasMoreTokens()) {
  String nameValue = tok1.nextToken();

デリミタとして等記号(=)を使用して、tok2という名前の文字列トークン関数を作成し、nameValueを解析します。このようにして、pn=vnをpnとvnのトークンに分解します。

 StringTokenizer tok2 = new StringTokenizer(nameValue, "=");

最初のトークンをname変数に代入します。

 String name = tok2.nextToken();

2番目のトークンをvalueに代入します。tok2に他のトークンが残っている場合は、直後のトークンを戻し、これをvalueに代入します。残っていない場合は、空文字列をvalueに代入します。

 String value = tok2.hasMoreTokens() ? tok2.nextToken() : "";

parametersハッシュテーブルにnamevalueを挿入します。

    parameters.put(name, value);
  }
}

arg内に8個以上の引数がある場合は、arg[7]をlocation変数に代入します。ない場合は、locationを空にします。

location = arg.length >= 8 ? arg[7] : null;

他のオプションを使用して提供する構成ファイルの場所がnullである場合、configDirを使用してAccessClientインスタンスを作成します。アクセス・クライアントの作成の詳細は、Oracle Fusion Middleware Oracle Access Management Access Manager Access SDK Java APIリファレンスを参照してください。

try {
 ac = AccessClient.createDefaultInstance(configDir , 
   AccessClient.CompatibilityMode.OAM_10G); 
}

初期化の試行によりエラーが発生した場合は、トレースバックとともに標準エラー・ストリームに当該のエラー・メッセージ(ae)を報告します。

catch (AccessException ae) {
  System.out.println("
OAM Server SDK Initialize failed");
  ae.printStackTrace();

メイン・メソッドを終了することで、事実上プログラムを終了します。

 return;
}

各変数、ユーザーIDおよびパスワードをcredという名前のハッシュテーブルに読み取ります。

 cred.put("userid", userid);
cred.put("password", password);

resという名前のResourceRequestオブジェクトを作成すると、変数タイプ、URLおよびメソッドの値がOAMサーバーから戻されます。

try {
res = new ResourceRequest(type, url, method);

リクエストしたリソースresが保護されているかどうかを確認して、該当するメッセージを表示します。

if (res.isProtected())
  System.out.println("Resource " + type ":" + url + " protected");
else
  System.out.println("Resource " + type + ":" + url + " unprotected");
}

ResourceRequest構造体を作成できなかった場合は、エラー・メッセージtとともに障害を報告します。

catch (Throwable t) {
  t.printStackTrace();
  System.out.println("Failed to create new resource request");

メイン・メソッドを終了することで、事実上プログラムを終了します。

  return;
}

UserSessionパラメータのuserを空に設定します。

UserSession user = null;

ResourceRequest構造体のresAuthenticationScheme構造体のcredの値を戻す、userという名前のUserSession構造体を作成します。

try
  user = new UserSession(res, cred);

UserSession構造体を作成できなかった場合は、エラー・メッセージtとともに障害を報告します。

catch (Throwable t) {
  t.printStackTrace();
  System.out.println("Failed to create new user session");

メイン・メソッドを終了することで、事実上プログラムを終了します。

 return;
}

ユーザーが現在ログインしているかどうか、つまりこのユーザーの認証が成功しているかどうかを確認します。

try
{
if (user.getStatus() == UserSession.LOGGEDIN) {

ユーザーがログインしている場合は、location変数が空でないかどうかを確認します。locationが空でない場合は、AccessClientlocationパラメータにこのlocation変数の値を設定し、OAMサーバーが戻すステータス・コードとともに、ユーザーがログインしていることを報告します。

if (location != null) user.setLocation(location);
System.out.println("user status is " + user.getStatus());

認可をチェックします。これを行うには、parametersが存在するかどうかを確認します。存在する場合は、parametersに格納されているパラメータをアタッチしたときにターゲット・リソースへのアクセスがユーザーに認可されるかどうかを確認します。parametersが存在しない場合は、ターゲット・リソースへのアクセスがユーザーに認可されているかどうかを確認します。

try {
  if (parameters != null ? user.isAuthorized(res, parameters) :
    user.isAuthorized(res)) {

存在するすべてのパラメータを指定したときにユーザーがリソースへのアクセスを認可される場合は、権限が付与されたことを報告します。

System.out.println("Permission GRANTED");

さらに、ユーザー・セッション・トークンをシリアル番号付きで表示します。

System.out.println("User Session Token =" + user.getSessionToken());

location変数が空でない場合は、その値を報告します。

if (location != null) {
  System.out.println("Location = " + user.getLocation());
}

リソースへのアクセスをユーザーが認可されなかった場合は、権限が拒否されたことを報告します。

} else {
System.out.println("Permission DENIED");

UserSessionがERR_NEED_MORE_DATAを戻す場合は、nParams変数を認可に必要なパラメータの数に設定し、その数値をユーザーに報告します。

if (user.getError() == UserSession.ERR_NEED_MORE_DATA) {
  int nParams = res.getNumberOfAuthorizationParameters();
  System.out.print("Required Authorization Parameters (" +
    nParams + ") :");

resという名前のResourceRequestオブジェクトのgetAuthorizationParametersメソッドによって戻されるハッシュテーブルのkeysパラメータの値として、eを設定します。

 Enumeration e = res.getAuthorizationParameters().keys();

eに含まれているすべての要素の名前を報告します。

while (e.hasMoreElements()) {
  String name = (String) e.nextElement();
  System.out.print(" " + name);
}
System.out.println();
}

そうでない場合は、次の文に進みます。

    else
  }
}

ユーザーがログインできなかった場合は、現在のユーザー・ステータスを報告します。

else
  System.out.println("user status is " + user.getStatus());

エラーが発生した場合は、認可の試行が失敗したことを報告します。

  catch (AccessException ae)
  System.out.println("Failed to get user authorization");
}

ここで、現行のユーザー・セッションに現在設定されているすべてのアクションを報告します。これを行うには、getActionTypesメソッドによって戻される文字列からactionTypesという名前の配列を作成します。次に、actionTypes内の各文字列をactionsという名前のハッシュテーブルに読み取ります。actionsに含まれている各キーの名前および値を報告します。

String[] actionTypes = user.getActionTypes();
for(int i =0; actionTypes[i] != null; i++){
  Hashtable actions = user.getActions(actionTypes[i]);
  Enumeration e = actions.keys();
  int item = 0;
  System.out.println("Printing Actions for type " + actionTypes[i]);
  while(e.hasMoreElements()) {
String name = (String)e.nextElement();
System.out.println("Actions[" + item +"]: Name " + name + " value " +
  actions.get(name));
item++;
  }
}

ResourceRequestオブジェクトのresに対するauthsという名前のAuthenticationSchemeオブジェクトの作成を試みます。

AuthenticationScheme auths;
try
  auths = new AuthenticationScheme(res);

AuthenticationSchemeを作成できなかった場合は、エラー・メッセージaseとともに障害を報告します。

catch (AccessException ase) {
  ase.printStackTrace();

メイン・メソッドを終了することで、事実上プログラムを終了します。

  return;
}

認可スキームがBasicかどうかを確認します。

try
{
if (auths.isBasic())

そうである場合は、その事実を報告します。

System.out.println("Auth scheme is Basic");

Basicでない場合は、その事実を報告します。

else
  System.out.println("Auth scheme is NOT Basic");

コピー・コンストラクタを使用して、元オブジェクトresからresNEWという名前の新規のResourceRequestオブジェクトを作成します。

  ResourceRequest resNew = (ResourceRequest) res.clone();

新しくクローニングしたオブジェクトの名前を報告します。

 System.out.println("Clone resource Name: " + resNew.getResource());

なんらかの理由によりResourceRequestオブジェクトがクローニングできなかった場合は、対応するトレースバックによって障害を報告します。

}
catch (Exception e) {
  e.printStackTrace();
}

ResourceRequestオブジェクトresAuthenticationSchemeオブジェクトauthsをNULLに設定し、Access SDK APIを切断します。

    res = null;
    auths = null;
    ac.shutdown();
  }
}

2.3.9 サンプル・コード: Javaでの証明書ベース認証

次のコードの抜粋では、X.509証明書を処理するアクセス・クライアントのJavaでの実装例を示しています。この抜粋は、管理者がアクセス・システムに証明書ベースの認証を構成する場合に適しています。

証明書はBase64でエンコードされている必要があります。OAMサーバーでは、ユーザーの識別にのみこの証明書を使用します。有効期間、ルート認証が信頼されているかどうかなどの検証は実行されません。

File oCertFile = new File("sample_cert.pem");
FileInputStream inStream = new FileInputStream(oCertFile);
CertificateFactory cf =
CertificateFactory.getInstance("X.509");

// cert must point to a valid java.security.cert.X509Certificate instance.
X509Certificate cert = (X509Certificate)
cf.generateCertificate(inStream);
 
// Convert the certificate into a byte array
byte[] encodedCert = cert.getEncoded();
 
// Encode the byte array using Base 64-encoding and convert it into a string
String base64EncodedCert = new String(Base64.encodeBase64 (encodedCert));
 
// Create hashtable to hold credentials
Hashtable<String, String> creds = new Hashtable<String, String>();
 
// Store the Base 64-encoded under the key "certificate"
creds.put("certificate", base64EncodedCert);
 
// Create ResourceResource request object including all information about the //
// resource being accessed including Resource type (for example http, ejb etc. 
// If null, defaults to http), and operation for the resource object
// (for example GET, POST, PUT, HEAD, DELETE, TRACE, OPTIONS, CONNECT, OTHER)
ResourceRequest resourceRequest = new ResourceRequest(resourceType, resourceUrl, operation);
 
// Create a UserSession with the requestRequest and the cred hashtable
UserSession userSession = new UserSession(resourceRequest, creds);
 
// The above statement will throw an exception if the certificate cannot be mapped // to a valid user by the OAM Server.

この抜粋に関連するインポート文を次に示します。

import java.security.cert.CertificateFactory;
     import java.security.cert.X509Certificate;
     import java.io.FileInputStream;
     import oracle.security.am.common.nap.util.Base64;

2.3.10 サンプル・コード: ASDKを使用したOAM_ID Cookieの作成

OAM_ID Cookieは、ASDKを使用した完全なSSOを実装するためにユーザー・セッションで使用します。このCookieは、Oracle Access Management Consoleを使用するか、oam-config.xmlファイルを編集して作成できます。

Oracle Access Management Consoleを使用してOAM_ID Cookieを作成するには、SDKアプリケーションをデプロイしたWebGateエージェントに必須パラメータAllowTokenScopeOperationsおよびAllowMasterTokenRetrievalを設定します。サンプル・コードを使用して、JavaベースのコードであるASDKのマスター・トークンを取得します。このマスター・トークンを取得すると、エージェント間のSSOに使用されるOAM_ID Cookieが設定されます。

必須パラメータがOracle Access Management Consoleに表示されない場合は、oam-config.xmlファイルを編集してOAM_ID Cookieを作成できます。WebGate 11gエージェントの構成に次の設定を追加します。

<Setting Name="AllowTokenScopeOperations" Type="xsd:boolean">true</Setting>
<Setting Name="AllowMasterTokenRetrieval" Type="xsd:boolean">true</Setting>

例2-4 OAM_ID Cookie作成のサンプルASDKコード

//TODO: Use Set-Cookie header for httpOnly=true
//TODO: Typically this cookie's host is OAM host, set it as domain level cookie retrieving the domain since we are setting this manually.
Cookie oamCookie2 = new Cookie("OAM_ID", user.getScopedSessionToken(null));
oamCookie2.setPath("/");
oamCookie2.setDomain("oracle.com");
response.addCookie(oamCookie2);
System.out.println("Cookie2: " + oamCookie2.getValue());

2.4 Access SDKログの生成

Access SDKでは、ログの生成にJavaロギングAPIが使用されます。具体的には、oracle.security.am.asdkパッケージにAccessLoggerクラスが含まれ、このクラスはAccess SDKログを生成します。Access SDKによって生成されるログには、実行された操作に関する情報が含まれます。たとえば、操作ステータス、発生したエラーまたは例外、およびトラブルシューティングに役立つ一般情報を記録できます。この項では、実行ログ中で、ステータスまたはエラーを示すためにAccess SDKが使用するメッセージおよび例外について説明します。


注意:

Access SDKは、ステータスまたはエラーの状態を示すローカライズ済メッセージをサポートします。例外としてアプリケーションに提供されるエラー・メッセージもローカライズされます。これらのローカライズ済エラー・メッセージは、Access SDKログ・ファイルに記録されます。

次のタイプの例外が、Access SDKログにおけるエラー条件を示すために使用されます。

  • OperationNotPermittedException

    Access SDKには、一連のセッション管理APIが用意されています。権限を持つアクセス・クライアントのみが、これらのセッション管理操作を実行できます。Access SDKを初期化するには、指定のエージェント・プロファイルにAllowManagementOperationsフラグが設定されている必要があります。

    アクセス・クライアントがこれらの操作の実行を許可されていない場合、11g OAMサーバーがエラーを返します。サーバーがエラーを返すと、Access SDKがこの例外をスローします。

  • AccessException

    操作の実行中に予期しないリカバリ不能なエラーが発生すると、Access SDK APIはAccessExceptionをスローします。

Access SDKログを生成するには、アプリケーションの起動時にログ構成ファイルを指定する必要があります。このログ構成ファイルはアプリケーション実行中のJavaプロパティとして指定しますが、この場合、Javaプロパティ-Djava.util.logging.config.filelogging.propertiesへのパスです。次に例を示します。

java -Djava.util.logging.config.file=JRE_DIRECTORY/lib/logging.properties

logging.propertiesファイルは、VMがロードされた直後に構成され準備が整うロガー、ハンドラ、フォーマッタおよびフィルタの数を定義します。状況に応じて、必要なロギング・レベルを構成することもできます。

logging.propertiesファイルのjava.util.logging.FileHandler.patternプロパティに対して、ログ・ファイル・パスを指定する必要があります。ファイル名のみを指定した場合、ファイルはカレント・ディレクトリの下に作成されます。logging.propertiesファイルの例は次のとおりです。

# "handlers" specifies a comma separated list of log Handler 
# classes.  These handlers will be installed during VM startup.
# Note that these classes must be on the system classpath.
# By default we only configure a ConsoleHandler, which will only
# show messages at the INFO and above levels.
# Add handlers to the root logger.
# These are inherited by all other loggers.
handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler
 
# Set the logging level of the root logger.
# Levels from lowest to highest are
# FINEST, FINER, FINE, CONFIG, INFO, WARNING and SEVERE.
# The default level for all loggers and handlers is INFO.
.level= ALL
 
# Configure the ConsoleHandler.
# ConsoleHandler uses java.util.logging.SimpleFormatter by default. 
# Even though the root logger has the same level as this,
# the next line is still needed because we're configuring a handler,
# not a logger, and handlers don't inherit properties from the root logger.
java.util.logging.ConsoleHandler.level =INFO
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
 
# The following special tokens can be used in the pattern property
# which specifies the location and name of the log file.
#   / - standard path separator
#   %t - system temporary directory
#   %h - value of the user.home system property
#   %g - generation number for rotating logs
#   %u - unique number to avoid conflicts
# FileHandler writes to %h/demo0.log by default.
java.util.logging.FileHandler.pattern=%h/asdk%u.log
 
 
# Configure the FileHandler.
# FileHandler uses java.util.logging.XMLFormatter by default. 
#java.util.logging.FileHandler.limit = 50000
#java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
java.util.logging.FileHandler.level=ALL

ログ出力のサンプルを次に示します。

Apr 19, 2011 5:20:39 AM AccessClient createClient
FINER: ENTRY
Apr 19, 2011 5:20:39 AM ObAAAServiceClient setHostPort
FINER: ENTRY
Apr 19, 2011 5:20:39 AM ObAAAServiceClient setHostPort
FINER: RETURN
Apr 19, 2011 5:20:39 AM ObAAAServiceClient setHostPort
FINER: ENTRY
Apr 19, 2011 5:20:39 AM ObAAAServiceClient setHostPort
FINER: RETURN
Apr 19, 2011 5:20:39 AM AccessClient createClient
FINER: RETURN
Apr 19, 2011 5:20:39 AM AccessClient initialize
FINER: read config from server, re-init if needed
Apr 19, 2011 5:20:39 AM AccessClient updateConfig
FINER: ENTRY
Apr 19, 2011 5:20:39 AM AccessClient readConfigFromServer
FINER: ENTRY
Apr 19, 2011 5:20:39 AM ObAAAServiceClient getClientConfigInfo
FINER: ENTRY
Apr 19, 2011 5:20:39 AM ObAAAServiceClient sendMessage
FINER: ENTRY
Apr 19, 2011 5:20:39 AM oracle.security.am.common.nap.util.NAPLogger log
FINER: Getting object using poolid primary_object_pool_factory
Apr 19, 2011 5:20:39 AM oracle.security.am.common.nap.util.pool.PoolLogger logEntry
FINER: PoolLogger : main entered: KeyBasedObjectPool.acquireObject
Apr 19, 2011 5:20:39 AM oracle.security.am.common.nap.util.NAPLogger log
FINEST: Creating pool with id = primary_object_pool_factory
Apr 19, 2011 5:20:39 AM oracle.security.am.common.nap.util.pool.PoolLogger log
FINER: PoolLogger:main : Maximum Objects = 1Minimum Objects1
Apr 19, 2011 5:20:39 AM oracle.security.am.common.nap.util.pool.PoolLogger logEntry
FINER: PoolLogger : main entered: constructObject
Apr 19, 2011 5:20:39 AM oracle.security.am.common.nap.ObMessageChannelImpl <init>

2.5 アクセス・クライアント・プログラムの構築

この項で説明する項目は、次のとおりです。

2.5.1 開発環境の設定

開発環境には、次の要件があります。

  • JDK 1.6.0以上をインストールします。

  • 11g Access SDKをインストールします。

  • JAVA_HOME環境変数がJDKインストール・ディレクトリを指すように定義します。たとえば、UNIX型オペレーティング・システムでは、次のコマンドを実行します。

    setenv JAVA_HOME <JDK install dir>/bin
    
  • PATH環境変数を、JAVA_HOME/binが指す場所に変更します。たとえば、UNIX型オペレーティング・システムでは、次のコマンドを実行します。

    setenv PATH $JAVA_HOME/bin:$PATH
    
  • CLASSPATH環境変数を、JDKおよびAccess SDK jarファイルを指すように変更します。たとえば、UNIX型オペレーティング・システムでは、次のコマンドを実行します。

    setenv CLASSPATH $JAVA_HOME/lib/tools.jar:$ACCESSSDK_INSTALL_DIR/oamasdk-api.jar:$CLASSPATH
    

    CLASSPATH変数に必要なすべてのjarファイルのリストは、第2.2項「Access SDKのインストール」を参照してください。

2.5.2 新規アクセス・クライアント・プログラムのコンパイル

2.5.1項「開発環境の設定」に示された開発環境を構成した後で、次のようなコマンドを使用して、Access Clientプログラムをコンパイルすることができます。

Javac –cp <location of Access SDK jar> SampleProgram.java

必要に応じて、CLASSPATH、アクセス・クライアント・プログラム名などの詳細を変更します。CLASSPATHに追加するjarファイルの詳細は、第2.2項「Access SDKのインストール」を参照してください。

2.6 アクセス・クライアントの構成およびデプロイ

テストおよび使用するには、アクセス・クライアントの開発後、実際のAccess Manager 11g環境でデプロイする必要があります。次の概要では、Oracle Access Managementの管理者資格証明を使用してユーザーが実行する必要があるタスクを説明します。アクセス・クライアント・プログラムはすでに開発され、コンパイル済であることが前提です。

  1. Access SDKのjarファイルを取得し、アクセス・クライアントの作成に使用するコンピュータにこれをコピーします。詳細は、第2.2項「Access SDKのインストール」を参照してください。

  2. 保護対象のアプリケーションをホストしているコンピュータにアクセス・クライアントをコピーします。

  3. アクセス・クライアントを構成します。

  4. 必要なJava環境があることを確認します。

    アクセス・クライアントがスタンドアロン環境にある場合、Java Development Kit (JDK)またはJavaランタイム環境(JRE)を使用できます。アクセス・クライアントがサーブレット・アプリケーションである場合、Java EEまたはJava EEコンテナで使用可能なJava環境を使用できます。

  5. Access SDKのjarファイルがCLASSPATHにあることを確認します。JRF以外の環境を使用している場合は、必要なJPS jarファイルがCLASSPATHにあることを確認します。詳細は、第2.2項「Access SDKのインストール」を参照してください。

  6. アクセス・クライアントをデプロイするには、『Oracle Fusion Middleware Oracle Access Management管理者ガイド』のコンソールを使用したエージェントおよびアプリケーションの登録に関する項を参照してください。

この項では、Access SDKを使用して開発されたアクセス・クライアントをデプロイする前に必要な構成手順について説明します。アクセス・クライアントのデプロイメント・プロセスは、その他のAccess Managerエージェントのデプロイメント・プロセスに類似しています。この項の内容は次のとおりです。

2.6.1 構成要件

Access SDK構成は、次のファイルで構成されます。

  • ObAccessClient.xml

    この構成ファイル(ObAccessClient.xml)は、Access Managerサーバーのホスト、ポート、アクセス・クライアントの動作を決定する他の構成アイテムなど、各種詳細が含まれます。たとえば、アイドル・セッション時間などがあります。

    ObAccessClient.xmlを使用するかわりに、ブートストラップ構成を提供して11.1.2 Access SDKを初期化する方法もあります。アクセス・クライアントまたはアプリケーションは、独自の構成ストアまたは他のメソッドのブートストラップ構成を使用できます。OAMサーバーのホストやポート番号などの構成の詳細は、AccessClient.createDefaultInstanceを使用して呼び出すことができます。プログラムによる初期化の詳細は、Oracle Fusion Middleware Oracle Access Management Access Manager Access SDK Java APIリファレンスを参照してください。

  • cwallet.sso

    このOracleウォレット・ファイルは、11gエージェントをAccess Managerに登録する際に作成されるアーティファクトです。cwallet.ssoファイルには、エージェントに対して発行されたトークンをOAMサーバーが暗号化するときに使用する秘密鍵が格納されています。

    cwallet.ssoファイルは、他のファイルと同じ場所に保存することも、他の場所に保存することもできます。そのパスをjps-config.xmlで、jps-config.xmlの位置に対する相対パスとして宣言する必要があります。cwallet.ssoは11gエージェントのみに適用されます。

    JRF環境では、<DOMAIN_HOME>/config/fmwconfigディレクトリの下にシステムのjps-config.xmlがあります。このファイルによって、同じディレクトリ内にあるシステムのcwallet.ssoを使用するように指定されます。システム・ウォレットには、システム内のすべてのコンポーネント用のキーと資格証明が含まれます。このため、次の手順を使用してエージェント登録用のcwallet.ssoとシステムのcwallet.ssoをマージする必要があります。

    1. merge-cred.xmlを準備します。このファイルには、ソースのcwallet.sso(エージェント登録アーティファクト)のディレクトリおよび宛先のcwallet.sso(システム・アーティファクト)を指定します。このファイルの内容は、例2-5で定義されている内容と似たものになります。

      例2-5 merge-cred.xmlのサンプル

      <?xml version="1.0" encoding="UTF-8" standalone='yes'?>
        <jpsConfig
      xmlns="http://xmlns.oracle.com/oracleas/schema/11/jps-config-11_1.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://xmlns.oracle.com/oracleas/schema/11/
        jps-config-11_1.xsd" schema-major-version="11" schema-minor-version="1">
       
         <serviceProviders>
          <serviceProvider
      class="oracle.security.jps.internal.credstore.ssp.SspCredentialStoreProvider"
      name="credstoressp" type="CREDENTIAL_STORE">
           <description>File-based credential provider</description>
          </serviceProvider>
         </serviceProviders>
       
         <serviceInstances>
              <!-- Source file-based credential store instance -->
          <serviceInstance location="<source cwallet.sso dir>"
            provider="credstoressp" name="credential.file.source">
          </serviceInstance>
       
              <!-- Destination file-based credential store instance -->
          <serviceInstance location="<destination cwallet.sso dir>"
            provider="credstoressp" name="credential.file.destination">
          </serviceInstance>
         </serviceInstances>
       
         <jpsContexts>
          <jpsContext name="FileSourceContext">
           <serviceInstanceRef ref="credential.file.source"/>
          </jpsContext>
       
          <jpsContext name="FileDestinationContext">
           <serviceInstanceRef ref="credential.file.destination"/>
          </jpsContext>
         </jpsContexts>
      </jpsConfig> 
      
    2. 次のWLSTコマンドを実行してウォレットをマージします。

      <MW_HOME>/common/bin/wlst.sh
      wls:/offline> connect("<username>", "<password>", "<host>:<admin_port>")
      wls:/base_domain/serverConfig>
      migrateSecurityStore(type="credStore",configFile="merge-creds.xml",
       src="FileSourceContext",dst="FileDestinationContext") 
      
    3. 次のコマンドを実行して、エージェントのcwallet.ssoがシステムのcwallet.ssoに正常にマージされたかどうかを確認します。

      <MW_HOME>/oracle_common/bin/orapki wallet display 
           -wallet <destination cwallet.sso dir>
      
  • jps-config.xml

    このファイルは、cwallet.ssoファイルを読み込むためのライブラリで必要とされます。次のいずれかの場所に格納できます。

    • デフォルトでは、<current working dir>/config/jps-config.xml (クライアント・インストールzipファイルを解凍すると、テンプレートが抽出されます)です。ここで、<current working dir>は、クライアント・インストールzipファイルを解凍したディレクトリです。または

    • -Doracle.security.jps.config=jps-config.xml file locationで指定できます。ファイルの場所をJavaコマンドでプロパティとして渡す必要があります。

    サンプルのjps-config.xmlファイルがクライアント・インストール・パッケージzipファイルに含まれています。これは11gエージェントのみに適用されます。


    注意:

    前述のとおり、JRF環境では<DOMAIN_HOME>/config/fmwconfigディレクトリの下にあるシステムのjps-config.xmlファイルがデフォルトで使用されます。別のjps-config.xmlを準備する必要はありません。

  • Javaのセキュリティ権限付与

    Javaセキュリティ・マネージャが有効な場合は、ウォレット内の資格証明にアクセスできるように、system-jazn-data.xmlファイルにアプリケーション用の権限付与を追加する必要があります。環境に応じて次のいずれかを選択します。

    • JRF環境でアプリケーションをデプロイしている場合は、system-jazn-data.xmlファイルに次の権限付与を追加します。

      <grant>
        <grantee>
         <codesource>
          <url>... ...</url>
         </codesource>
        </grantee>
        <permissions>
         <permission>
           <class>oracle.security.jps.service.credstore.
                CredentialAccessPermission</class>
           <name>context=SYSTEM,mapName=OAMAgent,keyName=*</name>
           <actions>read</actions>
          </permission>
         <permissions>
       <grant> 
      
    • JRF以外の環境でスタンドアロン・アプリケーションを使用しており、Javaセキュリティ・マネージャが有効になっていない場合は(スタンドアロン・アプリケーションでは一般的)、ポリシー・ファイルは不要です。

    • JRF以外の環境でアプリケーションをデプロイしており、Javaセキュリティ・マネージャが有効な場合は、使用される該当のJavaセキュリティ・ポリシー・ファイルを見つけ(たとえばWeblogic Serverの場合はweblogic.policy)、このファイルに次のセキュリティ権限付与を追加します。

      grant codeBase "<url>"
        {
          permission
           oracle.security.jps.service.credstore.CredentialAccessPermission
           "context=SYSTEM,mapName=OAMAgent,keyName=*", "read";
        };
      

      <url>には、デプロイされるアプリケーションのコード・ソースの場所を指定します。例: file:/scratch/install/WLS_HOME/user_projects/domains/base_domain/servers/AdminServer/tmp/_WL_user/ASDKServlet/-

  • SSL用のJKSキーストア

    このファイルは、トランスポート・セキュリティ・モードが簡易または証明書である場合のみ必要です。10g OAMサーバーおよび11g OAMサーバーのどちらも、エージェントとの通信においてオープン、簡易および証明書のトランスポート・セキュリティ・モードをサポートしています。資格証明は、Oracle Access Protocol (OAP)を使用して渡されます。OAPをオープン・モードで使用すると、通信が傍受に対して脆弱になるため、本番環境ではオープン・モードで使用しないでください。オープン・モードは、テスト環境でのみ使用してください。

    Access SDKを使用して開発されたアクセス・クライアントは、エージェントと呼ばれます。OAMサーバーが構成されているモードによっては、アクセス・クライアントを同じモードで通信するよう構成する必要があります。

    すべての10gエージェントで同じグローバル・キーを共有する10gエージェントと異なり、11gエージェントはそれぞれ固有のエージェント・キーを持ちます。11gエージェント・キーはcwallet.ssoに格納されています。このキーを使用して、11g形式のSSOトークン、accessClientPasswd、および簡易または証明書トランスポート・セキュリティ・モードで使用されるグローバル・パスフレーズ(password.xmlに格納)が暗号化されます。マスター・トークンから有効範囲付きセッション・トークンを取得した場合を除き、1つのエージェントに対して発行されたSSOトークンを別のエージェントに直接使用できません。詳細は、『Oracle Fusion Middleware Oracle Access Management管理者ガイド』を参照してください。

    トランスポート・セキュリティ・モードが簡易または証明書の場合、次のものが必要です。

    • oamclient-truststore.jks

    • oamclient-keystore.jks

    • password.xml

    詳細は、第2.1.2.2項「アクセス・クライアントのアーキテクチャ」および第2.6.2項「必要な構成ファイルの生成」を参照してください。

  • password.xml

    このファイルは、トランスポート・セキュリティ・モードが簡易または証明書である場合のみ必要です。このファイルには、パスワードが暗号化された形式で含まれます。このパスワードは、SSLキー・ファイルの保護に使用されます。

    詳細は、第2.6.2項「必要な構成ファイルの生成」を参照してください。

  • ログ構成

    ログ・ファイルを生成するために必要です。詳細は、2.4項「Access SDKログの生成」を参照してください。

2.6.2 必要な構成ファイルの生成

ObAccessClient.xml構成ファイルを取得するには、管理コンソールまたはリモート登録ツールを使用して、アクセス・クライアントを10gまたは11gエージェントとしてOAM 11gサーバーに登録します。11gエージェントの登録時には、cwallet.ssoファイルも作成されます。詳細は、『Oracle Fusion Middleware Oracle Access Management管理者ガイド』を参照してください。

Oracle Access Management管理コンソールでは、password.xmlファイルも作成されます。

oracle.security.am.asdk APIで開発されたアクセス・クライアント・アプリケーションは、構成ファイルおよびその他の必要なファイルを取得するための場所を指定できます。このためには、Access SDKを初期化し、構成ファイルが存在するディレクトリの場所を指定します。

構成ファイルの場所をAccess SDKに指定するオプションの詳細は、Oracle Fusion Middleware Oracle Access Management Access Manager Access SDK Java APIリファレンスを参照してください。

2.6.3 SSL証明書とキー・ファイルの要件

11g Access SDKでは、一般に信頼ストアまたはキー・ストアとして知られるデータベースのSSL証明書およびキー・ファイルを使用します。これらのストアはJKS (Java Key Standard)形式である必要があります。詳細は、次の各項を参照してください。

2.6.3.1 簡易トランスポート・セキュリティ・モード

簡易トランスポート・モードでは、OAMサーバーによってJKSキーストアが自動生成されます。生成されたキーストアは、WLS_OAM_DOMAIN_HOME/output/webgate-ssl/に保存されます。

2.6.3.2 「証明書」トランスポート・セキュリティ・モード

証明書トランスポート・セキュリティ・モードでは、サーバーおよびエージェントの証明書を認証局にリクエストする必要があります。オプションにより、証明書モード証明書を発行する目的で、簡易モードの自己署名証明書を認証局として使用することもできます。証明書モードを準備するには、次の手順を実行します。

  1. アクセス・クライアントおよびOAMサーバーに対して発行された証明書とキーのペアを使用して、認証局のCA証明書をインポートします。第2.6.3.2.1項「CA証明書のインポート」の手順を実行してください。cacert.pemまたはcacert.derのかわりに、発行局のCA証明書ファイルを使用します。

  2. 10g JNI ASDKがインストールされている場合、アクセス・クライアントの証明書およびキー・ファイルを生成できます。これらの証明書はPEM形式となります。

    インポートされたCA証明書を使用した証明書の生成方法の詳細は、『Oracle Fusion Middleware Oracle Access Management管理者ガイド』を参照してください。

    この証明書とキーのペアをPEM形式でoamclient-keystore.jksにインポートするには、第2.6.3.2.2項「キーストアの設定」の手順を実行します。

2.6.3.2.1 CA証明書のインポート

11g Java Access SDKを使用する場合、この手順は必要ありません。

10g JNI SDKを使用する場合は、CA証明書を信頼ストアにインポートする必要があります。10g Access SDKは、簡易モードで使用できる自己署名付きCA証明書を提供し、アクセス・クライアントに証明書を発行するために使用されます。11g OAMサーバーは自己署名付きCA証明書を提供します。

  • 10g Access SDK: CA証明書(cacert.pem)は、ASDK_INSTALL_DIR/oblix/tools/openssl/simpleCAに配置されます。

  • OAM 11gサーバー: CA証明書(cacert.der)は、$MIDDLEWARE_HOME/user_projects/domains/base_domain/config/fmwconfigに配置されます。

次のコマンドを実行して、PEMまたはDER形式のCA証明書を信頼ストアにインポートします。

  1. テキスト・エディタを使用してcacert.pemまたはcacert.derを編集し、CERTIFICATEブロック内に含まれるデータを除くすべてのデータを削除し、ファイルを保存します。次に例を示します。

    -----BEGIN CERTIFICATE-----
            Content to retain
    -----END CERTIFICATE-----
    
  2. 次のコマンドを実行し、必要に応じて環境にあわせて変更します。

    keytool -importcert -file <ca cert file cacert.pem or cacert.der> -trustcacerts -keystore oamclient-truststore.jks -storetype JKS

  3. プロンプトが表示されたら、キーストアのパスワードを入力します。これは、OAMサーバーで使用されるグローバル・パス・フレーズと同じである必要があります。

2.6.3.2.2 キーストアの設定

アクセス・クライアントのSSL証明書および秘密鍵ファイルをキーストアに追加する必要があります。アクセス・クライアントがOAMサーバーと通信できるように、SSL証明書および秘密鍵ファイルは簡易モードで生成する必要があります。

  • 10g Access SDK: アクセス・クライアントの証明書およびキー・ファイルの生成を提供します。これらの証明書はPEM形式です。

  • 11g OAMサーバー: リモート登録ツールおよび管理コンソールを使用して、アクセス・クライアントの証明書(aaa_cert.pem)およびキー・ファイル(aaa_key.pem)をPEM形式で生成します。

キーストアoamclient-keystore.jksに証明書およびキー・ファイルをインポートするには、次のコマンドを実行します。

  1. テキスト・エディタを使用してaaa_cert.pemを編集し、CERTIFICATEブロック内に含まれるデータを除くすべてのデータを削除し、ファイルを保存します。次に例を示します。

    -----BEGIN CERTIFICATE-----
            Content to retain
    -----END CERTIFICATE-----
    
  2. 次のコマンドを実行し、必要に応じて環境にあわせて変更します。

    openssl pkcs8 -topk8 -nocrypt -in aaa_key.pem -inform PEM -out aaa_key.der -outform DER

    このコマンドにより、パスワードの入力が要求されます。パスワードはグローバル・パス・フレーズである必要があります。

  3. 次のコマンドを実行し、必要に応じて環境にあわせて変更します。

    openssl x509 -in aaa_cert.pem -inform PEM -out aaa_cert.der -outform DER

  4. 次のコマンドを実行し、必要に応じて環境にあわせて変更します。

    java -cp importcert.jar oracle.security.am.common.tools.importcerts.CertificateImport -keystore oamclient-keystore.jks -privatekeyfile aaa_key.der -signedcertfile aaa_cert.der -storetype jks -genkeystore yes

    このコマンドでは、aaa_key.derおよびaaa_cert.derはDER形式の秘密鍵と証明書のペアです。

  5. プロンプトが表示されたら、キーストアのパスワードを入力します。これはグローバル・パス・フレーズと同じである必要があります。

2.7 互換性: 11gと10gのAccess SDKおよびAPI

11g Access Manager APIにより、開発者はカスタム・アクセス・クライアント・コードをJavaで記述できますが、これは10g (10.1.4.3) Javaアクセス・クライアントと機能的に同等です。Access Manager 11gにより、JavaコードはAPI内の基礎となるJavaバイナリと通信します。

組込みの自動Javaガベージ・コレクタにより、未使用のオブジェクトのメモリーはガベージ・コレクタが適切と見なした場合に割当て解除されます。ガベージ・コレクタでは、オブジェクトがいつクリーン・アップされるかは保証されませんが、オブジェクトが参照されなくなった場合にすべて破棄され、メモリー・リークが発生しないことが保証されます。

10gおよび11g Access Manager APIの機能は、7つの基本クラスで編成されています。表2-3に、Java言語プラットフォームの対応するクラス名をリストします。

表2-3 比較: 11gおよび10g Access APIクラス

クラスの用途 11g Javaクラス 10g Javaクラス

ユーザー認証を処理するための構造体を作成および操作する

oracle.security.am.asdkのAuthenticationSchemeクラス

ObAuthenticationSchemeはObAuthenticationSchemeInterfaceを実装する

リソースに対するユーザー・リクエストを処理するための構造体を作成および操作する

oracle.security.am.asdkのResourceRequestクラス

ObResourceRequestはObResourceRequestInterfaceを実装する

ユーザー・セッションを処理するための構造体を作成および操作する。ユーザー・セッションは、ユーザー認証とともに開始され、ユーザーがログオフするかタイムアウトになると終了する。

ユーザーの統合セッションを処理するための構造体を作成および操作する。セッションは、ユーザーの初回認証時に開始され、ユーザーがログオフするかセッション・タイムアウトになると終了する。

oracle.security.am.asdkのUserSessionクラス

oracle.security.am.asdkのPseudoUserSessionクラス

ObUserSessionはObUserSessionInterfaceを実装する

ObPseudoUserSession

アクセス・クライアント構成情報を取得および変更する

oracle.security.am.asdkのAccessClientクラス

ObConfig

Access Manager APIによってスローされるエラーを処理する

oracle.security.am.asdkのAccessException、OperationNotPermittedException

ObAccessException

構成の変更をコール元アプリケーションに通知する。

oracle.security.am.asdkのConfigUpdateCallbackクラス



この項で説明する項目は、次のとおりです。

2.7.1 11g Access SDKの互換性

11g Access SDKは、10g JNI ASDKでサポートされている機能を実装しています。この機能は、これを使用して10gと11g両方のOAMサーバーとシームレスに連携するカスタム・アクセス・クライアントを開発できるように実装されています。

また、Access SDKには、11g OAMサーバーでのみ使用できる新機能および変更された機能が実装されています。したがって、Access SDKではアプリケーションが10g OAMサーバーでこの機能の使用を試みるかどうかを正常に検出できます。

11g Access SDK (oracle.security.am.asdk)の新機能は次のとおりです。

  • 指定されたユーザーのセッションの列挙

  • 指定されたセッションの終了

  • 指定されたユーザー・セッションでの属性の設定

  • 指定されたセッションで設定された属性の取得

  • セッションを確立せずにユーザー資格証明を検証

  • セッションを確立せずにユーザー資格証明を検証し、同じリクエストで認可を実行


注意:

最後の2つの機能は、Access Manager 11g Access SDKのcom.oblix.accessパッケージでも提供されています。

さらに、Access SDKはサーバー側のセッションを削除するユーザー・ログアウト機能の変更済実装を提供します。この機能は、10g OAMサーバーではサポートされていません。

2.7.2 10g JNI ASDKと11g Access SDKの互換性

10g JNI ASDKと11g Access SDKバージョンのcom.oblix.accessパッケージの間には1対1の対応関係があります。

10g JNI ASDKを使用して開発されたカスタム・アクセス・クライアントは、コードの変更なしで引き続き11g Access SDKで動作できます。

11g Access SDK com.oblix.accessパッケージには、次のクラスが追加されています。

  • ObPseudoUserSession: このクラスは、11g OAMサーバーのみで使用できる次の機能を提供します。

    • セッションを確立せずにユーザー資格証明を検証します。

    • セッションを確立せずにユーザー資格証明を検証し、同じリクエストで認可を実行します。

  • ObAccessRuntimeException: このクラスは、ObAuthenticationSchemeクラスおよびObResourceRequestクラスを使用する操作の実行中にランタイム・エラーを示します。

2.7.3 非推奨: 10g JNI ASDK

11g Access SDKは、10g JNI ASDK com.oblix.accessパッケージのインタフェースをサポートします。ただし、com.oblix.accessのすべてのAPIが非推奨としてマークされています。これらのAPIは、将来のAccess Manager 11g Access SDKリリースにおいて拡張もサポートもされません。

開発者はあらゆる新規開発において11g Access SDKを使用することを強くお薦めします。

2.8 10gアプリケーションの移行と変換

この項では、11g Access SDKを使用する場合に実行する移行プロセスを説明します。次の理由から、Access SDKへの移行が必要となる場合があります。

  • アプリケーションを移行することで、これらのアプリケーションにおけるAccess SDKの使用方法を変更せずに、10g JNI ASDKのcom.oblix.access APIを、11g Access SDKの対応するAPIと置き換えます。

  • アプリケーション・コードを移行することで、com.oblix.access (これは下位互換性のために11g Access SDKでサポートされます)のかわりにoracle.security.am.asdk APIを使用するようにします。

アプリケーションを移行する前に、開発環境と11g Access SDKが正しく構成されていることを確認します。詳細は、第2.6項「アクセス・クライアントの構成およびデプロイ」を参照してください。この項には次のトピックが含まれます。

2.8.1 11gとの併用を可能にする10g ASDKコンポーネントの移行

10g com.oblix.accessパッケージで開発されたアクセス・クライアントおよびプラグインを、11g OAMサーバーで動作するよう移行できます。この項では、10g JNI ASDKで記述されたプログラムを11g OAMサーバーで使用する方法を説明します。


注意:

10g JNI ASDKと11g Access SDKのcom.oblix.access APIにおける類似点と相違点の詳細は、第2.7.2項「10g JNI ASDKと11g Access SDKの互換性」を参照してください。

10g JNI ASDKおよび11g Access SDKで提供されているcom.oblix.accessクラスおよびインタフェースのサポートは同じです。通常、11g Access SDKのcom.oblix.accessクラスを使用するためにアプリケーションを移行する場合、アプリケーション・コードを変更または再コンパイルする必要はありません。


注意:

新しいランタイム例外のObAccessRuntimeExceptioncom.oblix.accessパッケージに導入されています。この例外は、AuthenticationSchemeクラスおよびResourceRequestクラスの操作時にスローされます。

アプリケーション・コードで正しい例外処理を実行することをお薦めします。これを実行した場合、アプリケーションを11g Access SDK jarファイルで再コンパイルする必要があります。


この説明では、10g ASDKコンポーネントがインストールされており、OAMサーバーで構成されていることを前提としています。シナリオでは、10g JNI ASDKを使用して開発された既存のアクセス・クライアント・アプリケーションを使用します。前提は次のとおりです。

  • 第2.6.1項「構成要件」にリストした構成アイテムは、10g ASDKのインストール・ディレクトリ(ASDK_INSTALL_DIR)から参照されます。

  • ASDK_INSTALL_DIR/access/oblix/libからObAccessClient.xmlが読み取られます。

  • トランスポート・セキュリティ・モードが簡易または証明書である場合、ASDK_INSTALL_DIR/access/oblix/configからpassword.xmlが読み取られます。

環境を設定するには、第2.5.1項「開発環境の設定」の手順を実行します。10g JNI ASDKのファイル名はjobaccess.jarです。jobaccess.jarがCLASSPATHにある場合、削除する必要があります。

com.oblix.access APIを使用するために移行されたアクセス・クライアント・アプリケーションでは、10g JNI ASDK構成ファイルの場所を次のように指定できます。

  • ASDKの初期化中に、10g ASDKがインストールされているディレクトリの場所を指定します。または、

  • 10g JNI ASDKがインストールされているディレクトリの場所を指す、環境変数OBACCESS_INSTALL_DIRを設定します。

これによって、11g Access SDKは、渡された場所に基づいて必要なファイルのパスを判別します。次の各項には、コンポーネントのモードに応じた詳細が含まれます。

2.8.1.1 簡易モードの10g ASDKコンポーネントの移行

10g ASDKコンポーネントを簡易モードで構成するには、10gリリースのOracle Access Manager管理ガイドを参照してください。次の手順を実行します。

  1. aaa_cert.pemおよびaaa_key.pemファイルをoamclient-keystore.jksにインポートします。

    aaa_cert.pemおよびaaa_key.pemファイルは、ASDK_INSTALL_DIR/access/oblix/config/simpleに置かれています。

  2. 簡易モード証明書の発行に使用される自己署名CA証明書を、ASDK_INSTALL_DIR/access/oblix/tools/openssl/simpleCAに置きます。

  3. 自己署名CA証明書をoamclient-truststore.jksにインポートします。

  4. 2.6.3項「SSL証明書とキー・ファイルの要件」の手順に従って、証明書とキー・ファイルをJKSストアにインポートします。

  5. JKSストアをASDK_INSTALL_DIR/access/oblix/config/simpleにコピーします。

2.8.1.2 証明書モードの10g ASDKコンポーネントの移行

10g ASDKコンポーネントを証明書モードで構成するには、10gリリースのOracle Access Manager管理ガイドを参照してください。次の手順を実行します。

  1. aaa_cert.pemおよびaaa_key.pemファイルをoamclient-keystore.jksにインポートします。aaa_chain.pemをoamclient-truststore.jksにインポートします。

    aaa_cert.pem、aaa_key.pemおよびaa_chain.pemファイルは、ASDK_INSTALL_DIR/access/oblix/configに置かれています。

  2. 2.6.3項「SSL証明書とキー・ファイルの要件」の手順に従って、証明書とキー・ファイルをJKSストアにインポートします。

  3. JKSストアをASDK_INSTALL_DIR/access/oblix/config/simpleにコピーします。

2.8.2 10gコードの変換

この項では、10g JNI ASDKで記述されたプログラムをAccess Manager 11gで使用する方法を説明します。11g Java Access SDKは、com.oblix.accessパッケージの10g JNI ASDK APIの機能をサポートしています。同じ機能を11g Access SDKに実装することで、10g JNI ASDKとの下位互換性を実現しています。ただし、com.oblix.accessのAPIはすべて非推奨です。これらのAPIは、将来の11g Access SDKリリースにおいて拡張もサポートもされません。

oracle.security.am.asdkパッケージには、新規の認証および認可APIが含まれます。com.oblix.accessパッケージが提供する機能の他に、oracle.security.am.asdkパッケージには、11g OAMサーバーの機能を利用する拡張機能も含まれています。表2-4は、10g JNI SDK com.oblix.access packageのAPIと11g Access SDK oracle.security.am.asdkパッケージのAPIを比較したものです。必要に応じて、10g JNI ASDKと11g Access SDKのクラスの対応関係も示しています。

表2-4 パッケージの相違点: com.oblix.accessとoracle.security.am.asdk

JNI ASDK com.oblix.accessパッケージ Access SDK oracle.security.am.asdkパッケージ

インタフェースの要約:

  • ObAuthenticationSchemeInterface

  • ObResourceRequestInterface

  • ObUserSessionInterface

インタフェースの要約:

なし

クラスの要約:

  • ObAuthenticationScheme

  • ObConfig

  • ObDiagnostic

  • ObResourceRequest

  • ObUserSession

クラスの要約:

  • AuthenticationScheme

  • AccessClient

  • Supported through AccessClient

  • ResourceRequest

  • UserSession

  • PseudoUserSession

  • BaseUserSession

例外の要約:

ObAccessException

例外の要約:

  • AccessException

  • OperationNotPermittedException

列挙の要約:

なし

列挙の要約:

AccessClient.CompatibilityMode.OAM_10G

AccessClient.CompatibilityMode.OAM_11G


11g Access SDKには、Oracle Access Manager 10g JNI SDKのAPIに機能的に類似した新規のAPIセットが含まれますが、インタフェースが新しくなっているので注意してください。10g JNI ASDKを使用して実装されたアプリケーション・コードを移行して、11g Access SDKと同じ機能を実現できます。次の各項では、11g Access SDKの新しいAPIを使用するために既存のアプリケーションコードを変更する方法を説明します。

2.8.2.1 Access SDKの初期化および非初期化

10g JNI SDKでは、com.oblix.access.ObConfigクラスがASDKの初期化および非初期化を実行する機能を提供します。11g Access SDKでは、oracle.security.am.asdk.AccessClientがこの機能を提供します。10g JNI SDKと同様に、アクセス・クライアント・アプリケーション・インスタンスは指定された構成で動作できます。要件に応じて、AccessClientクラスを次の2通りに使用できます。

  • createDefaultInstance静的関数を使用して、AccessClientクラスの単一インスタンスを作成できます。このクラスのデフォルト・インスタンスは1つのみ使用できます。アクセス・クライアント・アプリケーションの単一インスタンス内でこのメソッドを複数回起動すると、例外が発生します。

    createDefaultInstanceメソッドを使用する場合、AuthenticationSchemeResourceRequestまたはUserSessionクラスのいずれかをインスタンス化する際には、このメソッドを使用して取得したAccessClientクラス・インスタンスを使用する必要があります。これらのクラスをインスタンス化する際にAccessClientインスタンスを指定しないと、デフォルトのインスタンスが使用されます。

    AccessClientオブジェクトを初期化するとき、AccessClient.CompatibilityMode.OAM_10GまたはAccessClient.CompatibilityMode.OAM_11Gを渡すことができます。指定しないと、デフォルトのOAM_11Gが使用されます。その場合、11gエージェントが登録されており、必要な11gエージェント構成ファイルが適切に設定されていることを確認してください。

  • createInstance静的関数を使用して、指定の構成で初期化された新規のAccessClientクラス・インスタンスを作成できます。このクラスが必要とされるのは、このクラスがアクセス・クライアント・アプリケーションの同じ実行中インスタンス内にあり、アプリケーションが様々なAccess Managerシステムまたは構成で動作する必要がある場合です。各AccessClientクラス・インスタンスは、アクセス・クライアント・インスタンスの構成時に適切なロガー名を渡すことで、メッセージを別のログ・ファイルに記録できます。

    AccessClientオブジェクトを初期化するとき、AccessClient.CompatibilityMode.OAM_10GまたはAccessClient.CompatibilityMode.OAM_11Gを渡すことができます。指定しないと、デフォルトのOAM_11Gが使用されます。その場合、11gエージェントが登録されており、必要な11gエージェント構成ファイルが適切に設定されていることを確認してください。

    createInstanceメソッドを使用する場合、AuthenticationSchemeResourceRequestまたはUserSessionクラスをインスタンス化する際に、このメソッドを使用して取得されたAccessClientクラス・インスタンスを使用する必要があります。これらのクラスをインスタンス化する際にAccessClientインスタンスを指定しないと、デフォルトのインスタンスが使用されます。

アプリケーションの停止時に、AccessClientクラスのshutdownメソッドを起動して、次の例に示すように非初期化を実行します。

  • 10g JNI ASDKの場合

    Public static void main (String args[]) {
      try {
       ObConfig.Initialize (); // Configuration is read from the location pointed by OBACCESS_INSTALL_DIR
                                             // environment variable
    

    または

      ObConfig.Initialize (configLocation); //Configuration is read from the location provided
       ………..
       }catch (ObAccessException e){
       }
    ObConfig.shutdown();
    }//main ends here
    
  • 11g Access SDKの場合

    import java.io.*;
    import java.util.*;
    import oracle.security.am.asdk.*; //Import classes from OAM11g Access ASDK
    …………..
    Public static void main (String args[]) {
      try {
         ac = AccessClient.createDefaultInstance ("", AccessClient.CompatibilityMode.OAM_10G); // Refer to Oracle Fusion Middleware Access SDK Java API Reference for Oracle Access Management Access Manager
    

    または

         AccessClient.createInstance("",AccessClient.CompatibilityMode.OAM_10G); // Refer to Oracle Fusion Middleware Access SDK Java API Reference for Oracle Access Management Access Manager
       ………..
       }catch (AccessException e){
       }
    ac.shutdown();
    }//main ends here
    

2.8.2.2 アクセス操作の実行

表2-4に示すように、アクセス操作の実行に使用されるクラス間には1対1マッピングがあります。oracle.security.am.asdkのクラスは、AuthenticationSchemeResourceRequestおよびUserSessionです。AccessClientクラスのインスタンス化の方法に応じて、これらのクラスの対応するコンストラクタを使用します。

10g JNI ASDKと同様に、初期化時またはアクセス操作の実行中に発生したエラーは例外として報告されます。AccessExceptionは、次の例に示すように、11g Access SDKで使用される例外クラスです。

  • 10g JNI ASDKの場合

    Public static void main (String args[]) {
      try {
       ObConfig.Initialize (); // Configuration is read from the location pointed by OBACCESS_INSTALL_DIR
                                             // environment variable
       ObResourceRequest rrq = new ObResourceRequest(ms_protocol, ms_resource,ms_method);
       if (rrq.isProtected()) {
         System.out.println("Resource is protected.");
         ObAuthenticationScheme authnScheme = new ObAuthenticationScheme(rrq);
         if (authnScheme.isForm()) {
           System.out.println("Form Authentication Scheme.");
           Hashtable creds = new Hashtable();
           creds.put("userid", ms_login);
           creds.put("password", ms_passwd);
           ObUserSession session = new ObUserSession(rrq, creds);
           if (session.getStatus() == ObUserSession.LOGGEDIN) {
             if (session.isAuthorized(rrq)) {
               System.out.println("User is logged in and authorized for the
               request at level " + session.getLevel());
             } else {
               System.out.println("User is logged in but NOT authorized");
             }
          } else {
            System.out.println("User is NOT logged in");
         }
       } else {
         System.out.println("non-Form Authentication Scheme.");
      }
    } else {
      System.out.println("Resource is NOT protected.");
    }
    }catch (ObAccessException oe) {
      System.out.println("Access Exception: " + oe.getMessage());
    }
    ObConfig.shutdown();
    }//main ends here
    
  • 11g Access SDKの場合

    import java.io.*;
    import java.util.*;
    import oracle.security.am.asdk.*; //Import classes from OAM11g Access ASDK
     
    Public static void main (String args[]) {
      AccessClient ac;
      try {
        ac = AccessClient.createDefaultInstance("",
         AccessClient.CompatibilityMode.OAM_10G);
     
        ResourceRequest rrq = new ResourceRequest(ms_protocol,ms_resource, ms_method);
     
        if (rrq.isProtected()) {
          System.out.println("Resource is protected.");
          AuthenticationScheme authnScheme =new AuthenticationScheme(rrq);
          if (authnScheme.isForm()) {
            System.out.println("Form Authentication Scheme.");
            Hashtable creds = new Hashtable();
            creds.put("userid", ms_login);
            creds.put("password", ms_passwd);
            creds.put("ip", ms_ip);
            creds.put("operation", ms_method);
            creds.put("resource", ms_resource);
            creds.put("targethost", ms_targethost);
     
            UserSession session = new UserSession(rrq, creds);
            if (session.getStatus() == UserSession.LOGGEDIN) {
              if (session.isAuthorized(rrq)) {
                System.out.println("User is logged in " +
                    "and authorized for the request " +"at level " + session.getLevel());
              } else {
                System.out.println("User is logged in but NOT authorized");
              }
            } else {
              System.out.println("User is NOT logged in");
            }
          }
        }catch (AccessException oe) {
          System.out.println("Access Exception: " + oe.getMessage());
        }
        ac.shutdown();
    } //main ends here
    

2.9 ベスト・プラクティス

この項では、様々な問題を回避する方法や、開発中に頻繁に発生する問題を解決するための方法をいくつか説明します。この項で説明する項目は、次のとおりです。

2.9.1 カスタム・アクセス・クライアントでの問題の回避

カスタム・アクセス・クライアントでの問題発生を回避するための提案を次に示します。

  • アクセス・クライアントが適切なOAMサーバーに接続しようとしているかを確認します。

  • OAMサーバーについての構成情報とアクセス・クライアントについての構成情報が一致するようにします。Oracle Access Management管理コンソールを使用して、OAMサーバー上のアクセス・クライアントの構成情報を確認できます。詳細は、『Oracle Fusion Middleware Oracle Access Management管理者ガイド』のエージェントおよびアプリケーションの登録に関する項を参照してください。

  • OAMサーバーとの接続や切断をきれいに行うには、AccessClientクラスのinitializeメソッドおよびshutdownメソッドを使用します。

  • 環境変数OBACCESS_INSTALL_DIRをWindowsまたはUNIXタイプのホスト・コンピュータ上で設定し、アクセス・クライアントをコンパイルおよびリンクできるようにする必要があります。一般的に、この変数は、アクセス・クライアントを実行する場合にも必ず設定しておく必要があります。

  • 開発中に問題を捕捉したり報告するには、カスタム・アクセス・クライアント・コードの作成に使用した言語の例外処理機能(try、throwおよびcatch)を使用します。

  • アクセス・クライアントは、マルチスレッド・アプリケーション全体でただ1つのスレッドとなります。そのような環境内で確実に安全な操作ができるように、開発者は、スレッド・セーフなコードを開発するための次のプラクティスを遵守するようお薦めします。

    • シングル・スレッド関数ではなく、スレッド・セーフ関数を使用します。たとえば、localtimeでなくlocaltime_rを使用します。

    • マルチスレッド機能がサポートされるよう、適切なビルド環境とコンパイラ・フラグを指定します。たとえば、-D_REENTRANTを使用します。また、UNIX型プラットフォームでは-mt、Windowsプラットフォームでは/MDを使用します。

    • FILEポインタなどのスレッド・セーフ方式の共有ローカル変数は注意して使用してください。

2.9.2 アクセス・クライアントに関する問題の特定と解決

アクセス・クライアントが実行に失敗したかどうかの確認点を次に示します。

  • OAMサーバーが実行中であることを確認します。Windowsシステムでこれを確認するには、「コンピュータの管理」、「サービス」、「AccessServer」の順にナビゲートします。AccessServerは、アクセス・クライアントを接続するOAMサーバーの名前です。

  • アクセス・クライアントがユーザー・ログアウトを実行することを確認し、OAMサーバー側のセッションが必ず削除されるようにします。ユーザー・セッションが蓄積すると、ユーザー認証に失敗する可能性があります。

  • コードが想定しているドメイン・ポリシーが正しく存在し、有効化されていることを確認します。

  • リリース・ノートの確認

  • アクセス・システムの低位レベルのポリシーが、検査中のポリシーをオーバーライドして、アクセス・クライアントに応答しないようにします。

  • 11gアクセス・テスターを使用すると、特定のリソースにどのポリシーが適用されるかを確認できます。アクセス・テスターの使用方法およびアプリケーション・ドメインによるリソースの保護の詳細は、『Oracle Fusion Middleware Oracle Access Management管理者ガイド』を参照してください。

2.9.3 環境に関する問題の解決

この項では、11g Java Access SDKの使用時に発生する可能性のある環境の競合を解消するための情報を提供します。次のコンテナに関する情報が含まれます。

2.9.3.1 Java EEコンテナ

11g Java Access SDKを使用するWebアプリケーションで、Javaクラス・バージョンの競合を解消するには、次の手順に従ってください。

Access SDKによって使用されるライブラリと異なるバージョンのライブラリが、同じJava EEコンテナにホストされている別のアプリケーションによってロードされると、競合が発生します。表示される可能性のあるエラー・メッセージのサンプルを次に示します。

oracle/security/am/common/aaaclient/ObAAAServiceClient.&lt;init&gt;(Ljava/lang
/String;[CILjava/lang/String;Ljava/lang/String;[C[CZIJJLjava/lang/Integer;Ljava/u
til/List;Ljava/util/List;)V 
at oracle.security.am.asdk.AccessClient.createClient(AccessClient.java:798) 
at oracle.security.am.asdk.AccessClient.initialize(AccessClient.java:610) 
at oracle.security.am.asdk.AccessClient.&lt;init&gt;(AccessClient.java:527) 
at
oracle.security.am.asdk.AccessClient.createDefaultInstance(AccessClient.java:234) 
at com.newco.authenticateIdentity.AuthenticateIdentityAccessClient.authenticateUser(
AuthenticateIdentityAccessClient.java:52)

この問題は、Java EEコンテナへのクラスのロード方法に関係しています。詳細は、使用しているコンテナの、クラスのロードについて記載されたドキュメントを参照してください。

この問題を解消するには、特定のライブラリ・バージョンを必要とするWebアプリケーションに対してクラス・ローダー・フィルタリングを構成します。詳細と手順は、使用しているアプリケーション・サーバーのドキュメントを参照してください。

2.9.3.2 Oracle WebLogicサーバー

システム・クラス・ローダーを使用してロードするかわりに、WebLogic Server FilteringClassLoaderを使用すると、アプリケーションから常にロードされるパッケージを指定できます。

この問題を解決するには、次の手順を実行します。

  1. weblogic.xmlファイルがアプリケーションのMETA-INFフォルダに存在することを確認します。存在しない場合は、このファイルを作成して次のコメントを追加します。

    <?xml version="1.0" encoding="UTF-8"?>
    <weblogic-application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.bea.com/ns/weblogic/weblogic-application/1.0/we
    blogic-application.xsd"
    xmlns="http://www.bea.com/ns/weblogic/weblogic-application">
    
    <prefer-application-packages>
      <?xml version="1.0" encoding="UTF-8"?>
    <weblogic-application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.bea.com/ns/weblogic/weblogic-application/1.0/we
    blogic-application.xsd"
    xmlns="http://www.bea.com/ns/weblogic/weblogic-application">
    
    <prefer-application-packages>
    <package-name>Package to be loaded</package-name>
    <package-name>Package to be loaded</package-name>
    </prefer-application-packages>
    </weblogic-application>
    

    ここで、Package to be loadedはログ・ファイルにある対応するパッケージです。たとえば、問題のあるのがObAAAServiceClientとすると、対応するパッケージ名はoracle.security.am.common.aaaclientです。この場合、次のように追加します。

    <package-name>oracle.security.am.common.aaaclient.*<package-name>
    

    バージョンが異なる同一のクラスがシステム・クラス・ローダーのCLASSPATHで指定されていても、このパッケージに関連付けられたすべてのクラスがアプリケーション・ローダーによってロードされます。

  2. アプリケーションを停止します。

  3. 以前デプロイしたバージョンのアプリケーションを削除します。

  4. アプリケーションをインストールします。

  5. リソースにアクセスします。

    エラーが解消され、アプリケーションが正常に動作します。

2.9.3.3 その他のアプリケーション・サーバー

どのアプリケーション・サーバーにも構成ファイルがあり、そのファイルでクラスのロードに関連するオプションが構成されます。一般に、特定のクラス・ローダーで一連のクラスをロードできるようにするために必要な構成ファイルとタグを特定することが鍵となります。

  1. アプリケーション・サーバーの構成ファイルを特定します。

  2. アプリケーション・クラス・ローダーを使用して、クラスがCLASSPATHで指定されていても親クラス・ローダーによってロードされないようにします。

  3. デフォルトのクラスのロード動作を変更して、現在のクラス・ローダーがクラスのロードに失敗した場合にのみ親クラス・ローダーがコールされるようにします。

  4. または、WebLogic Serverのように、指定のクラス・ローダーを使用してクラスをロードできる方法が存在する場合もあります。

  5. アプリケーション・サーバーによっては、アプリケーション用に親ドメインとは別のドメインを定義し、親を最後にロードするようクラスのロード動作を設定する必要がある場合もあります。

2.9.4 高負荷環境のためのチューニング

高負荷で高ストレスな環境では、11g Access SDKの環境を次のようにチューニングしてください。

  • ユーザー定義パラメータとしてpoolTimeoutを構成します。poolTimeoutのクライアント数を増やしてください。

  • 最大接続数を調整します。パフォーマンスを向上させるためには、プライマリ・サーバーの最大接続数をエージェント・プロファイルで設定する必要があります。