| Oracle® Fusion Middleware Oracle Access ManagerおよびOracle Security Token Service開発者ガイド 11g リリース1 (11.1.1) B66696-01 |
|
![]() 前 |
![]() 次 |
この章の内容は次のとおりです。
Oracle Access Manager 11g Access SDKは、オラクル社が様々なエンタープライズ・プラットフォーム(32ビットおよび64ビットの両方のモードを使用)およびハードウェアの組合せで認証した、プラットフォーム非依存パッケージです。これは、Oracle Fusion Middlewareアプリケーション間でサポートされているJDKバージョンで提供されています。
oracle.security.am.asdkパッケージでは、Oracle Access Manager 11gバージョンのApplication Program Interface(API)が提供されています。11gバージョンはOracle Access Manager 10g APIによく似ていますが、OAM 11gサーバーで使用するための拡張機能が備わっています。11g Access SDKは、com.oblix.accessインタフェースをサポートすることで下位互換性を提供しています。
|
参照: Oracle Security Token Service Java APIリファレンス |
Oracle Access Manager 10g (10.1.4.3)のcom.oblix.accessパッケージおよびクラスは非推奨です。非推奨APIは、機能改良などの理由から使用が推奨されておらず、通常はそれに代わるAPIが提供されます。非推奨APIは今後の実装で削除される可能性があります。
|
注意: 開発者はあらゆる新規開発においてOracle Access Manager 11g Access SDKを使用することを強くお薦めします。 |
Access SDKのインストール後は、サブディレクトリおよびファイルの相対的な場所を変更しないでください。変更すると、APIが正しくビルドおよび操作できなくなります。
表2-1では、Access SDKパッケージおよびリソースと、それぞれの入手場所を特定しています。
表2-1 場所: Access SDKリソース
| リソースおよび場所 |
|---|
|
バージョンおよびプラットフォームのサポート: Oracle Technology Network
|
|
パッケージのダウンロード: Oracle Technology Network
|
|
Oracle Access Manager 11g Access SDKパッケージ:
|
|
Javaマニュアル:
各メソッドには次の詳細が含まれます。
|
Oracle Access Manager 11g Access SDKは、Javaアプリケーション開発者を対象とし、密結合されている高パフォーマンスの統合の開発を目的としています。
機能的な観点からすると、Oracle Access Manager 11g Access SDKは10g (10.1.4.3) Java Access SDKのパリティを維持しており、新規APIレイヤーを使用して既存のカスタム・コードを記述しなおすことができます。
Oracle Access Manager 11g Access SDKには、認証および認可機能が組み込まれています。ただし、管理APIは組み込まれておらず(たとえば、11gポリシー・マネージャAPIはありません)、Oracle Access Manager 11g Cookieを使用しません。
Access SDKの最も一般的な用途は、Oracle Access Managerとその他のアプリケーション(Oracleまたはサード・パーティ)とのカスタム統合の開発を可能にすることです。使用例を次に示します。
Oracle Access Manager認証プロセスの一部として格納される可能性があるセッション情報へのアクセス。
プリンシパル・ユーザーのHTTPヘッダーを信頼せず、Oracle Access ManagerセッションCookieの有効性を確認。
Access SDKのもう1つの用途としては、Oracleがデフォルトで統合を提供しないWebサーバーまたはアプリケーション・サーバーに対する、カスタム・アクセス・クライアントの開発があります。
表2-2では、Oracle Access Manager 11g Access SDKの主な機能について説明します。
表2-2 Oracle Access Manager 11g Access SDKの機能
| 機能 | 説明 |
|---|---|
|
インストール |
クライアント・パッケージ: 1つのjarファイルで構成されます。サポート・ファイル(署名およびTLSネゴシエーション用)は含まれておらず、個別に生成する必要があります。 サーバー関連コード: コアOracle Access Managerサーバー・インストールの一部として組み込まれています。 注意: Oracle Access Manager 10g (10.1.4.3)で開発されたアクセス・クライアントおよびプラグインは、Oracle Access Manager 11gで使用できます。Oracle Access Manager 10g (10.1.4.3)バンドル・パッチは、Oracle Access Manager 11gで使用するためのJava SDKコード拡張機能を配布する目的で使用します。 |
|
組込みバージョニング |
次のことが可能です。
|
|
ロギング |
Access SDKロギング・メカニズムにより、ローカル・ファイルに表示する詳細のレベル(情報、警告およびエラーの各レベル)を指定できます。メッセージは、問題を解決するための十分な詳細を提供します。たとえば、互換性のないAccess SDKパッケージが使用されている場合、ログ・メッセージには、バージョン不一致に関する詳細と、遵守する必要があるバージョン基準が含まれます。 SDKが指定期間内に大量のログを生成した場合、ファイル制限または期間に基づいてログのロールオーバーを構成できます。たとえば、ファイル制限に達した場合(または一定時間が経過した場合)、ログ・ファイルはアーカイブ・ディレクトリにコピーされ、新規ログ・ファイルが開始されます。 |
|
新規コール |
Access SDKには、Oracle Access Manager 11gの新規アーキテクチャに基づいてセッションに関する追加情報を決定する新規コールが組み込まれています。 注意: Oracle Access Manager 10gのcom.oblix.accessパッケージで開発されたアクセス・クライアントおよびプラグインは、移行してOAM 11gサーバーで動作できます。 |
Access SDKを使用することで、認証、認可および監査など保護されたリソースへのアクセスを制御する目的で、Oracle Access Managerとのカスタム統合を開発できます。通常このアクセス制御を実現するには、Access SDKランタイムとインタフェースするためのAccess Client APIを起動するアプリケーションまたはプラグインであるカスタム・アクセス・クライアントを開発およびデプロイします。
アクセス・クライアント側のキャッシュがAccess SDKランタイム内で内部的に使用され、処理オーバーヘッドがさらに抑えられます。Access SDKランタイムおよびOracle Access Managerサーバーの連携により、動的構成管理が透過的に実行され、それによって、Oracle Access Manager管理コンソールを使用したアクセス・クライアント構成の変更は、対象となるAccess SDKランタイムに自動的に反映されます。
アクセス・クライアントAPIのすべてまたはサブセットを使用することで、目的の機能に応じて、様々なタイプのカスタム・アクセス・クライアントを開発できます。APIは通常、ユーザーとの通信に使用される保護されたリソースおよびネットワーク・プロトコルのタイプは認識しません。たとえば、HTTPプロトコルの詳細およびHTTP Cookieの用途はAccess SDKの範囲外です。非HTTPリソースを保護するアクセス・クライアントは、HTTPリソースを保護するエージェントと同じくらい容易に開発できます。
カスタム・アクセス・クライアント単独で、または他のアクセス・クライアントと組み合せて実行できる一般的な機能は、次のとおりです。
Oracle Access Managerおよびその構成済ユーザー・リポジトリに対する資格証明を検証してユーザーを認証します。
ユーザーを認証し、リソースへのアクセスについて認可の有無をチェックします。
ユーザーを認証し、セッション・トークンで表された一意のOracle Access Managerセッションを作成します。
ユーザーにより提供されたセッション・トークンを検証し、保護されたリソースへのユーザーのアクセス権を認可します。
セッション・トークンまたは名前付きセッション識別子がある場合は、Oracle Access Managerセッションを終了します。
名前付きユーザー識別子を指定し、指定ユーザーのOracle Access Managerセッションを列挙します。
Oracle Access Managerのカスタム・セッション属性を保存または取得します。
アクセス・クライアントの一部の操作は、指定されたアクセス・クライアント・インスタンスによる使用に制限されています。たとえば、Oracle Access Manager Access SDK Java APIリファレンスのOperationNotPermittedに関する項を参照してください。
Oracle Access Manager管理者は、Oracle Access Manager管理コンソールを使用して、個々のアクセス・クライアントの権限を制御できます。詳細は、Oracle Fusion Middleware Oracle Access Manager with Oracle Security Token Service管理者ガイドを参照してください。
この項では、ステータスまたはエラーを示すためにAccess SDKで使用されるメッセージおよび例外について説明します。
Access SDKにより生成される実行ログについても説明します。実行ログは、実行された操作に関する情報を提供します。たとえば、操作ステータス、発生したエラーまたは例外、およびトラブルシューティングに役立つ一般情報があります。
この項で説明する項目は、次のとおりです。
Access SDKは、ステータスまたはエラーの状態を示すローカライズ済メッセージをサポートします。例外としてアプリケーションに提供されるエラー・メッセージもローカライズされます。これらのローカライズ済エラー・メッセージは、Access SDKログ・ファイルに記録されます。
次のタイプの例外は、アプリケーションにエラーの状態を示すために使用されます。
OperationNotPermittedException
Oracle Access Manager 11g Access SDKにより、新しいセッション管理APIのセットが導入されます。権限を持つアクセス・クライアントのみが、これらのセッション管理操作を実行できます。
アクセス・クライアントがこれらの操作の実行を許可されていない場合、Oracle Access Manager 11gサーバーがエラーを返します。サーバーがエラーを返すと、Access SDKがこの例外をスローします。
AccessException
操作の実行中に予期しないリカバリ不能なエラーが発生すると、Oracle Access Manager 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>
この項では、Access SDKを使用して開発されたアクセス・クライアントをデプロイする前に必要な構成ステップについて説明します。詳細は、第2.6.1.2項「アクセス・クライアントのアーキテクチャ」を参照してください。
アクセス・クライアントの開発後、テストおよび使用する前に、現在のOracle Access Manager 11g環境でデプロイする必要があります。アクセス・クライアントのデプロイメント・プロセスは、その他のOracle Access Managerエージェントのデプロイメント・プロセスに類似しています。
次の概要では、Oracle Access Managerの管理者資格証明を使用してユーザーが実行する必要があるタスクを説明します。
|
参照: Oracle Security Token Serviceを伴うOracle Fusion Middleware Oracle Access Manager管理者ガイド |
タスク概要: アクセス・クライアント・コードのデプロイ
アクセス・クライアント・プログラムはすでに開発され、コンパイル済であることが前提です。
Access SDKのjarファイルを取得し、アクセス・クライアントの作成に使用するコンピュータにこれをコピーします。
保護対象のアプリケーションをホストしているコンピュータにアクセス・クライアントをコピーします。
アクセス・クライアントを構成します。
必要なJava環境があることを確認します。
アクセス・クライアントがスタンドアロン環境にある場合、Java Development Kit (JDK)またはJavaランタイム環境(JRE)を使用できます。アクセス・クライアントがサーブレット・アプリケーションである場合、Java EEまたはJava EEコンテナで使用可能なJava環境を使用できます。
Access SDKのjarファイルがクラス・パスにあることを確認します。
Access SDK構成は、次のファイルで構成されます。
構成ファイル(ObAccessClient.xml)
この構成ファイルは、Oracle Access Managerサーバーのホスト、ポートおよびアクセス・クライアントの動作を決定する他の構成アイテムなど、各種詳細が含まれます。たとえば、アイドル・セッション時間などがあります。このファイルの名前はObAccessClient.xmlです。
SSL認証およびキー・ファイル
このファイルは、トランスポート・セキュリティ・モードが簡易または証明書である場合のみ必要です。Oracle Access Manager 10gサーバーおよびOracle Access Manager 11gサーバーのどちらも、エージェントとの通信においてオープン、簡易および証明書のトランスポート・セキュリティ・モードをサポートしています。Access SDKを使用して開発されたアクセス・クライアントは、エージェントと呼ばれます。Oracle Access Managerサーバーが構成されているモードによっては、アクセス・クライアントが同じモードで通信するよう構成されることが必要となります。
トランスポート・セキュリティ・モードが簡易または証明書の場合、次のものが必要です。
アクセス・クライアントの証明書
アクセス・クライアントの秘密鍵
OAMサーバーの証明書を信頼するためのCA証明書
password.xmlファイル
このファイルは、トランスポート・セキュリティ・モードが簡易または証明書である場合のみ必要です。このファイルには、パスワードが暗号化された形式で含まれます。このパスワードは、SSLキー・ファイルの保護に使用されます。
ログ構成
ログ・ファイルを生成するために必要です。
ObAccessClient.xml構成ファイルを取得するには、Oracle Access Manager 11g管理コンソールまたはリモート登録ツールを使用して、アクセス・クライアントをOAM 10gエージェントとしてOAM 11gサーバーに登録します。詳細は、Oracle Fusion Middleware Oracle Access Manager with Oracle Security Token Service管理者ガイドを参照してください。
登録時にトランスポート・セキュリティ・モードが簡易または証明書モードに指定された場合、Oracle Access Manager管理コンソールによって、SSL証明書およびキー・ファイルがPEM形式で作成されます。この後、証明書およびキー・ファイルはoamclient-keystore.jksファイルにインポートできます。証明書およびキーの発行に使用されたCA証明書は、oamclient-truststore.jksにインポートされる必要があります。詳細は、第2.5.3項「SSL証明書およびキー・ファイル」を参照してください。
Oracle Access Manager管理コンソールでは、password.xmlファイルも作成されます。
oracle.security.am.asdk APIで開発されたアクセス・クライアント・アプリケーションは、構成ファイルおよびその他の必要なファイルを取得するための場所を指定できます。このためには、Access SDKを初期化し、構成ファイルが存在するディレクトリの場所を指定します。
構成ファイルの場所をAccess SDKに指定できるオプションの詳細は、Oracle Access Manager Access SDK Java APIリファレンスを参照してください。
Oracle Access Manager 11g Access SDKでは、一般に信頼ストアまたはキー・ストアとして知られるデータベースのSSL証明書およびキー・ファイルを使用します。これらのストアはJKS (Java Key Standard)形式である必要があります。
CA証明書のインポート
CA証明書は信頼ストアにインポートする必要があります。Oracle Access Manager 10g JNI ASDKは、簡易モードで使用できる自己署名付きCA証明書を提供し、アクセス・クライアントに証明書を発行するために使用されます。また、OAM 11gサーバーも自己署名付きCA証明書を提供します。
Oracle Access Manager 10g JNI ASDKでは、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証明書を信頼ストアにインポートします。
テキスト・エディタを使用してca_cert.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証明書および秘密鍵ファイルは簡易モードで生成する必要があります。
Oracle Access Manager 10g JNI ASDKは、アクセス・クライアントの証明書およびキー・ファイルの生成を提供します。これらの証明書はPEM形式です。
OAM 11gサーバーは、アクセス・クライアントの証明書およびキー・ファイルを生成するための、リモート登録および管理コンソールと呼ばれるツールを提供します。これらの証明書もPEM形式です。これらのファイルの名前は、aaa_cert.pemおよびaaa_key.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形式の秘密鍵と証明書のペアです。
プロンプトが表示されたら、キーストアのパスワードを入力します。これはグローバル・パス・フレーズと同じである必要があります。
証明書トランスポート・セキュリティ・モードでは、サーバーおよびエージェントの証明書を認証局にリクエストする必要があります。オプションにより、証明書モード証明書を発行する目的で、簡易モードの自己署名証明書を認証局として使用することもできます。
証明書モードを準備するには、次の手順を実行します。
アクセス・クライアントおよびOAMサーバーに対して発行された証明書とキーのペアを使用して、認証局のCA証明書をインポートします。「CA証明書のインポート」の手順を実行してください。cacert.pemまたはcacert.derのかわりに、発行局のCA証明書ファイルを使用します。
Oracle Access Manager 10g JNI ASDKインストールが使用可能である場合、アクセス・クライアントの証明書およびキー・ファイルを生成できます。これらの証明書はPEM形式となります。
インポートされたCA証明書を使用した証明書の生成方法の詳細は、『Oracle Fusion Middleware Oracle Access Manager with Oracle Security Token Service管理者ガイド』を参照してください。
この証明書とキーのペアをPEM形式でoamclient-keystore.jksにインポートするには、「キーストアの設定」の手順を実行します。
この項で説明する項目は、次のとおりです。
アクセス・クライアントは、OAMサーバーで保護されたLDAPドメイン内のリソースへのユーザーのアクセス・リクエストを処理します。一般的には、リソース・リクエストを受け取るサーブレット(プラグイン)またはスタンドアロン・アプリケーションにカスタム・アクセス・クライアント・コードを埋め込みます。このコードは、Access Manager APIライブラリを使用して、OAMサーバー上での認証および認可サービスを実行します。
リソースが保護されていない場合、アクセス・クライアントはリクエストされたリソースに対する自由なアクセスをユーザーに許可します。リソースが保護されていて、ユーザーがアクセスを得るために特定の資格証明を提示できるように認可されている場合は、アクセス・クライアントがそのユーザー資格証明の取得を試み、OAMサーバーが資格証明を確認できるようにします。ユーザーの認証とリソースへの認可が成功すると、アクセス・クライアントは、ユーザーがリソースを利用できるようにします。
アクセス・クライアントには、表2-3に示すように各種要素に応じてバリエーションがあります。
表2-3 アクセス・クライアントのバリエーション
| バリエーション | 説明 |
|---|---|
|
アプリケーションのタイプ |
スタンドアロン・アプリケーション対サーバー・プラグインです。 |
|
開発言語 |
各開発言語により、APIの基礎となる機能へのインタフェースを選択できます。 Oracle Access Manager 11gでは、Javaはカスタム・アクセス・クライアントの唯一の開発言語です。 |
|
リソース・タイプ |
HTTPおよびHTTP以外の両方のリソースを保護します。 |
|
資格証明の取得 |
他のメソッド間における、HTTPフォーム・ベース入力、セッション・トークンの使用およびコマンドライン入力を有効にします。 |
一般に、Oracle Access Managerによってまだデフォルト・ソリューションが用意されていないリソースへのアクセスを制御する必要がある場合に、標準のWebゲートのかわりに、カスタム・アクセス・クライアントをデプロイします。これには次のような場合が含まれます。
HTTP以外のリソースの保護。
特殊機能を実装するために開発したカスタムWebサーバーの保護(リバース・プロキシなど)。
HTTPとHTTP以外のリソースの組合せを保護するためのシングル・サインオン(SSO)の実装。
たとえば、Oracle WebLogic ServerクラスタおよびOracle WebLogic Server以外のリソースが含まれる企業環境内でのSSOを容易にするアクセス・クライアントを作成できます。
表2-4に示すように、各アクセス・クライアントは3つのタイプのリソースから作成されます。
表2-4 アクセス・クライアントを作成するためのリソース
| リソース | 説明 |
|---|---|
|
カスタム・アクセス・クライアント・コード |
サーブレットまたはスタンドアロン・アプリケーションに組み込まれます。Oracle Access Manager 11gでは、Java言語プラットフォームを使用してアクセス・クライアント・コードを記述します。 |
|
構成情報 |
|
|
Access Manager APIライブラリ |
アクセス・クライアントとOAMサーバーの相互作用を容易にします。 |
図2-1は、ホスト・サーバー上にインストールされるアクセス・クライアントのコンポーネントを示しています。
第2.6.1.2項「アクセス・クライアントのアーキテクチャ」で説明しているリソースのタイプにより生じる多様性にかかわらず、アクセス・クライアントの多くは同じ基本ステップに従ってユーザー・リクエストを処理します。
ユーザーまたはアプリケーションが、アクセス・クライアントがインストールされているサーバー上で動作するサーブレットまたはアプリケーションに対してリソース・リクエストを発行すると、そのサーブレットまたはアプリケーションに埋め込まれたアクセス・クライアント・コードが次の図に示す基本プロセスを開始します。
図2-2は、リソース・リクエストの処理方法を示しています。
プロセスの概要: リソース・リクエストの処理
アクセス・クライアント・コードが埋め込まれているアプリケーションまたはサーブレットが、ユーザーのリソース・リクエストを受け取ります。
アクセス・クライアントにより、ResourceRequest構造体が構成されます。この構造体は、リクエストされたリソースが保護されているかどうかをアクセス・クライアント・コードがOAMサーバーに問い合せるために使用されます。
OAMサーバーが応答します。
状況に応じて、次のいずれかが発生します。
リソースが保護されていない場合、アクセス・クライアントはリソースに対するアクセスをユーザーに許可します。
リソースが保護されている場合、アクセス・クライアントがAuthenticationScheme構造体を構成、使用して、ユーザーがどの資格証明を提示する必要があるかをOAMサーバーに問い合せます。このステップは、アクセス・クライアントでリソース別の認証スキームを使用できる場合にのみ必要です。
OAMサーバーが応答します。
アプリケーションは、フォームまたはその他の手段を使用してユーザー資格証明を要求します。場合によっては、ユーザー資格証明が次の一部としてすでに発行されていることがあります。
有効なセッション・トークン
Webブラウザからの入力
アクセス・クライアント・アプリケーションを起動したコマンドライン・スクリプトの引数またはキーボード入力
ユーザーがアプリケーションに応答します。
アクセス・クライアントによりUserSession構造体が構成され、この構造体を通して、OAMサーバーはユーザー資格証明を取得し、資格証明をOracle Access Managerユーザー・ディレクトリ内のユーザー・プロファイルにマップします。
資格証明が有効と判定されると、アクセス・クライアントがユーザーのセッション・トークンを作成し、認可リクエストをOAMサーバーに送信します。このリクエストには、ユーザーID、ターゲット・リソースの名前およびリクエストされた操作が含まれています。
アクセス・クライアントはリソースへのアクセス権をユーザーに付与しますが、これはユーザーがリクエストした特定のリソースに対する操作を行う権限がある場合に限られます。
(図に対応部分なし)。正常に動作する場合、アクセス・クライアントは、作成したオブジェクトによって使用されているメモリーの割当てを解除して、Access Manager APIを停止します。
「プロセスの概要: リソース・リクエストの処理」で説明しているステップは、認可プロセスの主な経路のみ示しています。その後に分岐する次の場合については、通常、サーブレットまたはアプリケーション内の追加コード部分によって処理されます。
リクエストされたリソースが保護されていない場合。
保護されたリソースに関連付けられている認証チャレンジ・メソッドがアプリケーションでサポートされていない場合。
有効なシングル・サインオンCookie (ObSSOCookie)がユーザーにあり、Cookieに埋め込まれたセッション・トークンが現在でも有効なため、資格証明を再提示しなくてもリソースにアクセスできる場合。ObSSOCookiesおよびシングル・サインオンの詳細は、『Oracle Fusion Middleware Oracle Access Manager with Oracle Security Token Service管理者ガイド』を参照してください。
ユーザーが、指定された条件で有効な資格証明を提示できなかった場合。
その他のエラー状態が発生した場合。
特殊な状況や機能を処理するために、開発者がアクセス・クライアントに追加のカスタム・コードを組み込んである場合。
一般的なアクセス・クライアント・アプリケーションの構造は、アクセス・クライアント・セッションの設定に必要な一連のイベントを大まかにミラー化しています。
アクセス・クライアント・アプリケーション構造セクション
必要なライブラリをインクルードまたはインポートします。
リソースを取得します。
認証スキームを取得します。
認証スキームに必要となるユーザー資格証明を収集します。
ユーザー・セッションを作成します。
リソースに対するユーザー認可をチェックします。
クリーン・アップします(Javaは自動ガベージ・コレクションを使用)。
停止します。
HTTPフォーム・ベースのアクセス・クライアントのアプリケーションとプラグインは、すべて次の図に示すような同じ基本パターンを実行します。図2-3は、フォーム・ベースのアプリケーションのプロセス・フローを示しています。
プロセスの概要: アクセス・クライアントによるフォーム・ベースのアプリケーションの実行
ライブラリをインポートします。
SDKを初期化します。
ResourceRequestオブジェクトを作成します。
リクエストされたリソースが保護されているかどうかを判別します。
リソースが保護されていない場合: アクセスを許可し、APIを停止し、プログラムを終了します。
リクエストされたリソースが保護されている場合: AuthenticationSchemeオブジェクトを作成します。
HTTPフォーム・ベースの認証スキームの場合: ユーザーIDとパスワードを含む構造体を作成し、UserSessionオブジェクトを作成し、ユーザーが認証されるかどうかを判定します。
HTTPフォーム・ベースでない認証スキームの場合: アクセスを拒否して理由を報告し、APIを停止し、プログラムを終了します。
ユーザーが認証された場合: ユーザーが認可されるかどうかを判定します(ステップ10)。
ユーザーが認証されていない場合: アクセスを拒否して理由を報告し、APIを停止し、プログラムを終了します。
ユーザーが認可された場合: アクセスを許可し、APIを停止し、プログラムを終了します。
ユーザーが認可されなかった場合: アクセスを拒否して理由を報告し、APIを停止し、プログラムを終了します。
|
注意: このテスト・アプリケーション、あるいはその他のいずれかの例を実行する場合、アクセス・システムが正しくインストールおよび設定されていることを確認してください。特に、サンプル・プログラムで必要とされるURLと認証スキームに完全に一致するリソースが保護されるように構成されているかどうかを確認してください。アプリケーション・ドメインの作成およびアプリケーション・ドメインによるリソースの保護の詳細は、『Oracle Fusion Middleware Oracle Access Manager with Oracle Security Token Service管理者ガイド』を参照してください。 |
この例は、簡易アクセス・クライアント・プログラムです。ここでは、動作中のアクセス・クライアントに必要な最小限のタスクの実装方法を示しています。
簡易アクセス・クライアントの処理: JAccess Client.java
OAMサーバーに接続します。
HTTPフォーム・チャレンジ・メソッドを採用した認証スキームを使用してログインします。
HTTP GETリクエストを使用してリソースの認証を確認します。
Access SDK APIの例外を捕捉およびレポートします。
通常、このコール順序は、フォーム・チャレンジ・メソッドを使用するアクセス・クライアントに共通です。フォーム・メソッドのアクセス・クライアント間の主な違いは、認証に必要な資格証明と保護するリソース・タイプです。
JAccess Client.javaの完全なリストは例2-1に示しています。このコードをテキスト・ファイルJAccess Client.javaに一字一句すべてコピーし、Access Manager SDKがインストールされているコンピュータ上でこれを実行できます。
第2.6.2.2.1項「注釈付きコード: JAccess Client.java」では、Java Access Manager APIコールに慣れることができるよう、注釈付きコードを1行ずつ示しています。
例2-1 JAccess Client.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 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 Manager with Oracle Security Token Service管理者ガイド』を参照してください。
public static void main(String argv[]) {
メイン・メソッド内のすべての関連するプログラム文をtryという大きなブロック内に配置し、プログラム終了までにすべての例外をこの捕捉用ブロックで捕捉できるようにします。
AccessClient ac = null;
try {
構成ファイルObAccessClient.xmlのディレクトリの場所を指定し、アクセス・クライアント・インスタンスを作成してAccess SDKを初期化します。Access SDKを初期化するための構成場所を指定するには複数の方法があります。詳細は、Oracle Access Manager Access SDK Java APIリファレンスを参照してください。
作成する必要があるのはアクセス・クライアントのインスタンスのみであり、これがAccess SDK APIを初期化します。AccessClient.CompatibilityMode.OAM_10Gは、Oracle Access Managerの10gおよび11gリリースと互換性があるモードで動作するようAccess SDKが初期化されることを示します。
ac = AccessClient.createDefaultInstance(m_configLocation , AccessClient.CompatibilityMode.OAM_10G);
ResourceRequestコンストラクタを次の3つのパラメータとともに使用して、rrqという名前の新規のリソース・リクエスト・オブジェクトを作成します。
ms_protocol: リクエストするリソースのタイプを示します。未指定の場合、デフォルト値はHTTPです。使用可能な値としてEJBもありますが、ここでの例にはこれは使用しません。『Oracle Fusion Middleware Oracle Access Manager with Oracle Security Token Service管理者ガイド』で説明しているように、カスタム・タイプを作成することもできます。
ms_resource: リソース名です。この特定の例でリクエストされたリソース・タイプはHTTPであるため、次のようにリソース名の先頭にホスト名およびポート番号を追加することは有効です。
//Example.com:80/secrets/index.html
ms_method: リソースに対して実行する操作のタイプです。リソース・タイプがHTTPの場合、指定可能な操作はGETとPOSTです。EJBタイプのリソースでは、操作はEXECUTEにかぎります。カスタム・リソース・タイプの場合、リソース・タイプを設定する際に、許可する操作を定義します。リソース・タイプの定義およびアプリケーション・ドメインによるリソースの保護の詳細は、『Oracle Fusion Middleware Oracle Access Manager with Oracle Security Token Service管理者ガイド』を参照してください。
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 Manager with Oracle Security Token Service管理者ガイド』を参照してください。
} 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.6.2.2項「簡易アクセス・クライアントの例: JAccess Client.java」で説明しているように、アクセス・クライアントを定義するAPIコールの基本パターンを実行しています。ただしこの例は、Webサーバーまたはアプリケーション・サーバー内で実行されるJavaサーブレットとして実装されています。アクセス・クライアント・サーブレットは、この環境では、Webアプリケーションのユーザーに対してさらに重要な役割を果すことができます。サーブレットは、セッション・トークンをユーザーのHTTPセッション内に格納することで、ユーザーがシングル・サインオンできるようにします。つまり、最初のリクエストで確立された認証済OAMサーバー・セッション情報は、1回認可確認した後でも破棄されません。格納されたセッション・トークンは、破棄されずに、Beansやその他のサーブレットなどのサーバー側アプリケーション・コンポーネントで利用できるようになり、これらのコンポーネントが同じ資格証明をリクエストするためにユーザーに繰り返し割り込む必要がなくなります。セッション・トークン、ObSSOCookiesおよびシングル・サインオンの構成の詳細は、『Oracle Fusion Middleware Oracle Access Manager with Oracle Security Token Service管理者ガイド』を参照してください。
このサンプル・ログイン・サーブレットは、カスタム・ログイン・ページ上のフォームでuserid/passwordパラメータを受け付け、ユーザーにOracle Access Managerへのログインの機会を提供します。ログインが成功した場合、サーブレットは、セッション・トークンをUserSessionオブジェクト内に格納します。これにより、同じHTTPセッション内の後続のリクエストは認証ステップをバイパスし(後続のリクエストが最初のリクエストと同じ認証スキームを使用する場合)、シングル・サインオンを実現します。
Javaログイン・サーブレットの完全なリストは、例2-2に示しています。このコードは、Webサーバーまたはアプリケーション・サーバーに組み込むプラグインのベースとして使用できます。
第2.6.2.3.1項「注釈付きコード: 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の場所を渡し、アクセス・クライアントをインスタンス化してAccess SDKを初期化できます。アクセス・クライアントの作成の詳細は、Oracle Access Manager Access SDK Java APIリファレンスを参照してください。OAM_10g互換性フラグにより、OAM 10gサーバーおよびOAM 11gサーバーの両方と互換性があるモードでAccess SDKが初期化されました。
初期化に失敗した場合は、そのことを該当のエラー・メッセージとともに報告します。
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.6.2.2項「簡易アクセス・クライアントの例: JAccess Client.java」で説明しているように、次のサンプル・プログラムは、サンプル・アプリケーションJAccess Client.java内で確立されている基本パターンをベースとしてビルドされており、追加でいくつかのOAMサーバー・メソッドを起動しています。たとえば、セッション・オブジェクトを点検して、現在の認証スキームに関連付けられているポリシー・ルール内にどのアクションおよび名前付きレスポンスが現在構成されているかを確認します。
このデモを実行するには、アプリケーションを実行する前にOAMサーバーによりいくつかのアクションを構成する必要があります。認証アクションおよびユーザー認証の構成の詳細は、『Oracle Fusion Middleware Oracle Access Manager with Oracle Security Token Service管理者ガイド』を参照してください。例2–3には、このサンプル・アプリケーションの完全なリストが記載されています。
コードの注釈付きバージョンは、第2.6.2.4.1項「注釈付きコード: access_test_java.java」を参照してください。
例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();
アクセス・クライアント参照を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 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())
Basicの場合は、そのことを報告します。
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;
この項で説明する項目は、次のとおりです。
必要な環境は次のとおりです。
JDK 1.6.0以上をインストールします。
Oracle Access Manager 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
開発環境の構成後(第2.7.1項「開発環境の設定」を参照)、次のようなコマンドを使用してアクセス・クライアント・プログラムをコンパイルできます。
Javac –cp <location of Access SDK jar> SampleProgram.java
必要に応じて、クラスパスおよびアクセス・クライアント・プログラム名などの詳細を変更します。
詳細は、第2.5項「アクセス・クライアントの構成およびデプロイ」を参照してください。
この項で説明する項目は、次のとおりです。
11g Access Manager APIにより、開発者はカスタム・アクセス・クライアント・コードをJavaで記述できますが、これは10g (10.1.4.3) Javaアクセス・クライアントと機能的に同等です。Oracle Access Manager 11gにより、JavaコードはAPIの基礎となるJavaバイナリと通信します。
組込みの自動Javaガベージ・コレクタにより、未使用のオブジェクトのメモリーはガベージ・コレクタが適切と見なした場合に割当て解除されます。ガベージ・コレクタでは、オブジェクトがいつクリーン・アップされるかは保証されませんが、オブジェクトが参照されなくなった場合にすべて破棄され、メモリー・リークが発生しないことが保証されます。
10gおよび11g Access Manager APIの機能は、7つの基本クラスで編成されています。表2-5に、Java言語プラットフォームの対応するクラス名をリストします。
表2-5 比較: 11gおよび10g Access APIクラス
| クラスの用途 | 11g Javaクラス | 10g Javaクラス |
|---|---|---|
|
パラメータを格納するための構造体(リストまたはハッシュテーブル)をサポートする |
Java Development Kitから: java.util.Hashtable、java.util.Dictionaryを拡張 java.util.Set |
java.util.Hashtable、java.util.Dictionaryを拡張(これはCom.Oblix.Accessクラスではありません) |
|
リスト内の反復をサポートする(Javaはハッシュテーブルを列挙) |
Java Development Kitから: java.util.Hashtable、java.util.Dictionaryを拡張 java.util.Set |
java.util.Hashtable、java.util.Dictionaryを拡張(これはCom.Oblix.Accessクラスではありません) |
|
ユーザー認証を処理するための構造体を作成および操作する |
oracle.security.am.asdkのAuthenticationSchemeクラス |
ObAuthenticationSchemeはObAuthenticationSchemeInterfaceを実装する |
|
リソースに対するユーザー・リクエストを処理するための構造体を作成および操作する |
oracle.security.am.asdkのResourceRequestクラス |
ObResourceRequestはObResourceRequestInterfaceを実装する |
|
ユーザー・セッションを処理するための構造体を作成および操作し、ユーザー・セッションは、ユーザー認証とともに開始され、ユーザーがログオフするかセッションがタイムアウトになると終了する |
oracle.security.am.asdkのUserSessionクラス |
ObUserSessionはObUserSessionInterfaceを実装する |
|
アクセス・クライアント構成情報を取得および変更する |
oracle.security.am.asdkのAccessClientクラス |
ObConfig |
|
Access Manager APIによってスローされるエラーを処理する |
oracle.security.am.asdkのAccessException、OperationNotPermittedException |
ObAccessException |
Access SDKは、10g JNI ASDKでサポートされている機能を実装しています。この機能は、これを使用してOracle Access Manager 10gサーバーおよびOracle Access Manager 11gサーバーの両方とシームレスに連携するカスタム・アクセス・ゲートを開発できるように実装されています。
また、Access SDKには、Oracle Access Manager 11gサーバーでのみ使用できる新機能および変更された機能が実装されています。したがって、Access SDKではアプリケーションがOracle Access Manager 10gサーバーでこの機能の使用を試みるかどうかを正常に検出できます。
Oracle Access Manager 11g Access SDK(oracle.security.am.asdk)の新機能は、次のとおりです。
指定されたユーザーのセッションの列挙
指定されたセッションの終了
指定されたユーザー・セッションでの属性の設定
指定されたセッションで設定された属性の取得
セッションを確立せずにユーザー資格証明を検証
セッションを確立せずにユーザー資格証明を検証し、同じリクエストで認可を実行
|
注意: 最後の2つの機能は、Oracle Access Manager 11g Access SDKのcom.oblix.accessパッケージでも提供されています。 |
さらに、Access SDKはサーバー側のセッションを削除するユーザー・ログアウト機能の変更済実装を提供します。この機能は、Oracle Access Manager 10gサーバーではサポートされていません。
次の図は、Oracle Access Manager 10g JNIバージョンおよびOracle Access Manager 11g Access SDKバージョンのcom.oblix.accessパッケージの1対1マッピングを示しています。
10g JNI ASDKを使用して開発されたカスタム・アクセス・ゲートは、コードの変更なしで引き続き11g Access SDKで動作できます。
図2-4に示すように、次のクラスがOracle Access Manager 11g Access SDKのcom.oblix.accessパッケージに追加されています。
ObPseudoUserSession: このクラスは、Oracle Access Manager 11gサーバーでのみ使用できる次の機能を提供します。
セッションを確立せずにユーザー資格証明を検証します。
セッションを確立せずにユーザー資格証明を検証し、同じリクエストで認可を実行します。
ObAccessRuntimeException: このクラスは、ObAuthenticationSchemeクラスおよびObResourceRequestクラスを使用する操作の実行中にランタイム・エラーを示します。
Access SDKは、10g JNI ASDK com.oblix.accessパッケージのインタフェースをサポートします。ただし、com.oblix.accessのすべてのAPIが非推奨としてマークされています。これらのAPIは、将来のOracle Access Manager 11g Access SDKリリースにおいて拡張もサポートもされません。
この項では、Access SDKを使用する場合に実行する移行プロセスを説明します。次の理由から、Access SDKへの移行が必要となる場合があります。
アプリケーションを移行することで、これらのアプリケーションにおけるAccess SDKの使用方法を変更せずに、Oracle Access Manager 10g JNI ASDKのcom.oblix.access APIを、Oracle Access Manager 11g Access SDKの対応するAPIと置き換えます。
アプリケーション・コードを移行することで、com.oblix.accessのかわりにoracle.security.am.asdk APIを使用するようにしますが、これは下位互換性のためにOracle Access Manager 11g Access SDKでサポートされています。
この項には次のトピックが含まれます:
アプリケーションを移行する前に、開発環境が構成されていることを確認します。また、Oracle Access Manager 11g Access SDKが正しく構成されていることを確認します。詳細は、第2.5項「アクセス・クライアントの構成およびデプロイ」を参照してください。
Oracle Access Manager 10gのcom.oblix.accessパッケージで開発されたアクセス・クライアントおよびプラグインは、OAM 11gサーバーで動作するよう移行できます。この項では、Oracle Access Manager 10g JNI ASDKで記述されたプログラムをOracle Access Manager 11gで使用する方法を説明します。
|
注意: Oracle Access Manager 10g JNIおよびOracle Access Manager 11g Access SDKのそれぞれにおけるcom.oblix.access APIの類似点と相違点の詳細は、第2.8.2項「10g JNI ASDKおよび11g Access SDKの互換性」を参照してください。 |
Oracle Access Manager 10g JNI SDKおよびOracle Access Manager 11g Access SDKで提供されているクラスおよびインタフェースのサポートは同じです。
通常、Oracle Access Manager 11g Access SDKのcom.oblix.accessクラスを使用するためにアプリケーションを移行する場合、アプリケーション・コードを変更または再コンパイルする必要はありません。
新しいランタイム例外のObAccessRuntimeExceptionはcom.oblix.accessパッケージに導入されています。Oracle Access Managerは、AuthenticationSchemeクラスおよびResourceRequestクラスの操作の実行時にこの例外をスローします。
アプリケーション・コードで正しい例外処理を実行することをお薦めします。これを実行した場合、アプリケーションはOAM 11g Access SDK jarファイルで再コンパイルする必要があります。
この説明では、Oracle Access Manager 10g ASDKコンポーネントがインストールされており、OAMサーバーで構成されていることを前提としています。このシナリオでは、Oracle Access Manager 10g JNI ASDKを使用して開発された既存のアクセス・クライアント・アプリケーションを使用します。前提は次のとおりです。
第2.5.1項「構成要件」にリストした構成アイテムは、Oracle Access Manager 10g ASDKのインストール・ディレクトリ(ASDK_INSTALL_DIR)から参照されます。
ASDK_INSTALL_DIR/access/oblix/libからObAccessClient.xmlが読み取られます。
トランスポート・セキュリティ・モードが簡易または証明書である場合、ASDK_INSTALL_DIR/access/oblix/configからpassword.xmlが読み取られます。
簡易モード
Oracle Access Manager 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.3項「SSL証明書およびキー・ファイル」の手順を実行し、証明書およびキー・ファイルをJKSストアにインポートします。
JKSストアをASDK_INSTALL_DIR/access/oblix/config/simpleにコピーします。
証明書モード
Oracle Access Manager 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.3項「SSL証明書およびキー・ファイル」の手順を実行し、証明書およびキー・ファイルをJKSストアにインポートします。
JKSストアをASDK_INSTALL_DIR/access/oblix/config/simpleにコピーします。
構成ファイルの場所
com.oblix.access APIを使用するために移行されたアクセス・クライアント・アプリケーションは、Oracle Access Manager 10g JNI ASDK構成ファイルの場所を次のように指定できます。
ASDKの初期化中に、Oracle Access Manager 10g ASDKがインストールされているディレクトリの場所を指定します。または、
Oracle Access Manager 10g JNI ASDKがインストールされているディレクトリの場所を指す、環境変数OBACCESS_INSTALL_DIRを設定します。
これによって、Oracle Access Manager 11g Access SDKは、渡された場所に基づいて必要なファイルのパスを判別します。
環境
環境を設定するには、第2.7.1項「開発環境の設定」の手順を実行します。Oracle Access Manager 10g JNI ASDKは、jobaccess.jarという名前です。jobaccess.jarがCLASSPATHにある場合、削除する必要があります。
この項では、Oracle Access Manager 10g JNI ASDKで記述されたプログラムをOracle Access Manager 11gで使用する方法を説明します。
11g 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パッケージにも、OAM 11gサーバーの機能を利用する拡張機能が含まれます。
次の表では、Oracle Access Manager 10g JNI SDKのcom.oblix.accessパッケージのAPIと、Oracle Access Manager 11g Access SDKのoracle.security.am.asdkパッケージのAPIを比較しています。また、この表では必要に応じて、Oracle Access Manager 10g ASDKおよびOracle Access Manager 11g Access SDKのクラスをマップしています。
表2-6 JNI ASDK com.oblix.accessパッケージおよびAccess SDK oracle.security.am.asdkパッケージの相違点
| JNI ASDK com.oblix.accessパッケージ | Access SDK oracle.security.am.asdkパッケージ |
|---|---|
|
インタフェースの要約:
|
インタフェースの要約: なし |
|
クラスの要約:
|
クラスの要約:
|
|
例外の要約: ObAccessException |
例外の要約:
|
|
列挙の要約: なし |
列挙の要約: AccessClient.CompatibilityMode.OAM_10G |
Oracle Access Manager 11g Access SDKには、Oracle Access Manager 10g JNI SDK APIに機能的に類似した新規のAPIセットが含まれますが、インタフェースが新しくなっているので注意してください。
Oracle Access Manager 10g JNI ASDKを使用して実装されたアプリケーション・コードを移行して、Oracle Access Manager 11g Access SDKの機能を実現できます。この項では、Oracle Access Manager 11g Access SDKで新規APIを使用するために、既存のアプリケーション・コードを変更する方法を説明します。
Oracle Access Manager 10g JNI SDKでは、com.oblix.access.ObConfigクラスがASDKの初期化および非初期化を実行する機能を提供します。Oracle Access Manager 11g Access SDKでは、oracle.security.am.asdk.AccessClientがこの機能を提供します。
Oracle Access Manager 10g JNI SDKと同様に、アクセス・クライアント・アプリケーション・インスタンスは指定された構成で動作できます。
要件に応じて、AccessClientクラスを次の2通りに使用できます。
createDefaultInstance静的関数を使用して、AccessClientクラスの単一インスタンスを作成できます。このクラスのデフォルト・インスタンスは1つのみ使用できます。アクセス・クライアント・アプリケーションの単一インスタンス内でこのメソッドを複数回起動すると、例外が発生します。
createDefaultInstanceメソッドを使用する場合、AuthenticationScheme、ResourceRequestまたはUserSessionクラスをインスタンス化する際に、このメソッドを使用して取得されたAccessClientクラス・インスタンスを使用する必要があります。
createInstance静的関数を使用して、指定の構成で初期化された新規のAccessClientクラス・インスタンスを作成できます。このクラスは、アクセス・クライアント・アプリケーションの同じ実行中インスタンス内にある場合に必要であり、アプリケーションは様々なOracle Access Managerシステムまたは構成で動作する必要があります。各AccessClientクラス・インスタンスは、アクセス・クライアント・インスタンスの構成時に適切なログ出力名を渡すことで、メッセージを別のログ・ファイルに記録できます。
AccessClientオブジェクトを初期化する際には、AccessClient.CompatibilityMode.OAM_10Gを互換モードで渡す必要があります。
createInstanceメソッドを使用する場合、AuthenticationScheme、ResourceRequestまたはUserSessionクラスをインスタンス化する際に、このメソッドを使用して取得されたAccessClientクラス・インスタンスを使用する必要があります。
アプリケーションの停止時に、AccessClientクラスのshutdownメソッドを起動して、次の例に示すように非初期化を実行します。
Oracle Access Manager 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
Oracle Access Manager 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 Access Manager Access SDK Java API Reference
または
AccessClient.createInstance(“”,AccessClient.CompatibilityMode.OAM_10G); // Refer to Oracle Access Manager Access SDK Java API Reference
………..
}catch (AccessException e){
}
ac.shutdown();
}//main ends here
表2-6に示すように、アクセス操作の実行に使用されるクラス間には1対1マッピングがあります。oracle.security.am.asdkのクラスは、AuthenticationScheme、ResourceRequestおよびUserSessionです。
AccessClientクラスのインスタンス化の方法に応じて、これらのクラスの対応するコンストラクタを使用します。
Oracle Access Manager 10g JNI ASDKと同様に、初期化時またはアクセス操作の実行中に発生したエラーは例外として報告されます。AccessExceptionは、次の例に示すように、Oracle Access Manager 11g Access SDKで使用される例外クラスです。
Oracle Access Manager 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
Oracle Access Manager 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サーバーについての構成情報とアクセス・クライアントについての構成情報が一致するようにします。Oracle Access Suiteを使用して、OAMサーバー上のアクセス・クライアントの構成情報を確認できます。詳細は、『Oracle Fusion Middleware Oracle Access Manager with Oracle Security Token Service管理者ガイド』のアクセス・クライアントの登録に関する項を参照してください。
OAMサーバーとの接続や切断をきれいに行うには、AccessClientクラスのinitializeメソッドおよびshutdownメソッドを使用します。
環境変数OBACCESS_INSTALL_DIRをWindowsまたはUNIXのようなホスト・コンピュータ上で設定し、アクセス・クライアントをコンパイルおよびリンクできるようにする必要があります。一般的に、この変数は、アクセス・クライアントを実行する場合にも必ず設定しておく必要があります。
開発中に問題を捕捉したり報告するには、カスタム・アクセス・クライアント・コードの作成に使用した言語の例外処理機能(try、throwおよびcatch)を使用します。
アクセス・クライアントは、マルチスレッド・アプリケーション全体でただ1つのスレッドとなります。
そうした環境でも安全に操作できるよう、開発者は次のガイドラインを順守することをお薦めします。
シングル・スレッド関数ではなく、スレッド・セーフ関数を使用します。たとえば、localtimeでなくlocaltime_rを使用します。
マルチスレッド機能がサポートされるよう、適切なビルド環境とコンパイラ・フラグを指定します。たとえば、-D_REENTRANTを使用します。また、UNIX型プラットフォームでは-mt、Windowsプラットフォームでは/MDを使用します。
FILEポインタなどのスレッド・セーフ方式の共有ローカル変数は注意して使用してください。
アクセス・クライアントがAccess SDKのcom.oblix.access APIを使用して開発された場合、環境変数OBACCESS_INSTALL_DIRをWindowsまたはUNIXのようなホスト・コンピュータ上で設定し、アクセス・クライアントをコンパイルおよびリンクできるようにする必要があります。一般的に、この変数は、アクセス・クライアントを実行する場合にも必ず設定しておく必要があります。アクセス・クライアントがAccess SDKのoracle.security.am.asdk APIを使用して開発された場合、環境が正しく設定されていることを確認します。Oracle Access Manager Access SDK Java APIリファレンスのAccessClientクラスに関する項を参照してください。
アクセス・クライアントが実行に失敗したかどうかの確認点を次に示します。
OAMサーバーが実行中であることを確認します。Windowsシステムでこれを確認するには、「コンピュータの管理」、「サービス」、「AccessServer」の順にナビゲートします。AccessServerは、アクセス・クライアントを接続するOAMサーバーの名前です。
アクセス・クライアントがユーザー・ログアウトを実行することを確認し、OAMサーバー側のセッションが必ず削除されるようにします。ユーザー・セッションが蓄積すると、ユーザー認証に失敗する可能性があります。
コードが想定しているドメイン・ポリシーが正しく存在し、アクセス・システムで有効化されていることを確認します。
作業しているアクセス・システム製品に付属のリリース・ノートをお読みください。
アクセス・システムの低位レベルのポリシーが、検査中のポリシーをオーバーライドして、アクセス・クライアントに応答しないようにします。
Oracle Access Manager 11gアクセス・テスターを使用すると、特定のリソースにどのポリシーが適用されるかを確認できます。アクセス・テスターの使用およびアプリケーション・ドメインによるリソースの保護の詳細は、『Oracle Fusion Middleware Oracle Access Manager with Oracle Security Token Service管理者ガイド』を参照してください。