Oracle® Fusion Middleware Oracle Access Management開発者ガイド 11g リリース2 (11.1.2.2.0) for All Platforms B69537-08 |
|
前 |
次 |
Oracle Access Management Access Manager (Access Manager)では、カスタム・アクセス・クライアントを作成するための純粋なJavaソフトウェア開発キット(SDK)およびアプリケーション・プログラミング・インタフェース(API)を提供しています。この章では、カスタム・アクセス・クライアントの開発方法と次の項目について説明します。
Webgateは、リソースに対するHTTPリクエストを捕捉して、認証と認可のためにOAMサーバーに転送するWebサーバー・プラグインです。Webgateは、アクセス・リクエストに対する実際の強制ポイントとして機能するWebサーバー・エージェントです。複数のWebgateがそのまま使用できる状態で用意されており、アクセス・リクエストを捕捉するOracle HTTP Serverにインストールできます。
アクセス・クライアントとは、11g Access SDKおよびAPIを使用して開発されたカスタムWebgateのことです。標準のWebgateが適切でない場合は、カスタム・アクセス・クライアントを記述してデプロイすることにより、WebリソースまたはWeb以外のリソース(HTTP以外)に対するユーザーまたはアプリケーションからのリクエストを処理できます。
この項の内容は次のとおりです。
11g Access SDKおよびAPIは、Javaアプリケーション開発者を対象とし、密結合されている高パフォーマンスの統合の開発を目的としています。詳細は、このガイドの他にOracle Fusion Middleware Oracle Access Management Access Manager Access SDK Java APIリファレンスを参照してください。
Access SDKは、オラクル社が様々なエンタープライズ・プラットフォーム(32ビットおよび64ビットの両方のモードを使用)およびハードウェアの組合せで認証した、プラットフォーム非依存パッケージです。これは、Oracle Fusion Middlewareアプリケーション間でサポートされているJDKバージョンで提供されています。
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レイヤーを使用して既存のカスタム・コードを記述しなおすことができます。
注意: 10g (10.1.4.3)のcom.oblix.access パッケージおよびクラスは非推奨です。非推奨APIは、機能改良などの理由から使用が推奨されておらず、通常はそれにかわるAPIが提供されます。非推奨APIは今後の実装で削除される可能性があります。
開発者はあらゆる新規開発において11g Access SDKを使用することを強くお薦めします。 |
Access SDKのインストール後は、サブディレクトリおよびファイルの相対的な場所を変更しないでください。変更すると、APIが正しくビルドおよび操作できなくなります。次のAccess SDKパッケージが含まれています。
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+)バージョンのサーバーで使用できます。
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ロギング・メカニズムにより、ローカル・ファイルに表示する詳細のレベル(情報、警告およびエラーの各レベル)を指定できます。メッセージは、問題を解決するための十分な詳細を提供します。たとえば、互換性のないAccess SDKパッケージが使用されている場合、ログ・メッセージには、バージョン不一致に関する詳細と、遵守する必要があるバージョン基準が含まれます。 SDKが指定期間内に大量のログを生成した場合、ファイル制限または期間に基づいてログのロールオーバーを構成できます。たとえば、ファイル制限に達した場合(または一定時間が経過した場合)、ログ・ファイルはアーカイブ・ディレクトリにコピーされ、新規ログ・ファイルが開始されます。 |
Java Access SDK Client for Access Manager 11gをインストールするには、次の手順を実行します。
Oracle Technology Networkからoam-java-asdk.zip
ファイルをダウンロードします。
ファイルoam-java-asdk.zip
の中身をローカル・ディレクトリに展開します。
oamasdk-api.jar
をCLASSPATHに追加します。必要に応じて、次の追加のJARファイルから選択します。
JRF以外の環境を使用している場合は、次のようにします。
アクセス・クライアントを10gモードで構成している場合は、jps-api.jar
をCLASSPATHに追加します。
アクセス・クライアントを11gモードで構成している場合は、次のJARファイルをCLASSPATHに追加します。
identitystore.jar jps-api.jar jps-common.jar jps-internal.jar jps-unsupported-api.jar oraclepki.jar osdt_cert.jar osdt_core.jar osdt_xmlsec.jar
JRF環境を使用している場合は、OPSS依存性は最初から設定されています。CLASSPATHの追加の変更は必要ありません。
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管理者ガイド』を参照してください。
一般に、Oracle Access Managerによってまだデフォルト・ソリューションが用意されていないリソースへのアクセスを制御する必要がある場合に、標準のWebgateのかわりに、カスタム・アクセス・クライアントをデプロイします。これには次のような場合が含まれます。
HTTP以外のリソースの保護。
特殊機能を実装するために開発したカスタムWebサーバーの保護(リバース・プロキシなど)。
HTTPとHTTP以外のリソースの組合せを保護するためのシングル・サインオン(SSO)の実装。
たとえば、Oracle WebLogic ServerクラスタおよびOracle WebLogic Server以外のリソースが含まれる企業環境内でのSSOを容易にするアクセス・クライアントを作成できます。
各アクセス・クライアントは、次の3種類のリソースから構築されます。
カスタム・アクセス・クライアント・コード
サーブレットまたはスタンドアロン・アプリケーションに組み込まれます。11gリリースでは、Java言語プラットフォームを使用してアクセス・クライアント・コードを記述します。
構成情報
ObAccessClient.xmlファイル: プライマリ構成ファイル。アクセス・クライアント・プロファイルを構成する構成情報が格納されています。
cwallet.ssoおよびjps-config.xmlファイル: 11gエージェントの場合のみ。
トランスポート・セキュリティ・モードが簡易または証明書の場合、次のファイルが必要です。
oamclient-truststore.jks: 証明書発行局のCA証明書が含まれるJKS形式の信頼ストア・ファイル。
oamclient-keystore.jks: アクセス・クライアントに対して発行された証明書および秘密鍵が含まれるJKS形式のキー・ストア・ファイル。
password.xml: グローバル・パス・フレーズの値を保持するXMLファイル。秘密鍵ファイルを保護する際にも同じパスワードが使用されます。
Access Manager APIライブラリ
アクセス・クライアントとOAMサーバー間の連携を可能にします。
図2-1は、ホスト・サーバーにインストールされたアクセス・クライアント・コンポーネント間の関係を示しています。
第2.1.3.2項「アクセス・クライアントのアーキテクチャ」で説明しているリソースのタイプにより生じる多様性にかかわらず、アクセス・クライアントの多くは同じ基本ステップに従ってユーザー・リクエストを処理します。
ユーザーまたはアプリケーションが、アクセス・クライアントがインストールされているサーバー上で動作するサーブレットまたはアプリケーションに対してリソース・リクエストを発行すると、そのサーブレットまたはアプリケーションに埋め込まれたアクセス・クライアント・コードが図2-2に示す基本プロセスを開始します。
図2-2は、リソース・リクエストの処理方法を示しています。
プロセスの概要: リソース・リクエストの処理
アクセス・クライアント・コードが埋め込まれているアプリケーションまたはサーブレットが、ユーザーのリソース・リクエストを受け取ります。
アクセス・クライアントにより、ResourceRequest
構造体が構成されます。この構造体は、リクエストされたリソースが保護されているかどうかをアクセス・クライアント・コードがOAMサーバーに問い合せるために使用されます。
OAMサーバーが応答します。
状況に応じて、次のいずれかが発生します。
リソースが保護されていない場合、アクセス・クライアントはDenyOnNotProtected
フラグの値に基づいて、リソースに対するアクセス権を付与または拒否します。デフォルト値はtrueです。
Access Manager 11gエージェントの場合、DenyOnNotProtected
フラグは常にtrueであり、変更できません。
リソースが保護されている場合、アクセス・クライアントがAuthenticationScheme
構造体を構成、使用して、ユーザーがどの資格証明を提示する必要があるかをOAMサーバーに問い合せます。このステップは、アクセス・クライアントでリソース別の認証スキームを使用できる場合にのみ必要です。
OAMサーバーが応答します。
アプリケーションは、フォームまたはその他の手段を使用してユーザー資格証明を要求します。場合によっては、ユーザー資格証明が次の一部としてすでに発行されていることがあります。
有効なセッション・トークン
Webブラウザからの入力
アクセス・クライアント・アプリケーションを起動したコマンド行スクリプトの引数またはキーボード入力
ユーザーがアプリケーションに応答します。
アクセス・クライアントによりUserSession
構造体が構成され、この構造体を通して、OAMサーバーはユーザー資格証明を取得し、資格証明をOracle Access Managerユーザー・ディレクトリ内のユーザー・プロファイルにマップします。
資格証明が有効と判定されると、アクセス・クライアントがユーザーのセッション・トークンを作成し、認可リクエストをOAMサーバーに送信します。このリクエストには、ユーザーID、ターゲット・リソースの名前およびリクエストされた操作が含まれています。
Access SDKを使用して開発されたアクセス・クライアントの場合、SSOトークンが名前なしの文字列型として発行されます。既存のUserSession
オブジェクトに対してgetSessionToken()
を使用すると、そのセッションのトークンが返されます。既存のトークンがある場合は、そのトークンを使用してユーザー・セッション・オブジェクトを構成できます。トークンは暗号化されおり、ユーザーには理解できませんが、内部的には10g形式または11g形式になっています。
アクセス・クライアントはリソースへのアクセス権をユーザーに付与しますが、これはユーザーがリクエストした特定のリソースに対する操作を行う権限がある場合に限られます。
図2-2に示したフローは、認可プロセスのメイン・パスのみを表しています。その後に分岐する次の場合については、通常、サーブレットまたはアプリケーション内の追加コード部分によって処理されます。
リクエストされたリソースが保護されていない場合。
保護されたリソースに関連付けられている認証チャレンジ・メソッドがアプリケーションでサポートされていない場合。
ユーザーが、指定された条件で有効な資格証明を提示できなかった場合。
その他のエラー状態が発生した場合。
特殊な状況や機能を処理するために、開発者がアクセス・クライアントに追加のカスタム・コードを組み込んである場合。
カスタム・アクセス・クライアントを記述する場合、ユーザーをバックチャネル経由で認証できます。
この項で説明する項目は、次のとおりです。
一般的なアクセス・クライアント・アプリケーションの構造は、アクセス・クライアント・セッションの設定に必要な一連のイベントを大まかにミラー化しています。
アクセス・クライアント・アプリケーション構造の概要
必要なライブラリをインクルードまたはインポートします。
リソースを取得します。
認証スキームを取得します。
認証スキームに必要となるユーザー資格証明を収集します。
ユーザー・セッションを作成します。
リソースに対するユーザー認可をチェックします。
クリーン・アップします(Javaは自動ガベージ・コレクションを使用)。
停止します。
HTTPフォーム・ベースのアクセス・クライアントのアプリケーションとプラグインは、すべて図2-3に示すような同じ基本パターンを実行します。
図2-3は、フォーム・ベースのアプリケーションのプロセス・フローを示しています。
プロセスの概要: アクセス・クライアントによるフォーム・ベースのアプリケーションの実行
ライブラリをインポートします。
SDKを初期化します。
ResourceRequest
オブジェクトを作成します。
リクエストされたリソースが保護されているかどうかを判別します。
リソースが保護されていない場合: リソースが保護されていない場合、アクセス・クライアントはDenyOnNotProtected
フラグの値に基づいて、リソースに対するアクセス権を付与または拒否します。デフォルト値はtrue
です。Access Manager 11gエージェントの場合、DenyOnNotProtected
フラグは常にtrue
であり、変更できません。
リクエストされたリソースが保護されている場合: AuthenticationScheme
オブジェクトを作成します。
HTTPフォーム・ベースの認証スキームの場合: ユーザーIDとパスワードを含む構造体を作成し、UserSession
オブジェクトを作成して、ユーザーが認証されるかどうかを判定します。
HTTPフォーム・ベースでない認証スキームの場合: アクセスを拒否して理由を報告し、APIを停止し、プログラムを終了します。
ユーザーが認証された場合: ユーザーが認可されるかどうかを判定します(ステップ10)。
ユーザーが認証されていない場合: アクセスを拒否して理由を報告し、APIを停止し、プログラムを終了します。
ユーザーが認可された場合: アクセスを許可し、APIを停止し、プログラムを終了します。
ユーザーが認可されなかった場合: アクセスを拒否して理由を報告し、APIを停止し、プログラムを終了します。
注意: このテスト・アプリケーション、あるいはその他のいずれかの例を実行する場合、アクセス・システムが正しくインストールおよび設定されていることを確認してください。特に、サンプル・プログラムで必要とされるURLと認証スキームに完全に一致するリソースが保護されるように構成されているかどうかを確認してください。アプリケーション・ドメインの作成およびアプリケーション・ドメインによるリソースの保護の詳細は、『Oracle Fusion Middleware Oracle Access Management管理者ガイド』を参照してください。 |
この例は、簡易アクセス・クライアント・プログラムです。これは、動作中のアクセス・クライアントに必要な最小限のタスクの実装方法を示しています。
OAMサーバーに接続します。
HTTPフォーム・チャレンジ・メソッドを採用した認証スキームを使用してログインします。
HTTP GETリクエストを使用してリソースの認証を確認します。
Access SDK APIの例外を捕捉およびレポートします。
通常、このコール順序は、フォーム・チャレンジ・メソッドを使用するアクセス・クライアントに共通です。フォーム・メソッドのアクセス・クライアント間の主な違いは、認証に必要な資格証明と保護するリソース・タイプです。
JAccessClient.java
の完全なリストは例2-1に示しています。このコードをテキスト・ファイルJAccessClient.java
に一字一句すべてコピーし、Access Manager SDKがインストールされているコンピュータ上でこれを実行できます。
この例の注釈付きバージョンは、第2.2.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(); } }
資格証明を保持する標準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
(userid
とpassword
のみを要求する)、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.2.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.2.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>"); } }
システム入出力および基本機能を実装する標準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
を起動してユーザーの資格証明であるユーザー名とパスワードを戻し、それぞれsUserName
とsPassword
の変数に代入します。
次の文でauthnScheme.isBasic
コールを正しく動作させるには、次のように、ユーザー名とパスワードをユーザーのHTTPリクエストの問合せ文字列内に含める必要があります。
http://host.example.com/resource?username=bob&userpassword=bobspassword
ここで、resource
は、リクエスト先のリソース、bob
はリクエスト元のユーザー、bobspassword
はユーザーのパスワードです。
authnScheme.isFormの追加コード
注意: authnScheme.isBasic のかわりにauthnScheme.isForm を使用する場合は、追加コードを記述して、次のステップを実装する必要があります。 |
元のリクエストを処理して、フォーム・ベースのログインが必要なことを判断します。
ログイン・フォームに関する302リダイレクト・レスポンスを送信し、HTTPセッションに元のリソース情報を保存します。
ユーザー名とパスワードとともにポストされたフォーム・データを処理して、ユーザーを認証します。
HTTPリソースから元のリソースを取得し、そのリソースに関する302リダイレクト・レスポンスを送信します。
元のリクエストをもう1回処理しますが、今回はHTTPセッション内に格納されているUserSession
を使用して処理します。
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);
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.2.3項「サンプル・コード: 簡単なアクセス・クライアント」で説明した、サンプル・アプリケーションJAccessClient.java
で確立されている基本パターンをベースとして構築されており、追加でいくつかのOAMサーバー・メソッドを起動しています。たとえば、セッション・オブジェクトを点検して、現在の認証スキームに関連付けられているポリシー・ルール内にどのアクションおよび名前付きレスポンスが現在構成されているかを確認します。
このデモを実行するには、アプリケーションを実行する前にOAMサーバーによりいくつかのアクションを構成する必要があります。認証アクションおよびユーザー認証の構成の詳細は、『Oracle Fusion Middleware Oracle Access Management管理者ガイド』を参照してください。例2–3には、このサンプル・アプリケーションの完全なリストが記載されています。このコードの注釈付きバージョンは、第2.2.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(); } }
基本ユーティリティ、列挙およびトークン処理機能を実装する標準の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個の必須引数、およびオプションの変数であるconfigDir
、authz-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])をuserid
、password
、type
、method
、url
の変数に代入します。
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
ハッシュテーブルにname
とvalue
を挿入します。
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
構造体のres
とAuthenticationScheme
構造体の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
が空でない場合は、AccessClient
のlocation
パラメータにこの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
オブジェクトres
とAuthenticationScheme
オブジェクトauths
をNULLに設定し、Access SDK APIを切断します。
res = null; auths = null; ac.shutdown(); } }
次のコードの抜粋では、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[] encodecCert = 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 creds = new Hashtable(); // Store the Base 64-encoded under the key "certificate" cred.put("certificate", base64EncodedCert); // Create ResourceResource request object including all information about the // // resource being accessed 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;
この項では、ステータスまたはエラーを示すために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ロギングAPIが使用されます。具体的には、oracle.security.am.asdk
パッケージにAccessLogger
クラスが含まれ、このクラスはAccess SDKログを生成します。
Access SDKログを生成するには、アプリケーションの起動時にログ構成ファイルを指定する必要があります。このログ構成ファイルはアプリケーション実行中のJavaプロパティとして指定しますが、この場合、Javaプロパティ-Djava.util.logging.config.file
はlogging.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>
この項で説明する項目は、次のとおりです。
必要な環境は次のとおりです。
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.1.2項「Access SDKのインストールについて」を参照してください。
開発環境の構成後(第2.4.1項「開発環境の設定」を参照)、次のようなコマンドを使用してアクセス・クライアント・プログラムをコンパイルできます。
Javac –cp <location of Access SDK jar> SampleProgram.java
必要に応じて、CLASSPATH、アクセス・クライアント・プログラム名などの詳細を変更します。CLASSPATHに追加するjarファイルの詳細は、第2.1.2項「Access SDKのインストールについて」を参照してください。
アクセス・クライアントの開発後、テストおよび使用の前に、実際のAccess Manager 11g環境でデプロイする必要があります。この項では、Access SDKを使用して開発されたアクセス・クライアントをデプロイする前に必要な構成手順について説明します。アクセス・クライアントのデプロイメント・プロセスは、その他のAccess Managerエージェントのデプロイメント・プロセスに類似しています。
この項の内容は次のとおりです。
次の概要では、Oracle Access Managementの管理者資格証明を使用してユーザーが実行する必要があるタスクを説明します。アクセス・クライアント・プログラムはすでに開発され、コンパイル済であることが前提です。
Access SDKのjarファイルを取得し、アクセス・クライアントの作成に使用するコンピュータにこれをコピーします。詳細は、第2.1.2項「Access SDKのインストールについて」を参照してください。
保護対象のアプリケーションをホストしているコンピュータにアクセス・クライアントをコピーします。
アクセス・クライアントを構成します。
必要なJava環境があることを確認します。
アクセス・クライアントがスタンドアロン環境にある場合、Java Development Kit (JDK)またはJavaランタイム環境(JRE)を使用できます。アクセス・クライアントがサーブレット・アプリケーションである場合、Java EEまたはJava EEコンテナで使用可能なJava環境を使用できます。
Access SDKのjarファイルがCLASSPATHにあることを確認します。JRF以外の環境を使用している場合は、必要なJPS jarファイルがCLASSPATHにあることを確認します。詳細は、第2.1.2項「Access SDKのインストールについて」を参照してください。
アクセス・クライアントをデプロイするには、『Oracle Fusion Middleware Oracle Access Management管理者ガイド』のコンソールを使用したエージェントおよびアプリケーションの登録に関する項を参照してください。
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をマージする必要があります。
merge-cred.xmlを準備します。このファイルには、ソースのcwallet.sso(エージェント登録アーティファクト)のディレクトリおよび宛先のcwallet.sso(システム・アーティファクト)を指定します。このファイルの内容は、例2-4で定義されている内容と似たものになります。
例2-4 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>
次の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")
次のコマンドを実行して、エージェントの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.3.2項「アクセス・クライアントのアーキテクチャ」および第2.5.3項「必要な構成ファイルの生成」を参照してください。
password.xml
このファイルは、トランスポート・セキュリティ・モードが簡易または証明書である場合のみ必要です。このファイルには、パスワードが暗号化された形式で含まれます。このパスワードは、SSLキー・ファイルの保護に使用されます。
詳細は、第2.5.3項「必要な構成ファイルの生成」を参照してください。
ログ構成
ログ・ファイルを生成するために必要です。詳細は、2.3.3項「ロギング」を参照してください。
ObAccessClient.xml構成ファイルを取得するには、管理コンソールまたはリモート登録ツールを使用して、アクセス・クライアントを10gまたは11gエージェントとしてOAM 11gサーバーに登録します。11gエージェントの登録時には、cwallet.ssoファイルも作成されます。詳細は、『Oracle Fusion Middleware 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リファレンスを参照してください。
11g Access SDKでは、一般に信頼ストアまたはキー・ストアとして知られるデータベースのSSL証明書およびキー・ファイルを使用します。これらのストアはJKS (Java Key Standard)形式である必要があります。
簡易トランスポート・モードでは、OAMサーバーによってJKSキーストアが自動生成されます。生成されたキーストアは、WLS_OAM_DOMAIN_HOME/output/webgate-ssl/に保存されます。
証明書トランスポート・セキュリティ・モードでは、サーバーおよびエージェントの証明書を認証局にリクエストする必要があります。オプションにより、証明書モード証明書を発行する目的で、簡易モードの自己署名証明書を認証局として使用することもできます。
証明書モードを準備するには、次の手順を実行します。
アクセス・クライアントおよびOAMサーバーに対して発行された証明書とキーのペアを使用して、認証局のCA証明書をインポートします。第2.5.4.2.1項「CA証明書のインポート」の手順を実行してください。cacert.pemまたはcacert.derのかわりに、発行局のCA証明書ファイルを使用します。
10g JNI ASDKがインストールされている場合、アクセス・クライアントの証明書およびキー・ファイルを生成できます。これらの証明書はPEM形式となります。
インポートされたCA証明書を使用した証明書の生成方法の詳細は、『Oracle Fusion Middleware Oracle Access Management管理者ガイド』を参照してください。
この証明書とキーのペアをPEM形式でoamclient-keystore.jksにインポートするには、第2.5.4.2.2項「キーストアの設定」の手順を実行します。
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証明書を信頼ストアにインポートします。
テキスト・エディタを使用してcacert.pemまたはcacert.derを編集し、CERTIFICATEブロック内に含まれるデータを除くすべてのデータを削除し、ファイルを保存します。次に例を示します。
-----BEGIN CERTIFICATE----- Content to retain -----END CERTIFICATE-----
次のコマンドを実行し、必要に応じて環境にあわせて変更します。
keytool -importcert -file <ca cert file cacert.pem or cacert.der> -trustcacerts -keystore oamclient-truststore.jks -storetype JKS
プロンプトが表示されたら、キーストアのパスワードを入力します。これは、OAMサーバーで使用されるグローバル・パス・フレーズと同じである必要があります。
アクセス・クライアントのSSL証明書および秘密鍵ファイルをキーストアに追加する必要があります。アクセス・クライアントがOAMサーバーと通信できるように、SSL証明書および秘密鍵ファイルは簡易モードで生成する必要があります。
10g Access SDK: アクセス・クライアントの証明書およびキー・ファイルの生成を提供します。これらの証明書はPEM形式です。
11g OAMサーバー: リモート登録ツールおよび管理コンソールを使用して、アクセス・クライアントの証明書(aaa_cert.pem)およびキー・ファイル(aaa_key.pem)をPEM形式で生成します。
キーストアoamclient-keystore.jksに証明書およびキー・ファイルをインポートするには、次のコマンドを実行します。
テキスト・エディタを使用してaaa_cert.pemを編集し、CERTIFICATEブロック内に含まれるデータを除くすべてのデータを削除し、ファイルを保存します。次に例を示します。
-----BEGIN CERTIFICATE----- Content to retain -----END CERTIFICATE-----
次のコマンドを実行し、必要に応じて環境にあわせて変更します。
openssl pkcs8 -topk8 -nocrypt -in
aaa_key.pem
-inform PEM -out
aaa_key.der
-outform DER
このコマンドにより、パスワードの入力が要求されます。パスワードはグローバル・パス・フレーズである必要があります。
次のコマンドを実行し、必要に応じて環境にあわせて変更します。
openssl x509 -in
aaa_cert.pem
-inform PEM -out
aaa_cert.der
-outform DER
次のコマンドを実行し、必要に応じて環境にあわせて変更します。
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形式の秘密鍵と証明書のペアです。
プロンプトが表示されたら、キーストアのパスワードを入力します。これはグローバル・パス・フレーズと同じである必要があります。
この項で説明する項目は、次のとおりです。
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クラス |
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サーバーではサポートされていません。
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
クラスを使用する操作の実行中にランタイム・エラーを示します。
11g Access SDKは、10g JNI ASDK com.oblix.access
パッケージのインタフェースをサポートします。ただし、com.oblix.access
のすべてのAPIが非推奨としてマークされています。これらのAPIは、将来のAccess Manager 11g Access SDKリリースにおいて拡張もサポートもされません。
開発者はあらゆる新規開発において11g Access SDKを使用することを強くお薦めします。
この項では、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.5項「アクセス・クライアントの構成およびデプロイ」を参照してください。
10g com.oblix.access
パッケージで開発されたアクセス・クライアントおよびプラグインを、11g OAMサーバーで動作するよう移行できます。この項では、10g JNI ASDKで記述されたプログラムを11g OAMサーバーで使用する方法を説明します。
注意: 10g JNI ASDKと11g Access SDKのcom.oblix.access APIにおける類似点と相違点の詳細は、第2.6.2項「10g JNI ASDKと11g Access SDKの互換性」を参照してください。 |
10g JNI ASDKおよび11g Access SDKで提供されているクラスおよびインタフェースのサポートは同じです。
通常、11g Access SDKのcom.oblix.access
クラスを使用するためにアプリケーションを移行する場合、アプリケーション・コードを変更または再コンパイルする必要はありません。
新しいランタイム例外のObAccessRuntimeException
はcom.oblix.access
パッケージに導入されています。この例外は、AuthenticationScheme
クラスおよびResourceRequest
クラスの操作時にスローされます。
アプリケーション・コードで正しい例外処理を実行することをお薦めします。これを実行した場合、アプリケーションを11g Access SDK jarファイルで再コンパイルする必要があります。
この説明では、10g ASDKコンポーネントがインストールされており、OAMサーバーで構成されていることを前提としています。このシナリオでは、10g JNI ASDKを使用して開発された既存のアクセス・クライアント・アプリケーションを使用します。前提は次のとおりです。
第2.5.2項「構成要件」にリストした構成アイテムは、10g ASDKのインストール・ディレクトリ(ASDK_INSTALL_DIR)から参照されます。
ASDK_INSTALL_DIR/access/oblix/libからObAccessClient.xmlが読み取られます。
トランスポート・セキュリティ・モードが簡易または証明書である場合、ASDK_INSTALL_DIR/access/oblix/configからpassword.xmlが読み取られます。
簡易モード
10g ASDKコンポーネントを簡易モードで構成するには、10gリリースのOracle Access Manager管理ガイドを参照してください。
次のステップを実行します。
aaa_cert.pemおよびaaa_key.pemファイルをoamclient-keystore.jksにインポートします。
aaa_cert.pemおよびaaa_key.pemファイルは、ASDK_INSTALL_DIR/access/oblix/config/simpleに置かれています。
簡易モード証明書の発行に使用される自己署名CA証明書を、ASDK_INSTALL_DIR/access/oblix/tools/openssl/simpleCAに置きます。
自己署名CA証明書をoamclient-truststore.jksにインポートします。
第2.5.4項「SSL証明書およびキー・ファイル」の手順を実行し、証明書およびキー・ファイルをJKSストアにインポートします。
JKSストアをASDK_INSTALL_DIR/access/oblix/config/simpleにコピーします。
証明書モード
10g ASDKコンポーネントを証明書モードで構成するには、10gリリースのOracle Access Manager管理ガイドを参照してください。
次のステップを実行します。
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.5.4項「SSL証明書およびキー・ファイル」の手順を実行し、証明書およびキー・ファイルをJKSストアにインポートします。
JKSストアをASDK_INSTALL_DIR/access/oblix/config/simpleにコピーします。
構成ファイルの場所
com.oblix.access
APIを使用するために移行されたアクセス・クライアント・アプリケーションでは、10g JNI ASDK構成ファイルの場所を次のように指定できます。
ASDKの初期化中に、10g ASDKがインストールされているディレクトリの場所を指定します。または、
10g JNI ASDKがインストールされているディレクトリの場所を指す、環境変数OBACCESS_INSTALL_DIRを設定します。
これによって、11g Access SDKは、渡された場所に基づいて必要なファイルのパスを判別します。
環境
環境を設定するには、第2.4.1項「開発環境の設定」の手順を実行します。10g JNI ASDKのファイル名はjobaccess.jarです。jobaccess.jarがCLASSPATHにある場合、削除する必要があります。
この項では、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サーバーの機能を利用する拡張機能も含まれています。
次の表は、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パッケージ |
---|---|
インタフェースの要約:
|
インタフェースの要約: なし |
クラスの要約:
|
クラスの要約:
|
例外の要約: ObAccessException |
例外の要約:
|
列挙の要約: なし |
列挙の要約: 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を使用する方法を説明します。
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
メソッドを使用する場合、AuthenticationScheme
、ResourceRequest
または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
メソッドを使用する場合、AuthenticationScheme
、ResourceRequest
または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-4に示すように、アクセス操作の実行に使用されるクラス間には1対1マッピングがあります。oracle.security.am.asdk
のクラスは、AuthenticationScheme
、ResourceRequest
および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
この項では、様々な問題を回避する方法や、開発中に頻繁に発生する問題を解決するための方法をいくつか説明します。この項で説明する項目は、次のとおりです。
作成したアクセス・クライアントでの問題発生を回避するための提案を次に示します。
アクセス・クライアントが適切なOAMサーバーに接続しようとしているかを確認します。
OAMサーバーについての構成情報とアクセス・クライアントについての構成情報が一致するようにします。管理コンソールを使用して、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ポインタなどのスレッド・セーフ方式の共有ローカル変数は注意して使用してください。
アクセス・クライアントが実行に失敗したかどうかの確認点を次に示します。
OAMサーバーが実行中であることを確認します。Windowsシステムでこれを確認するには、「コンピュータの管理」、「サービス」、「AccessServer」の順にナビゲートします。AccessServerは、アクセス・クライアントを接続するOAMサーバーの名前です。
アクセス・クライアントがユーザー・ログアウトを実行することを確認し、OAMサーバー側のセッションが必ず削除されるようにします。ユーザー・セッションが蓄積すると、ユーザー認証に失敗する可能性があります。
コードが想定しているドメイン・ポリシーが正しく存在し、有効化されていることを確認します。
リリース・ノートの確認
アクセス・システムの低位レベルのポリシーが、検査中のポリシーをオーバーライドして、アクセス・クライアントに応答しないようにします。
11gアクセス・テスターを使用すると、特定のリソースにどのポリシーが適用されるかを確認できます。アクセス・テスターの使用方法およびアプリケーション・ドメインによるリソースの保護の詳細は、『Oracle Fusion Middleware Oracle Access Management管理者ガイド』を参照してください。
この項では、11g Java Access SDKの使用時に発生する可能性のある環境の競合を解消するための情報を提供します。
11g Java Access SDKを使用するWebアプリケーションで、Javaクラス・バージョンの競合を解消するには、次の手順に従ってください。
Access SDKによって使用されるライブラリと異なるバージョンのライブラリが、同じJava EEコンテナにホストされている別のアプリケーションによってロードされると、競合が発生します。表示される可能性のあるエラー・メッセージのサンプルを次に示します。
oracle/security/am/common/aaaclient/ObAAAServiceClient.<init>(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.<init>(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アプリケーションに対してクラス・ローダー・フィルタリングを構成します。詳細と手順は、使用しているアプリケーション・サーバーのドキュメントを参照してください。
システム・クラス・ローダーを使用してロードするかわりに、WebLogic Server FilteringClassLoader
を使用すると、アプリケーションから常にロードされるパッケージを指定できます。
この問題を解決するには、次の手順を実行します。
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で指定されていても、このパッケージに関連付けられたすべてのクラスがアプリケーション・ローダーによってロードされます。
アプリケーションを停止します。
以前デプロイしたバージョンのアプリケーションを削除します。
アプリケーションをインストールします。
リソースにアクセスします。
エラーが解消され、アプリケーションが正常に動作します。
どのアプリケーション・サーバーにも構成ファイルがあり、そのファイルでクラスのロードに関連するオプションが構成されます。一般に、特定のクラス・ローダーで一連のクラスをロードできるようにするために必要な構成ファイルとタグを特定することが鍵となります。
アプリケーション・サーバーの構成ファイルを特定します。
アプリケーション・クラス・ローダーを使用して、クラスがCLASSPATHで指定されていても親クラス・ローダーによってロードされないようにします。
デフォルトのクラスのロード動作を変更して、現在のクラス・ローダーがクラスのロードに失敗した場合にのみ親クラス・ローダーがコールされるようにします。
または、WebLogic Serverのように、指定のクラス・ローダーを使用してクラスをロードできる方法が存在する場合もあります。
アプリケーション・サーバーによっては、アプリケーション用に親ドメインとは別のドメインを定義し、親を最後にロードするようクラスのロード動作を設定する必要がある場合もあります。
高負荷で高ストレスな環境では、11g Access SDKの環境を次のようにチューニングしてください。
ユーザー定義パラメータとしてpoolTimeout
を構成します。poolTimeout
のクライアント数を増やしてください。
最大接続数を調整します。パフォーマンスを向上させるためには、プライマリ・サーバーの最大接続数をエージェント・プロファイルで設定する必要があります。