ヘッダーをスキップ
Oracle® Fusion Middlewareアプリケーション・セキュリティ・ガイド
11gリリース1(11.1.1)
B56235-07
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

19 アプリケーション・セキュリティのOPSSとの統合

この章では、ドメイン内およびドメイン間のアイデンティティの伝播を含むセキュリティ関連のユースケース、およびADFアプリケーション・セキュリティの一般的なライフ・サイクルについて説明します。また、このガイドの他の章に掲載されているコードおよび構成例もリストします。

この章は次の項で構成されています:

19.1 概要

この章の情報の対象読者は、開発者、セキュリティ設計者およびセキュリティ管理者です。情報は、このガイドのほとんどの項のように機能ごとではなく、ユースケースごとにまとめられています。アプリケーション・セキュリティの一般的な課題を解決するいくつかのユースケースが、特定のアプリケーション・セキュリティ要件を解決するための出発点として紹介されています。ユースケースには、宣言的なアプローチを使用する(アプリケーション・コードの変更を必要としない)ものと、プログラム的アプローチを使用するもの、さらに両方のアプローチを必要とするものがあります。

セキュリティ設計者や開発者が直面する主要なセキュリティ上の課題には、ユーザーの管理、ユーザー・パスワードの管理およびリソースへのアクセスの管理などがあります。OPSSは、次の機能をサポートすることでこれらの課題に対する解決策を提供するセキュリティ・サービス・スイートです。

図19-1は、アプリケーションがセキュリティ・ストアにアクセスする方法、およびこれらのストアを管理するためのツールを示します。

図19-1 アプリケーション、セキュリティ・ストアおよび管理ツール

図19-1については図の前後の説明を参照してください。

関連ドキュメントへのリンク

次の項目については、他の章で説明しています。

OPSS APIのリストについては、付録H「リファレンス」を参照してください。

19.2 セキュリティ統合ユースケース

この項では、次の主なセキュリティ機能またはセキュリティ・アーティファクトに基づいて分類したいくつかのユースケースを紹介します。

各ユースケースには、解決を試みる問題の簡単な説明、必要なセキュリティ・アーティファクト、関連する機能、およびその問題を解決するための詳細情報へのリンクが含まれます。特に明記しないかぎり、すべての説明はOracle WebLogic Application ServerおよびWebSphere Application Serverに当てはまります。

19.2.1 認証

認証ユースケースは次のとおりです。

19.2.1.1 認証されたユーザーが必要なJava EEアプリケーション

あるJava EEアプリケーションにアクセスするために、ユーザーはアイデンティティ・ストアに対して認証される必要があります。アイデンティティ・ストアは次のいずれかになります。

  • 単一のLDAPベースのストア

  • 同じ種類(たとえば、すべてOID)の複数のLDAPベースのストア

  • 異なる種類の複数のLDAPベースのストア (具体的には、1つがAD LDAP、もう1つがOID LDAPの2つのLDAPベースのストア)

  • 単一のDBベースのストア

  • 複数のLDAPベースおよびDBベースのストア

このユースケースでは、次のことが求められます。

  • アプリケーションへのアクセスを認証されたユーザーにのみ許可する

  • 顧客が別のリポジトリでユーザー・アイデンティティを管理している場合でも、アプリケーション・コードは変更しない

このユースケースでは、次の機能を使用します。

  • WebLogicコンテナへのアプリケーションのデプロイ

  • 特定のユーザー・リポジトリのセットに基づいた適切な認証プロバイダの構成

  • LDAPタイプが混在するかLDAPとDBタイプが混在する場合は、OVD認証プロバイダの構成

使用されているリポジトリに基づき、このユースケースの詳細は、次のシナリオに分かれます。

  • 単一のユーザー・リポジトリ - WebLogicコンソールで適切な認証プロバイダを構成します。

  • 複数のユーザー・リポジトリ(同じまたは異なる種類のLDAPにまたがる分割プロファイル) - OVD認証プロバイダを構成します。

  • DBベースのリポジトリ - OVD認証プロバイダを構成します。

詳細は、第3.2.2項「WebLogic認証プロバイダ」を参照してください。

19.2.1.2 プログラム認証が必要なJava EEアプリケーション

デプロイメント・ディスクリプタを使用しないあるJava EEアプリケーションは、構成済のアイデンティティ・ストアに対してユーザーをプログラム的に認証する必要があります。これは、Oracle WebLogic Application ServerにデプロイされたJava EEアプリケーションにのみ当てはまります。

このユースケースでは、ユーザーを認証するためにOPSSパブリックAPIを使用する必要があり、次の機能を使用します。

  • Java EEコンテナに対する認証プロバイダの構成

  • ユーザーを認証するためのLoginService APIの使用

このユースケースの詳細は、第21.1項「Java EEアプリケーションの認証トピックへのリンク」を参照してください。

19.2.1.3 認証が必要なJava SEアプリケーション

あるJava SEアプリケーションは、ドメイン内で使用されているLDAPアイデンティティ・ストアに対してユーザーを認証する必要があります。ドメインのアイデンティティ・ストアの詳細にかかわらず、認証をリクエストするアプリケーション・コードは同じでなければなりません。

このユースケースでは、認証に使用されるアイデンティティ・ストアを構成し、LoginServiceを使用する必要があります。Java SEアプリケーションでは、1つのidログイン・モジュールしか使用できないことに注意してください。

このユースケースの詳細は、第22.3.4項「Java SEアプリケーションでのOPSS API LoginServiceの使用方法」を参照してください。

19.2.2 アイデンティティ

アイデンティティ・ユースケースは次のとおりです。

19.2.2.1 2つの環境で実行されるアプリケーション

あるアプリケーションが2つの異なる環境で実行されており、LDAPベースのストアに格納されている、ユーザーの電子メール・アドレスなどのユーザー・プロファイル情報にアクセスする必要があります。LDAPサーバーのタイプはサポートされているタイプならどれでもかまわず、そのタイプは環境ごとに異なる場合があります。サポートされるタイプの詳細は、第4.1項「サポートされているファイルベース、LDAPベースおよびDBベースのサービス」を参照してください。

さらに具体的には、このユースケースでは次のことを前提としています。

  • アプリケーションはUserProfile.getEmail()メソッドを使用します。

  • 1つ目の環境にはAD LDAPがあり、次のように構成されています。

    mail.attr = msad_email
    
  • 2つ目の環境にはOID LDAPがあり、次のように構成されています。

    mail.attr = mail
    

コードを変更せず、また実行される環境(1つ目または2つ目)にかかわらず、アプリケーションが正しい情報を取得するには、各環境内でアイデンティティ・ストア・プロバイダが適切なプロパティで構成される必要があります。

1つ目の環境(AD LDAP)では、アイデンティティ・ストア・プロバイダには次のプロパティが設定されます。

<property name="mail.attr" value="msad_mail">

2つ目の環境(OID LDAP)では、アイデンティティ・ストア・プロバイダには次のプロパティが設定されます。

<property name="mail.attr" value="mail"

このユースケースの詳細は、第7.2項「アイデンティティ・ストア・プロバイダの構成」を参照してください。

19.2.2.2 複数のストア内のユーザー・プロファイルにアクセスするアプリケーション

あるアプリケーションは、複数のLDAPベースのストアに格納されたユーザー・プロファイル情報にアクセスする必要があります。

このユースケースでは、複数のLDAPベースのストアに対する環境を構成する必要があります。

詳細は、次の各項を参照してください。

19.2.3 認可

認可ユースケースは次のとおりです。

19.2.3.1 特定のロールのみアクセス可能なJava EEアプリケーション

あるJava EEアプリケーションには、Webディスクリプタで特定のロールが割り当てられたユーザーのみがアクセスできる必要があります。グループからロールへの割当ては、顧客の環境に応じて、デプロイメントで構成可能でなければなりません。

このユースケースの詳細は、『Oracle Fusion Middleware Oracle WebLogic Serverセキュリティのプログラミング』のWebアプリケーションでの宣言によるセキュリティの使用に関する項およびEJBでの宣言によるセキュリティの使用に関する項を参照してください。

19.2.3.2 ファイングレイン認可が必要なADFアプリケーション

コンテナ内のあるADFアプリケーションには、Webアプリケーション内のページ上の個々のコントロール・レベルでのファイングレイン認可が必要です。認可チェックはアプリケーションで開始されますが、ポリシーは外部化し、アプリケーションのデプロイメント後に顧客ごとにカスタマイズ可能である必要があります。

Oracle ADFアプリケーションの開発および保護の詳細は、Oracle Fusion Middleware Oracle Application Development Framework Fusion開発者ガイドの第30章「Fusion WebアプリケーションのADFセキュリティの導入」を参照してください。

ADFアプリケーションの一般情報については、第1.5.2項「シナリオ2: Oracle ADFアプリケーションの保護」を参照してください。

ADFアプリケーションのライフ・サイクルの詳細は、「付録 - ADFアプリケーションのセキュリティ・ライフ・サイクル」を参照してください。

19.2.3.3 Webサービスを保護するWebアプリケーション

あるWebアプリケーションは、ファイングレイン・ポリシーを使用してWebサービスを保護する必要があります。

Webサービスのセキュリティ管理の詳細は、Oracle Fusion Middleware Webサービスのためのセキュリティおよび管理者ガイドを参照してください。

19.2.3.4 コードベースのパーミッションが必要なJava EEアプリケーション

あるJava EEアプリケーションには、特定のアクションを実行するためにコードベースのパーミッションが必要です。アクションの代表的な例としては、資格証明ストアから資格証明を読み取る、またはポリシー・ストアでポリシーを検索するなどがあります。

Fusion Middleware Controlでのコードベース・ポリシーの作成の詳細は、第9.2.3項「システム・ポリシーの管理」を参照してください。

19.2.3.5 ファイングレイン認可が必要な非ADFアプリケーション

ある非ADFアプリケーションは、ファイングレイン認可チェックを使用して保護する必要があります。

このユースケースでは、次のことが求められます。

  • アプリケーション・コード内の適切な箇所へのチェックの配置

  • 適切なポリシーの構成

詳細は、第20.3項「JAAS/OPSS認可モデル」を参照してください。

19.2.4 資格証明

資格証明ユースケースは次のとおりです。

19.2.4.1 システムへのアクセスに資格証明が必要なアプリケーション

あるアプリケーションには、データベースまたはLDAPサーバーなどのバックエンド・システムに接続するために資格証明が必要です。アプリケーション・コードは、デプロイメント後にアプリケーション・コードを変更することなく顧客ごとに資格証明の詳細が変更可能になるよう、この資格証明を参照する必要があります。さらにこのユースケースでは、資格証明ストアにアクセスできるユーザー、および認可されたユーザーが資格証明ストアで実行できる操作を指定する必要もあります。

このユースケースでは、次の機能を使用します。

  • 資格証明を永続化するための資格証明ストアの使用

  • アプリケーション・コード内のCSF APIによる実行時の資格証明のフェッチ

  • コードベース上でのシステム・ポリシーの定義と施行

詳細は、次の各項を参照してください。

19.2.5 監査

監査ユースケースは次のとおりです。

19.2.5.1 セキュリティ関連アクティビティの監査

あるアプリケーションは、複数のセキュリティ領域でセキュリティ関連アクティビティを記録する必要があります。具体的には、次の情報を記録する必要があります。

  • ポリシーへの変更: 何がいつ変更されたか

  • 特定の時間間隔内に評価されたポリシー

  • 資格証明またはキーへの変更: 何がいつ変更されたか

このユースケースで説明する設定は、ドメイン内のすべてのアプリケーションおよびコンポーネントに当てはまります。

このユースケースでは、監査可能なアプリケーションが次の条件を満たしている必要があります。

  • 共通監査フレームワーク(CAF)に統合される

  • セキュリティ・アクティビティを記録する機能が組み込まれている

  • 特定のセキュリティ領域でアクティビティを取得するための適切な監査フィルタ・レベルが設定されている

このユースケースでは、次の機能を使用します。

  • 共通監査フレームワークへの統合

  • アプリケーションがセキュリティ領域内で独自の監査カテゴリおよびイベントを定義することを可能にし、アプリケーションを監査対応にする

  • アプリケーションでの適切なフィルタ・レベルの設定を可能にする

詳細は、次の各項を参照してください。

19.2.5.2 ビジネス関連アクティビティの監査

アプリケーションは、機能フローのコンテキストでビジネス関連アクティビティを記録する必要があります。具体的には、ユーザーおよびそのユーザーにより特定の間隔で実行されるビジネス・アクションのロギングを行う必要があります。

このユースケースで説明する設定は、ドメイン内のすべてのアプリケーションおよびコンポーネントに当てはまります。

このユースケースでは、アプリケーションが次の操作を行う必要があります。

  • ビジネス・ニーズに基づいて独自の監査イベントを作成する

  • データ・リポジトリを監査するための実行時属性とともにビジネス・アクティビティを記録する

  • 監査イベントから監査レポートを生成する

  • 実行時監査ポリシーを管理する

  • 必要に応じて監査イベント定義を変更する

このユースケースでは、次の機能を使用します。

  • アプリケーションがビジネス機能領域(監査カテゴリとして)、ビジネス・アクティビティ(カテゴリ内の監査イベントとして)、および各カテゴリ内に属性を定義することを可能にする

  • デプロイメント時のアプリケーションの登録、監査定義の更新、デプロイメント後のアプリケーションの登録解除

  • Fusion Middleware ControlまたはWSLTスクリプトを使用した監査アーティファクトの管理

詳細は、次の各項を参照してください。

19.2.6 アイデンティティ伝播

アイデンティティ伝播ユースケースは次のとおりです。

19.2.6.1 実行ユーザー・アイデンティティの伝播

コンテナ内のあるクライアント・アプリケーションは、SOAPを介してWebサービスに実行ユーザー・アイデンティティを伝播する必要があります。Webサービスは、同じドメイン内または別のドメイン内の別の管理対象サーバー上で実行されています。

このユースケースでは、現在の実行ユーザー・アイデンティティをSOAPを介してWebサービスに伝播する必要があります。

このユースケースを実現するために、主にOracle Web Services Manager (OWSM)の機能を使用します。

OWSMの詳細は、『Oracle Fusion Middleware Webサービスのためのセキュリティおよび管理者ガイド』の第4章「Oracle Fusion MiddlewareにおけるOracle WSMの再設計の詳細」を参照してください。

SOAPを介したアイデンティティの伝播の詳細は、『Oracle Fusion Middleware Webサービスのためのセキュリティおよび管理者ガイド』の第11章「ポリシーの構成」を参照してください。

19.2.6.2 ユーザー・アイデンティティの伝播

コンテナ内のあるクライアント・アプリケーションは、SOAPを介してWebサービスにユーザー・アイデンティティ(実行ユーザー・アイデンティティではない)を伝播する必要があります。伝播するアイデンティティはOPSSセキュリティ・ストアに格納されています。

このユースケースでは、現在の実行ユーザーとは別のユーザーのアイデンティティを、SOAPを介してWebサービスに伝播する必要があります。

このユースケースでは、次の機能を使用します。

  • 資格証明が格納され、アプリケーションがPasswordCredentialとして伝播する必要がある特定のアイデンティティを取得するOPSSセキュリティ・ストア

  • アイデンティティをフェッチし、リモートWebサービスに伝播するOracle Web Services Managerの機能

このユースケースの詳細は、Oracle Fusion Middleware Webサービスのためのセキュリティおよび管理者ガイドの第9章「ポリシー・セットの作成および管理」を参照してください。

19.2.6.3 別のドメインへのアイデンティティの伝播

WebLogicドメインのコンテナ内のあるクライアント・アプリケーションは、ユーザー・アイデンティティ(OPSSセキュリティ・ストアに格納されている)を、RMIを介して別のWebLogicドメインに伝播する必要があります。

このユースケースの詳細は、WebLogic Serverドメイン間の信頼の有効化に関する項を参照してください。

19.2.6.4 HTTPを介したアイデンティティの伝播

WebLogicドメインまたはWASセルのコンテナ内のあるクライアント・アプリケーションは、HTTPを介してアイデンティティを伝播する必要があります。

このユースケースの要件および詳細は、「OPSSトラスト・サービスを使用したアイデンティティの伝播」の推奨される実装に関する項を参照してください。OPSSキーストア・サービスを使用しない代替の実装は、「付録 - JKSベースのキーストアを使用したアイデンティティの伝播」で説明します。

19.2.7 管理

管理ユースケースは次のとおりです。

19.2.7.1 中央ストアが必要なアプリケーション

あるアプリケーションには、ポリシー、資格証明、監査構成、信頼およびキーを格納する中央リポジトリ(OPSSセキュリティ・ストア)、およびその中央リポジトリを管理するためのツール・セットが必要です。

このユースケースでは、次の機能を使用します。

  • OPSSセキュリティ・ストア

  • Fusion Middleware Controlを使用したセキュリティ・アーティファクトの管理

  • OPSSスクリプトを使用したセキュリティ・アーティファクトの管理

詳細は、次の各項を参照してください。

19.2.7.2 カスタム管理ツールが必要なアプリケーション

あるアプリケーションには、アプリケーションのビジネスに意味のあるコンテキストで、外部化したセキュリティ・アーティファクトを管理するためのカスタム・ツールが必要です。

このユースケースでは、アプリケーションに意味のあるコンテキストでOPSSセキュリティ・ストア内のセキュリティ・アーティファクトを表示および管理するためのOPSS APIへのコールを含む、カスタム・グラフィカル・ユーザー・インタフェースを構築する必要があります。

このユースケースでは、次の機能を使用します。

  • OPSS APIを使用したセキュリティ・アーティファクトの管理

詳細は、次の各項を参照してください。

19.2.7.3 複数のサーバー環境で実行されるアプリケーション

複数のサーバー・インスタンスが複数のマシンに分散されているWebLogicドメイン内で実行されているアプリケーションが、セキュリティ・アーティファクトを変更する必要があります。変更は、どこで実行されているかにかかわらず、アプリケーションのすべてのコンポーネントに反映されなければなりません。

このユースケースでは、次の機能を使用します。

  • 管理サーバー上でセキュリティ・アーティファクトの変更が開始された場合の変更の伝播。管理対象サーバー・ノード上のデータは、キャッシュ・ポリシーに基づいてリフレッシュされます。

  • MBean APIまたは管理APIを使用したセキュリティ・アーティファクトの変更。

詳細は、次の各項を参照してください。

19.2.8 統合

統合ユースケースは次のとおりです。

19.2.8.1 複数のドメインで実行されるアプリケーション

ある製品では、複数のWebLogicドメインを実行する必要があり、これらのドメインは単一の中央OPSSセキュリティ・ストアを共有します。

このユースケースでは、次の機能を使用します。

  • 1つのセキュリティ・ストアを共有する複数のドメインに対するOPSSのサポート

詳細は、次の各項を参照してください。

19.3 OPSSトラスト・サービス

OPSSトラスト・サービスにより、トークンを提供および検証することによって、HTTP対応のアプリケーションにアイデンティティを伝播できます。OPSSトラスト・サービスは、次のプラットフォームでのみ使用可能なアサーション・プロバイダを使用します。

WebLogicドメインまたはWebSphereセルごとに1つのアサーション・プロバイダが存在します。

サービス構成プロパティの詳細は、第F.2.6項「トラスト・サービスのプロパティ」を参照してください。Fusion Middleware Controlを使用したこのサービスの構成の詳細は、第8.7.3項「トラスト・サービス・プロバイダの構成」を参照するか、次の項の説明に従ってOPSSスクリプトupdateTrustServiceConfigを使用してください。

19.3.1 updateTrustServiceConfigスクリプトを使用した更新

オンラインのOPSSスクリプトupdateTrustServiceConfigにより、プロパティ・ファイルで渡される値を使用してドメイン・トラスト・サービスの構成を更新します。このスクリプトは、WebLogicおよびWebSphereの両方のプラットフォームで機能します。WebLogicでの構文は、次のとおりです。

updateTrustServiceConfig([providerName="<the provider name>",] 
                          propsFile="<path of properties file>")

WebSphereでの構文は、次のとおりです。

Opss.updateTrustServiceConfig([providerName="<the provider name>",] 
                               propsFile="<path of properties file>")

引数の意味は、次のとおりです。

  • providerNameは、トラスト・サービス・プロバイダの名前を指定します。この引数はオプションです。指定しない場合は、デフォルトでtrust.provider.embeddedが使用されます。

  • propsFileは、プロパティの値を設定するファイルへのパスを指定します。プロパティ・ファイルのサンプルは次のとおりです。

    trust.keystoreType=KSS
    trust.keyStoreName=kss://<stripeName>/<keystoreName>
    trust.trustStoreName=kss://<stripeName>/<truststoreName>
    trust.aliasName=<aliasName>
    trust.issuerName=<aliasName>
    

    指定されたプロパティのリストは、trust.keystoreTypeプロパティの値により異なることに注意してください。タイプはKSSまたはJKSに設定できます。プロパティに空の文字列が設定されている場合は、そのプロパティはトラスト・サービス構成から削除されます。使用可能なプロパティのリストの詳細は、付録F「トラスト・サービスのプロパティ」を参照してください。

19.4 HTTPプロトコルを介したアイデンティティの伝播

HTTPコールを使用したアイデンティティ伝播は、一般的に次のように実行されます(図19-2を参照)。

  1. Domain1のクライアント・アプリケーションが、Domain1のOPSSトラスト・サービス・インスタンスに対して、認証されたユーザーに対するトークンをリクエストします。

  2. トラスト・サービスがDomain1のキーストアにアクセスし、トークンをクライアント・アプリケーションに発行します。

  3. クライアント・アプリケーションがトークンをHTMLヘッダー内にエンコードし、HTTPリクエストをDomain2のサーブレット・アプリケーションにディスパッチします。Domain 2のアサーション・プロバイダがリクエストをインターセプトし、トークンを抽出します。

  4. アサーション・プロバイダがDomain2のOPSSトラスト・サービス・インスタンスに対して、そのトークンの検証をリクエストします。

  5. トラスト・サービスがトークンを検証するためにDomain2のキーストアにアクセスし、レスポンスを返します。

  6. 検証が成功したとみなし、アサーション・プロバイダはアサートされたアイデンティティを使用して、リクエストをサーブレット・アプリケーションに送信します。

  7. サーブレット・アプリケーションが、クライアント・アプリケーション・リクエストに対するHTTPレスポンスを送信します。

図19-2 HTTPコールを使用したアイデンティティ伝播

図19-2については周囲のテキストで説明しています。

即時利用可能な構成では、キー別名はWebLogicサーバー名に基づいていることを前提としています。ただし、WebSphereでは、キー別名はWebSphereサーバー・ルートに基づいて設定されます。たとえば、サーバー・ルート名が$T_WORK/middleware/was_profiles/DefaultTopology/was_as/JrfServerの場合、キー別名はJrfServerに設定されます。


注意:

アイデンティティの伝播を実装するには、「OPSSトラスト・サービスを使用したアイデンティティの伝播」の説明に従って、OPSSトラスト・サービスおよびOPSSキーストアを使用する方法をお薦めします。


19.5 OPSSトラスト・サービスを使用したアイデンティティの伝播

この項では、複数ドメイン間および単一のドメイン内の複数コンテナ間で、OPSSトラスト・サービスを使用してアイデンティティを伝播する方法を説明します。トラスト・サービスを使用したアイデンティティの伝播は、Oracle WebLogicおよびIBM WebSphereプラットフォームでのみサポートされています。


注意:

この項のサンプルではWebLogicドメインの構成を示していますが、WebSphereセルにも適用されます。すべてのサンプルは、キーストア・サービスおよびアサーション・プロバイダ構成を除いて、どちらのプラットフォームにも適用されます。相違点は明記されています。


OPSSキーストア・サービスの詳細は、第11章「キーストア・サービスでのキーと証明書の管理」を参照してください。

この項では、Oracle WebLogicプラットフォームのOPSSトラスト・サービスを使用したアイデンティティの伝播に必要とされるコードおよび構成のサンプルについて説明します。この項の内容は次のとおりです。

19.5.1 複数のWebLogicドメイン間

このシナリオでは、Domain1とDomain2という2つのドメインが存在します。クライアント・アプリケーションはDomain1で、サーブレット・アプリケーションはDomain2で実行されています。クライアント・アプリケーションはトークンの生成にDomain1のOPSSトラスト・サービスを使用し、サーブレット・アプリケーションはトークンの検証にDomain2のOPSSトラスト・サービスを使用します。

次の各項で、このシナリオで必要なサンプルおよび構成について説明します。

19.5.1.1 クライアント側ドメインでのトークン生成

クライアント側、つまりトークンを発行するドメインでは、次の作業が必要です。

19.5.1.1.1 クライアント・アプリケーションの開発

クライアント・アプリケーションは、Java SEアプリケーションまたはJava EEアプリケーションです。次のコード・サンプルは、クライアント・アプリケーションの骨格を示しています。

// Authentication type name
public static final String AUTH_TYPE_NAME = "OIT";
// The authenticated username
String user = "weblogic"; 
// URL of the target application
URL url = "http://<host>:<port>/<destinationApp>"; 
//-----------------------------------------
JpsContextFactory ctxFactory = JpsContextFactory.getContextFactory();
JpsContext jpsCtx = ctxFactory.getContext();
final TrustService trustService = jpsCtx.getServiceInstance(TrustService.class);
final TokenManager tokenMgr = trustService.getTokenManager();
final TokenContext ctx = tokenMgr.createTokenContext(
    TokenConfiguration.PROTOCOL_EMBEDDED);
UsernameToken ut = WSSTokenUtils.createUsernameToken("wsuid", user);
GenericToken gtok = new GenericToken(ut);
ctx.setSecurityToken(gtok);
ctx.setTokenType(SAML2URI.ns_saml);
Map<String, Object> ctxProperties = ctx.getOtherProperties();
ctxProperties.put(TokenConstants.CONFIRMATION_METHOD,
    SAML2URI.confirmation_method_bearer);
 
AccessController.doPrivileged(new PrivilegedAction<String>() {
    public String run() {
        try {
            tokenMgr.issueToken(ctx);
        } catch (Exception e) {        
            e.printStackTrace();
        }
        return null;
    }
});
 
Token token = ctx.getSecurityToken();
String b64Tok = TokenUtil.encodeToken(token);
 
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.setReadTimeout(10000);
connection.setRequestProperty("Authorization", AUTH_TYPE_NAME + " " + b64Tok);
connection.connect();
BufferedReader rd = new BufferedReader(new InputStreamReader(
    connection.getInputStream()));
StringBuilder sb = new StringBuilder();
 
String line = null;
while ((line = rd.readLine()) != null) {
    sb.append(line);
}
connection.disconnect();        
System.out.println(sb.toString());
19.5.1.1.2 OPSSキーストア・サービスの構成

注意:

この項で示される構成はWebLogicプラットフォームにのみ適用されます。WebSphereプラットフォームでの同等の構成は、Oracle Fusion Middlewareサードパーティ・アプリケーション・サーバー・ガイドのOPSSキーストア・サービスの構成に関する項を参照してください。


トラスト・サービス・キーストアは、クライアント証明書および秘密鍵を使用してプロビジョニングされます。その証明書は、キーストアからエクスポートされてトラスト・ストアへインポートされます。これらのストア、キーストアおよびトラスト・ストアはいずれも、クライアント・ドメインのOPSS KSSにより管理されます。


注意:

トラスト・サービス・プロパティtrust.keystoreTypeがKSSに設定されている場合は、キーストアまたはトラスト・ストア用にパスワードを使用しないことをお薦めします。この場合、デフォルトで、トラスト・サービスで使用されるキーストアおよびトラスト・ストアは、コードソース・パーミッションにより保護されるため、パスワード保護は必要ありません。


次のスクリプトに、これらのタスクが示されています。

# Update following values with correct value
user = "<username>"
password = "<password>"
wlsurl = "t3(s)://<host>:<port>"
stripeName = "<stripeNmae>"
 
#-----------------------------------------------
ksName = "<trustservice_ks>"
tsName = "<trustservice_ts>"
aliasName = "<trustservice>"
issuerDN = "cn=" + aliasName
 
print "Stripe Name: " + stripeName
 
print "KeyStore Name: " + ksName
print "TrustStore Name: " + tsName
print "Alias Name: " + aliasName
print "Issuer DN: " + issuerDN
 
#-----------------------------------------------
connect(user, password, wlsurl)
 
svc = getOpssService(name='KeyStoreService')
svc.listKeyStores(appStripe=stripeName)

svc.createKeyStore(appStripe=stripeName, name=ksName, password="", permission=true)
svc.generateKeyPair(appStripe=stripeName, name=ksName, password="", dn=issuerDN, keysize="1024", alias=aliasName, keypassword="")
svc.exportKeyStoreCertificate(appStripe=stripeName, name=ksName, password="", alias=aliasName, keypassword="", type="Certificate", filepath="./trustservice.cer")
 
svc.createKeyStore(appStripe=stripeName, name=tsName, password="", permission=true)
svc.importKeyStoreCertificate(appStripe=stripeName, name=tsName, password="", alias=aliasName, keypassword="", type="TrustedCertificate", filepath="./trustservice.cer")
 
svc.listKeyStores(appStripe=stripeName)
svc.listKeyStoreAliases(appStripe=stripeName, name=ksName, password="", type="Certificate")
exit()
19.5.1.1.3 TrustServiceAccessPermission権限の追加

次のシステム・ポリシーは、トラスト・サービスAPIの使用をクライアントに許可するコードソースの権限付与を示しており、アプリケーションのjazn-data.xmlファイルに含まれている必要があります。

<grant>
  <grantee>
    <codesource> 
       <url>file:${oracle.deployed.app.dir}/<MyApp>${oracle.deployed.app.ext}</url>
    </codesource>
  </grantee>
  <permissions>
    <permission> 
       <class>oracle.security.jps.service.trust.TrustServiceAccessPermission</class>
      <name>appId=*</name>
      <actions>issue</actions>
    </permission>
  </permissions>
</grant>

その権限は、OPSSスクリプトを使用してシステム・ポリシー・ストアに追加できます。詳細は、第9.3.10項「grantPermission」を参照してください。または、アプリケーションがJava EEアプリケーションで、jazn-data.xmlファイルがアプリケーションとパッケージ化されている場合は、アプリケーションのデプロイ時に権限がシステム・ポリシー・ストアに移行されるように、ライフ・サイクル・リスナーを設定できます。詳細は、第21.2項「サーブレット・フィルタとEJBインターセプタの構成」を参照してください。

19.5.1.1.4 トラスト・サービス・プロバイダの構成

次のサンプルでは、jps-config.xmlファイルのトラスト・サービス・プロバイダの構成を示します。

<propertySet name="trust.provider.embedded">
        <property name="trust.keystoreType" value="KSS"/>
  <property name="trust.keyStoreName" value="kss://<stripeName>/<keystoreName>"/>
  <property name="trust.trustStoreName" value="kss://<stripeName>/<truststoreName>"/>
  <property name="trust.aliasName" value="<aliasName>"/>
  <property name="trust.issuerName" value="<issuerName>"/>
  <property name="trust.provider.className" value="oracle.security.jps.internal.trust.provider.embedded.EmbeddedProviderImpl"/>
  <property name="trust.clockSkew" value="60"/>
  <property name="trust.token.validityPeriod" value="1800"/>
  <property name="trust.token.includeCertificate" value="false"/>
</propertySet>

19.5.1.2 サーバー側つまりトークン検証ドメイン

サーバー側、つまりトークンを受信するドメインでは、次の作業が必要です。

19.5.1.2.1 サーバー・アプリケーションの開発

次のサンプルは、サーブレット・コードがアサートされたユーザーを取得する方法を示しています。

public void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
   String username = request.getRemoteUser();
   ServletOutputStream out = response.getOutputStream();
   out.print("Asserted username: " + username);
   out.close();
}
19.5.1.2.2 web.xmlの構成

次のサンプルは、web.xmlファイルでログイン構成メソッドをCLIENT-CERTに設定する必要があることを示しています。

<web-app id="WebApp_ID"
…
 <login-config>
   <auth-method>CLIENT-CERT</auth-method>
   <realm-name>Identity Assertion </realm-name>
 </login-config>
…
</web-app>
19.5.1.2.3 WebLogicトラスト・サービスのアサーション・プロバイダの構成

注意:

この項の手順はWebLogicプラットフォームにのみ適用されます。WebSphereプラットフォームでの同等の構成は、Oracle Fusion Middlewareサードパーティ・アプリケーション・サーバー・ガイドのWebSphereコンソールを使用したTAIの構成に関する項を参照してください。


WebLogicトラスト・サービス・アサーション・プロバイダを構成するには、次の手順を実行します。

  1. 次のいずれかを実行します。

    • WebLogicコンソールに管理者としてログインし、「セキュリティ・レルム」→myrealm→「プロバイダ」タブ→「認証」の順に移動してTrustServiceIdentityAsserterを選択します。

      このアサーション・プロバイダは、トラスト・サービスAPIをコールして受信するリクエストからのトークンをデコードし、検証します。そして、WebLogic Serverにユーザー名を渡してアサートされたサブジェクトを確立します。

    • 次のスクリプトを使用します。

      connect("<username>","<password>","t3://<host>:<port>")
      edit()
      startEdit()
      realm = cmo.getSecurityConfiguration().getDefaultRealm()
      tsia = realm.lookupAuthenticationProvider("TSIA")
      if tsia != None:
          realm.destroyAuthenticationProvider(tsia)
      tsia = realm.createAuthenticationProvider("TSIA", "oracle.security.jps.wls.providers.trust.TrustServiceIdentityAsserter")
      save()
      activate()
      disconnect()
      
19.5.1.2.4 OPSSキーストア・サービスのプロビジョニング

Domain1のキー・ストアでプロビジョニングされたクライアント証明書は、次のスクリプトで示されるように、そのドメインからエクスポートされ、Domain2のトラスト・ストアにインポートされる必要があります。


注意:

複数ドメイン設定の場合は、クライアント側でのトークンの生成中に設定されたissuerNameが、サーバー側の証明書の名前を検索するための別名として使用されます。キーストアの証明書は、クライアント側の発行者名と一致する別名でインポートされる必要があります。


# Update following values with correct value
user = "<username>"
password = "<password>"
wlsurl = "t3(s)://<host>:<port>"
 
stripeName = "<stripeName>"
 
#-----------------------------------------------
ksName = "<trustservice_ks>"
tsName = "<trustservice_ts>"
aliasName = "<trustservice>"
 
print "Importing certificate for : " + aliasName
print "Stripe Name: " + stripeName
 
print "TrustStore Name: " + tsName
print "Alias Name: " + aliasName
 
#-----------------------------------------------
connect(user, password, wlsurl)
 
svc = getOpssService(name='KeyStoreService')
 
svc.listKeyStores(appStripe=stripeName)
 
# switch Trust service to using FKS
svc.createKeyStore(appStripe=stripeName, name=tsName, password="", permission=true)
 
svc.importKeyStoreCertificate(appStripe=stripeName, name=tsName, password="", alias=aliasName, keypassword="", type="TrustedCertificate", filepath="./trustservice.cer")
 
svc.listKeyStoreAliases(appStripe=stripeName, name=tsName, password="", type="TrustedCertificate")
 
exit()
19.5.1.2.5 TrustServiceAccessPermissionの追加

次のシステム・ポリシーは、トラスト・サービスAPIの検証をクライアントに許可するコードソースの権限付与を示しており、アプリケーションのjazn-data.xmlファイルに含まれている必要があります。

<grant>
  <grantee>
    <codesource> 
       <url>file:${oracle.deployed.app.dir}/<MyApp>${oracle.deployed.app.ext}</url>
    </codesource>
  </grantee>
  <permissions>
    <permission> 
       <class>oracle.security.jps.service.trust.TrustServiceAccessPermission</class>
      <name>appId=*</name>
      <actions>validate</actions>
    </permission>
  </permissions>
</grant>
19.5.1.2.6 トラスト・サービス・プロバイダの構成

次のサンプルでは、jps-config.xmlファイルのトラスト・サービス・プロバイダの構成を示します。

<propertySet name="trust.provider.embedded">
        <property name="trust.keystoreType" value="KSS"/>
  <property name="trust.keyStoreName" value="kss://<stripeName>/<keystoreName>"/>
  <property name="trust.trustStoreName" value="kss://<stripeName>/<truststoreName>"/>
  <property name="trust.aliasName" value="<aliasName>"/>
  <property name="trust.issuerName" value="<issuerName>"/>
  <property name="trust.provider.className" value="oracle.security.jps.internal.trust.provider.embedded.EmbeddedProviderImpl"/>
  <property name="trust.clockSkew" value="60"/>
  <property name="trust.token.validityPeriod" value="1800"/>
  <property name="trust.token.includeCertificate" value="false"/>
</propertySet>

注意:

サーバーがトークンの検証にのみ使用されている場合は、前述の例で設定されたaliasNameおよびissuerNameはトークンの検証には使用されず、オプション属性です。この場合は、トークンを検証するために、トラスト・サービスはトークンにある発行者名を使用して証明書を探します。


19.5.2 単一のWebLogicドメイン内のコンテナ間

このシナリオでは、クライアント・アプリケーションとサーバー・アプリケーションは同じドメインで稼働します。したがって、両方のアプリケーションが同じキーストアを使用できるため、(その他のキーストアに対して)クライアント証明書をインポートする必要がありません。その他の情報はすべて、複数ドメインのシナリオで説明された内容と同じです。

19.5.3 埋込みトラスト・サービス・プロバイダのプロパティ

次のプロパティは、単一ドメインまたは複数ドメインのシナリオで、埋込みトラスト・サービス・プロバイダの構成に使用されます。

  • trust.keyStoreType

  • trust.keyStoreName

  • trust.trustStoreName

  • trust.aliasName

  • trust.issuerName

  • trust.provider.className

  • trust.clockSkew

  • trust.token.validityPeriod

  • trust.token.includeCertificate

次のサンプルでは、jps-config.xmlファイルの埋込みトラスト・サービス・プロバイダのサンプル構成を示します。

<propertySet name="trust.provider.embedded">
  <property name="trust.keystoreType" value="KSS"/>
  <property name="trust.keyStoreName" value="kss://<stripeName>/<keystoreName>"/>
  <property name="trust.trustStoreName" value="kss://<stripeName>/<truststoreName>"/>
  <property name="trust.aliasName" value="<aliasName>"/>
  <property name="trust.issuerName" value="<aliasName>"/>
  <property name="trust.provider.className" 
              value="oracle.security.jps.internal.trust.provider.embedded.EmbeddedProviderImpl"/>
  <property name="trust.clockSkew" value="60"/>
  <property name="trust.token.validityPeriod" value="1800"/>
  <property name="trust.token.includeCertificate" value="false"/>
</propertySet>

埋込みトラスト・サービス・プロバイダのプロパティを設定するには、OPSSスクリプトupdateTrustServiceConfigを使用するか、または、第8.7.3項「トラスト・サービス・プロバイダの構成」の説明に従ってOracle Enterprise Manager Fusion Middleware Controlを使用してください。

「OPSSキーストア・サービスの構成」で説明される構成では、<stripName>、<keystoreName>、<trustStoreName>、<aliasName>の値を適切に設定します。

19.6 カスタム・グラフィカル・ユーザー・インタフェース

このユースケースでは、たとえばポリシーを管理するためにカスタム・グラフィカルUIを実装する場合などに必要な操作の一部を示しています。紹介するサンプルはOPSS APIを使用し、次の操作について説明します。

このユースケースは次のことを前提としています:

図19-3に、このユースケースの前提となる、アプリケーション・ロールの階層、ユーザーとグループ、およびアプリケーション・ロールからユーザーとグループへのマッピングを示します。

図19-3 アプリケーション・ロールからユーザーとグループへのマッピング

図19-3については周囲のテキストで説明しています。

前述のロール階層は、たとえばロールSystem Manager内のユーザーはロールSystem Developerにも含まれ、他のロールについても同様であることを意味します。したがって、4人のユーザーのロール・メンバーシップはそれぞれ次のようになります。

コード・サンプルについては、次の各項に詳しく示します。

19.6.1 前提とするインポート

このユースケースのサンプル・コードでは、次のimport文を前提としています。

import java.security.AccessController;
import java.security.Policy;
import java.security.Principal;
import java.security.PrivilegedExceptionAction;
import java.security.Security;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.security.auth.Subject;
import oracle.security.idm.Identity;
import oracle.security.idm.IdentityStore;
import oracle.security.idm.ObjectNotFoundException;
import oracle.security.idm.Role;
import oracle.security.idm.RoleManager;
import oracle.security.idm.SearchParameters;
import oracle.security.idm.SearchResponse;
import oracle.security.idm.SimpleSearchFilter;
import oracle.security.idm.User;
import oracle.security.idm.UserProfile;
import oracle.security.jps.ContextFactory;
import oracle.security.jps.JpsContext;
import oracle.security.jps.JpsContextFactory;
import oracle.security.jps.principals.JpsApplicationRole;
import oracle.security.jps.service.idstore.IdentityStoreService;
import oracle.security.jps.service.policystore.ApplicationPolicy;
import oracle.security.jps.service.policystore.PolicyObjectNotFoundException;
import oracle.security.jps.service.policystore.PolicyStore;
import oracle.security.jps.service.policystore.PolicyStoreException;
import oracle.security.jps.service.policystore.entitymanager.AppRoleManager;
import oracle.security.jps.service.policystore.info.AppRoleEntry;
import oracle.security.jps.service.policystore.search.AppRoleSearchQuery;
import oracle.security.jps.service.policystore.search.ComparatorType;
import oracle.security.jps.util.JpsAuth;
import weblogic.security.principal.PrincipalFactory;

19.6.2 コード・サンプル1

次のサンプル・コードは、アイデンティティ・ストア内のユーザーに対する2つの問合せを示しています。

private void queryUsers() throws Exception {
        // Using IDM U/R to query ID store
        IdentityStore idmStore = idStore.getIdmStore();
 
        // Query an individual user by name
        User employee = idmStore.searchUser(USER_TOM);
        log("----------------------------------------------------------");
        log("### Query individual user (Tom) from ID store ###");
        log(USER_TOM + ": " + employee.getName() + " GUID: " +
            employee.getGUID());
        log();
 
        // Get all users whose name is not "Paul"
        SimpleSearchFilter filter =
            idmStore.getSimpleSearchFilter(UserProfile.NAME,
                                           SimpleSearchFilter.TYPE_NOTEQUAL,
                                           "Paul");
        SearchParameters sps =
            new SearchParameters(filter, SearchParameters.SEARCH_USERS_ONLY);
        SearchResponse result = idmStore.searchUsers(sps);
        log("----------------------------------------------------------");
        log("### Query all users (whose name is not Paul) from ID store ###");
        log("Found the following users:");
        while (result.hasNext()) {
            Identity user = result.next();
            log("\t user: " + user.getName() + ", GUID: " + user.getGUID());
        }
        log();
    }

19.6.3 コード・サンプル2

次のサンプル・コードは、アプリケーション・ロールを作成する方法およびロールを別のロールのメンバーにする方法を示しています。

private void createAppRoles1() throws Exception {
        AppRoleManager arm1 = ap1.getAppRoleManager();
        log("----------------------------------------------------------");
        log("### Creating app roles in app policy1 with hierachy ###");
 
        AppRoleEntry sysAnalystRole =
            arm1.createAppRole(APP_ROLE_SYS_ANALYST, APP_ROLE_SYS_ANALYST,
                               APP_ROLE_SYS_ANALYST);
        AppRoleEntry sysDeveloperRole =
            arm1.createAppRole(APP_ROLE_SYS_DEVELOPER, APP_ROLE_SYS_DEVELOPER,
                               APP_ROLE_SYS_DEVELOPER);
        AppRoleEntry sysManagerRole =
            arm1.createAppRole(APP_ROLE_SYS_MANAGER, APP_ROLE_SYS_MANAGER,
                               APP_ROLE_SYS_MANAGER);
 
        ap1.addPrincipalToAppRole(sysManagerRole, APP_ROLE_SYS_DEVELOPER);
        ap1.addPrincipalToAppRole(sysDeveloperRole, APP_ROLE_SYS_ANALYST);
        log("### App roles in app policy #1 have been created ###");
        log();
 
    }

19.6.4 コード・サンプル3

次のサンプル・コードは、アプリケーション・ロールを問い合せる様々な方法を示しています。

private void queryAppRolesInApplicationPolicy1() throws Exception {
        AppRoleManager arm1 = ap1.getAppRoleManager();
 
        // Get role that matches a name
        AppRoleEntry are = arm1.getAppRole(APP_ROLE_SYS_MANAGER);
        log("----------------------------------------------------------");
        log("### Query app roles in application policy #1, by name ###");
        log("Found " + are.getName() + " by app role name.");
        log();
 
        // Get the role that matches a name exactly
        AppRoleSearchQuery q =
            new AppRoleSearchQuery(AppRoleSearchQuery.SEARCH_PROPERTY.NAME,
                                   false, ComparatorType.EQUALITY,
                                   APP_ROLE_SYS_ANALYST,
                                   AppRoleSearchQuery.MATCHER.EXACT);
        List<AppRoleEntry> arel = arm1.getAppRoles(q);
        log("### Query app roles in application policy #1, by exact query ###");
        log("Found " + arel.get(0).getName() + " by exact query.");
        log();
 
        // Get roles with names that begin with a given string
        q =
   new AppRoleSearchQuery(AppRoleSearchQuery.SEARCH_PROPERTY.NAME, false,
                          ComparatorType.EQUALITY,
                          APP_ROLE_SYS_DEVELOPER.subSequence(0, 7),
                          AppRoleSearchQuery.MATCHER.BEGINS_WITH);
        arel = arm1.getAppRoles(q);
        log("### Query app roles in app policy #1, by begins_with query ###");
        log("Found " + arel.get(0).getName() + " by begins_with query.");
        log();
 
        // Get roles with names that contain a given substring
        q =
   new AppRoleSearchQuery(AppRoleSearchQuery.SEARCH_PROPERTY.NAME, false,
                          ComparatorType.EQUALITY, "dummy",
                          AppRoleSearchQuery.MATCHER.ANY);
        arel = arm1.getAppRoles(q);
        log("### Query app roles in app policy #1, by matcher any ###");
        log("Found " + arel.size() + " app roles by matcher any.");
        for (AppRoleEntry ar : arel) {
            log("\t" + ar.getName());
        }
        log();
    }

19.6.5 コード・サンプル4

次のサンプル・コードは、アプリケーション・ロールをユーザーとグループにマップする方法を示しています。

private void assignAppRoleToUsersAndGroups() throws Exception {
        // Obtain the user/group principals
        IdentityStore idmStore = idStore.getIdmStore();
        User tom = idmStore.searchUser(USER_TOM);
        User helen = idmStore.searchUser(USER_HELEN);
 
        Role trainingRole =
            idmStore.searchRole(IdentityStore.SEARCH_BY_NAME, GROUP_TRAINING);
        Role devRole =
            idmStore.searchRole(IdentityStore.SEARCH_BY_NAME, GROUP_DEV);
 
        Principal tomPrincipal =
            PrincipalFactory.getInstance().createWLSUser(tom.getName(),
                                                         tom.getGUID(),
                                                         tom.getUniqueName());
        Principal helenPrincipal =
            PrincipalFactory.getInstance().createWLSUser(helen.getName(),
                                                         helen.getGUID(),
                                                         helen.getUniqueName());
 
        Principal trainingPrincipal =
            PrincipalFactory.getInstance().createWLSGroup(trainingRole.getName(),
                                                          trainingRole.getGUID(),
                                                          trainingRole.getUniqueName());
        Principal devPrincipal =
            PrincipalFactory.getInstance().createWLSGroup(devRole.getName(),
                                                          devRole.getGUID(),
                                                          devRole.getUniqueName());
 
        // Application policy #1
        log("----------------------------------------------------------");
        log("### Assigning appl roles to users and groups, app policy #1 ###");
        ap1.addPrincipalToAppRole(helenPrincipal, APP_ROLE_SYS_MANAGER);
        ap1.addPrincipalToAppRole(devPrincipal, APP_ROLE_SYS_DEVELOPER);
 
        // Application policy #2
        log("### Assigning app roles to users and groups, app policy #2 ###");
        ap2.addPrincipalToAppRole(tomPrincipal, APP_ROLE_DIRECTOR);
        ap2.addPrincipalToAppRole(devPrincipal, APP_ROLE_INSTRUCTOR);
        ap2.addPrincipalToAppRole(trainingPrincipal, APP_ROLE_INSTRUCTOR);
 
        log("### App roles have been assigned to users and groups ###");
        log();
    }

19.6.6 コード・サンプル5

次のサンプル・コードは、特定のユーザーがメンバーであるすべてのロールを取得する方法を示しています。

private void showAppRoles() throws Exception {
        Subject tomSubject = getUserSubject(USER_TOM);
        Subject helenSubject = getUserSubject(USER_HELEN);
        Subject johnSubject = getUserSubject(USER_JOHN);
        Subject marySubject = getUserSubject(USER_MARY);
 
        Set<String> applications = new HashSet<String>();
        applications.add(APPLICATION_NAME1);
        applications.add(APPLICATION_NAME2);
 
        log("----------------------------------------------------------");
        log("### Query application roles for Tom ###");
        showAppRoles(applications, USER_TOM, tomSubject);
        log();
 
        log("### Query application roles for Helen ###");
        showAppRoles(applications, USER_HELEN, helenSubject);
        log();
 
        log("### Query application roles for John ###");
        showAppRoles(applications, USER_JOHN, johnSubject);
        log();
 
        log("### Query application roles for Mary ###");
        showAppRoles(applications, USER_MARY, marySubject);
        log();
    }

private Subject getUserSubject(String userName) throws Exception {
        Subject subject = new Subject();
 
        // Query users from ID store using user/role API,for user principal
        IdentityStore idmStore = idStore.getIdmStore();
        User user = idmStore.searchUser(userName);
 
        Principal userPrincipal =
            PrincipalFactory.getInstance().createWLSUser(user.getName(),
                                                         user.getGUID(),
                                                         user.getUniqueName());
 
        subject.getPrincipals().add(userPrincipal);
 
        // Query users from ID store using user/role API, for enterprise roles
        RoleManager rm = idmStore.getRoleManager();
        SearchResponse result = null;
        try {
            result = rm.getGrantedRoles(user.getPrincipal(), false);
        } catch (ObjectNotFoundException onfe) {
            // ignore
        }
 
        // Add group principals to the subject
        while (result != null && result.hasNext()) {
            Identity role = result.next();
            Principal groupPrincipal =
                PrincipalFactory.getInstance().createWLSGroup(role.getName(),
                                                              role.getGUID(),
                                                        role.getUniqueName());
            subject.getPrincipals().add(groupPrincipal);
        }
 
        // The subject now contains both user and group principals.
        // In the WebLogic Server, this setting is done by a login module
        return subject;
    }

private void showAppRoles(Set<String> applications, String user, Subject subject) {
        // Get all granted application roles for this subject
        Set<JpsApplicationRole> result = null;
        try {
            result = JpsAuth.getAllGrantedAppRoles(subject, applications);
        } catch (PolicyStoreException pse) {
            log(pse.toString());
        }
 
        if (result.size() <= 1) {
            log(user + " has " + result.size() + " application role.");
            if (result.size() == 1) {
                for (JpsApplicationRole ar : result) {
                    log("\tApplication role: " + ar.getName());
                }
            }
        } else {
            System.out.println(user + " has " + result.size() +
                               " application roles.");
            for (JpsApplicationRole ar : result) {
                log("\tApplication role: " + ar.getAppID() + "/" +
                    ar.getName());
            }
        }
    }

19.6.7 コード・サンプル6

次のサンプル・コードは、アプリケーション・ロールからグループへのマッピングを削除する方法を示しています。

private void removeAppRoleForUserDirector() throws Exception {
        // Remove instructor role from Dev group
        log("----------------------------------------------------------");
        log("### Removing Instructor application role from Dev group ###");
 
        IdentityStore idmStore = idStore.getIdmStore();
        Role devRole =
            idmStore.searchRole(IdentityStore.SEARCH_BY_NAME, GROUP_DEV);
        Principal devPrincipal =
            PrincipalFactory.getInstance().createWLSGroup(devRole.getName(),
                                                          devRole.getGUID(),
                                                          devRole.getUniqueName());
 
        ap2.removePrincipalFromAppRole(devPrincipal, APP_ROLE_INSTRUCTOR);
        log("### Instructor app role has been removed from Dev group ###");
        log();
 
        log("----------------------------------------------------------");
        log("### Now query application roles for user John, again ###");
        Set<String> applications = new HashSet<String>();
        applications.add(APPLICATION_NAME1);
        applications.add(APPLICATION_NAME2);
 
        Subject johnSubject = getUserSubject(USER_JOHN);
        showAppRoles(applications, USER_JOHN, johnSubject);
        log();
    }

19.7 付録 - ADFアプリケーションのセキュリティ・ライフ・サイクル

この項では、アプリケーションのセキュリティがたどるフェーズについて説明します。ここではアプリケーションがADFを使用し、Oracle JDeveloper環境を使用していることを前提として説明します。

アプリケーションのセキュリティ・ライフ・サイクルのフェーズとは、開発フェーズ、デプロイメント・フェーズ、および管理フェーズです。関係する担当者は製品マネージャ、アプリケーション設計者、アプリケーション開発者、およびアプリケーション・セキュリティ管理者です。タスクの概要については、「各フェーズの担当者別タスクの概要」を参照してください。

19.7.1 開発フェーズ

開発フェーズでは、開発者によってOracle Fusion Middlewareで使用可能な広範なセキュリティ・オプション機能がアプリケーションと連携するように設計されます。開発者はOracle JDeveloper、組込みのADFフレームワーク、およびOracle WebLogicサーバーで公開される豊富なセキュリティ・サービスを利用できます。これらのコンポーネントはすべてOPSSを基盤としています。OPSSによってアプリケーションの使用期間全体にわたってセキュリティ・アプローチの整合性が保持されることが保証されます。

通常、開発者はADFセキュリティ・ウィザード(認可エディタ)および式言語エディタを使用します。これらはすべてOracle JDeveloperにあります。さらに、必要に応じて、OPSS APIを使用してより複雑なセキュリティ・タスクを実装することもできます。これによってアプリケーションの一部で宣言によるセキュリティを使用し、別の部分でプログラムによるセキュリティを使用でき、また、いずれの場合も開発および実行時環境で使用可能なセキュリティ機能を利用できます。

アプリケーション開発者は、アプリケーションの保護に必要な複数のアプリケーション権限およびロール(ポリシー・シード・データ)も定義します。このポリシー・シード・データは、アプリケーションのソース・コードとともにソース・コントロール・システムに格納されます。

19.7.2 デプロイメント・フェーズ

通常、開発後のアプリケーションは本番環境にデプロイする前にステージング環境でテストされます。本番環境では、アプリケーションと実行時サービスの両方が他のセキュリティ・コンポーネントと統合されます。このコンポーネントは、ユーザー・ディレクトリ、シングル・サインオン・システム、ユーザー・プロビジョニング・システム、監査機能などです。一般にセキュリティ・サービスはフェーズとともに変化します。たとえば、開発時は開発者がファイルまたはOracleウォレットを利用してユーザーの資格証明を格納しますが、本番環境では資格証明はLDAPディレクトリ(OPSSセキュリティ・ストア)に格納されます。

通常デプロイメント・フェーズでは、管理者がポリシー・シード・データを本番ポリシー・ストア(OPSSセキュリティ・ストア)に移行し、アプリケーション・ポリシーに応じてアプリケーション・ロールをエンタープライズ・グループにマッピングします。

19.7.3 管理フェーズ

管理フェーズは、アプリケーションが本番環境にデプロイされたときに開始します。このフェーズではアプリケーション管理者またはエンタープライズ・セキュリティ管理者が日常的なセキュリティ・タスクを管理します。このタスクにはアプリケーション・リソースへのユーザー・アクセス権限の付与、監査ログの確認、セキュリティ・インシデントへの対応、セキュリティ・パッチの適用などが含まれます。

19.7.4 各フェーズの担当者別タスクの概要

次の各表はセキュリティ・ライフ・サイクルのフェーズごとに、担当者別に主要な担当任務をまとめたものです。図19-4は、基本的なフローを示します。

図19-4 アプリケーション・ライフ・サイクルのフェーズ

図19-4については周囲のテキストで説明しています。

表19-1 アプリケーション設計者のセキュリティ・タスク

フェーズ タスク

開発

機能のセキュリティ要件およびデータのセキュリティ要件に基づいて高度なアプリケーション・ロールを定義します。

初期のファイルベースのアプリケーション・ポリシー・ストアを移入します(jazn-data.xml)。

デプロイメント

QAチームのテストに使用する実際のカスタマ・シナリオを定義します。

管理

アプリケーション・ポリシーのカスタマイズ要件を理解し、特定します。

垂直産業向けのテンプレートの定義を検討します。


表19-2 アプリケーション開発者のセキュリティ・タスク

フェーズ タスク

開発

特にOracle JDeveloperのツールおよびプロセスを使用して、アプリケーションを構築し、アプリケーション・ロールやパーミッションなどのセキュリティ・アーティファクトを作成します。

FND権限を使用して、データレベルのセキュリティを指定します。

ローカル・ポリシー・ストア使用し、サンプルのユーザーとロールでアプリケーションをテストします。

デプロイメント

QAチームによる実行時の問題のトラブルシューティングおよび解決を支援します。


表19-3 アプリケーション・セキュリティ管理者のセキュリティ・タスク

フェーズ タスク

デプロイメント

デプロイメント・サービスを使用して、jazn-data.xmlのセキュリティ・シード・データを本番ポリシー・ストアに移行します。

アプリケーション・ロールをエンタープライズ・グループにマッピングして、セキュリティ・ポリシーの適用を可能にします。

管理

必要に応じてソフトウェアにパッチおよびアップグレードを適用します。

企業のユーザーおよびアプリケーション・ロールの階層は時間とともに変化するため、それに応じてユーザーとロールを管理します。

アプリケーションにパッケージ化されたポリシーを管理し、新たなポリシーを作成します。

IAMインフラストラクチャとの統合および管理を行います。


19.8 付録 - コードおよび構成例

この項では、このガイドの他の章に記載されている、ほとんどのコード・サンプルと構成サンプルのリストおよび完全なコード例を示します。

19.8.1 コード例

次のリストは、一般的なセキュリティ関連のプログラミング・タスクおよび実装方法を示すサンプル・コードへのリンクです。

19.8.2 構成例

次のリストは、一般的なセキュリティ関連の構成タスクおよびサンプル構成へのリンクです。

19.8.3 セキュリティが統合されたJava EEアプリケーションの完全なコード例

ezshareは、セキュリティがOPSSに統合され、パーミッションベースの権限付与を使用し、Oracle Networkからダウンロード可能なJava EEアプリケーションの完全な例です。この例を見つけるには、キーワードezshareで検索してください。

19.9 付録 - JKSベースのキーストアを使用したアイデンティティの伝播

次の各項で、HTTPプロトコルを介したアイデンティティの伝播(JKSベースのキーストアを使用)について説明します。

19.9.1 単一ドメイン・シナリオ

このシナリオでは、クライアント・アプリケーションとサーブレット・アプリケーションは同じトラスト・サービス・インスタンスを使用して、トークンを発行および検証します。次のコードおよび構成サンプルは、同じドメイン内で実行されているクライアント・アプリケーションとサーブレット・アプリケーションのサンプルを示しています。

19.9.1.1 クライアント・アプリケーションのコード・サンプル

次のサンプルは、クライアント・アプリケーションを示しています。jps-api.jarファイルおよびOSDT jarファイルのosdt_ws_sx.jar、osdt_core.jar、osdt_xmlsec.jar、osdt_saml2.jarは、コード・サンプルがコンパイルするクラスパスに含める必要があることに注意してください。

// Authentication type name
public static final String AUTH_TYPE_NAME = "OIT";
// The authenticated username
String user = "weblogic"; 
// URL of the target application
URL url = "http://<host>:<port>/<destinationApp>"; 
//-----------------------------------------
JpsContextFactory ctxFactory = JpsContextFactory.getContextFactory();
JpsContext jpsCtx = ctxFactory.getContext();
final TrustService trustService = jpsCtx.getServiceInstance(TrustService.class);
final TokenManager tokenMgr = trustService.getTokenManager();
final TokenContext ctx = tokenMgr.createTokenContext(
    TokenConfiguration.PROTOCOL_EMBEDDED);
UsernameToken ut = WSSTokenUtils.createUsernameToken("wsuid", user);
GenericToken gtok = new GenericToken(ut);
ctx.setSecurityToken(gtok);
ctx.setTokenType(SAML2URI.ns_saml);
Map<String, Object> ctxProperties = ctx.getOtherProperties();
ctxProperties.put(TokenConstants.CONFIRMATION_METHOD,
    SAML2URI.confirmation_method_bearer);
 
AccessController.doPrivileged(new PrivilegedAction<String>() {
    public String run() {
        try {
            tokenMgr.issueToken(ctx);
        } catch (Exception e) {        
            e.printStackTrace();
        }
        return null;
    }
});
 
Token token = ctx.getSecurityToken();
String b64Tok = TokenUtil.encodeToken(token);
 
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(true);
connection.setReadTimeout(10000);
connection.setRequestProperty("Authorization", AUTH_TYPE_NAME + " " + b64Tok);
connection.connect();
BufferedReader rd = new BufferedReader(new InputStreamReader(
    connection.getInputStream()));
StringBuilder sb = new StringBuilder();
 
String line = null;
while ((line = rd.readLine()) != null) {
    sb.append(line);
}
connection.disconnect();
System.out.println(sb.toString());

19.9.1.2 キーストア・サービスの構成

次のコマンドでは、生成されたdefault-keystore.jksファイルで表されるキーストアの作成を示します。

JAVA_HOME/bin/keytool -genkeypair 
  -alias orakey 
  -keypass welcome 
  -keyalg RSA 
  -dname "CN=jrfServer_admin,O=Oracle,C=US" 
  -keystore default-keystore.jks 
  -storepass password
 
# the generated file must be placed on the domain configuration location
cp default-keystore.jks ${domain.home}/config/fmwconfig

jps-config.xmlファイル内で構成されているキーストア・サービスが、生成されたdefault-keystore.jksを指していることを確認します。次のサンプルは、キーストア・サービスの構成を示しています。

<!-- KeyStore Service Instance -->
<serviceInstance name="keystore" 
    provider="keystore.provider"  location="./default-keystore.jks">
    <description>Default JPS Keystore Service</description>
    <property name="keystore.provider.type" value="file"/>
    <property name="keystore.file.path" value="./"/>
    <property name="keystore.type" value="JKS"/>
    <property name="keystore.csf.map" value="oracle.wsm.security"/>
    <property name="keystore.pass.csf.key" value="keystore-csf-key"/>
    <property name="keystore.sig.csf.key" value="sign-csf-key"/>
    <property name="keystore.enc.csf.key" value="enc-csf-key"/>
</serviceInstance >

19.9.1.3 CSF構成

キーストアを開くために使用するマップ/キー・ペアと、トークンを発行するために使用する別のマップ/キー・ペアを作成します。次のコマンドは、OPSSスクリプトcreateCredを使用してこれらの操作を行う方法を示しています。

// JKS keystore opening password
createCred(map="oracle.wsm.security", key="keystore-csf-key", 
           user="keystore", password="password") 
 
// Private key password to issue tokens
createCred(map="oracle.wsm.security", key="sign-csf-key", 
           user="orakey", password="password")

OPSSスクリプトcreateCredの詳細は、第10.5項「OPSSスクリプトによる資格証明の管理」を参照してください。

19.9.1.4 権限付与の構成

次のようなコードソースの権限付与を含むシステム・ポリシーをポリシー・ストアに追加します。これは、クライアント・アプリケーションにトラスト・サービスAPIを使用することを許可します。

<grant>
  <grantee>
    <codesource>    
      <url>file:${oracle.deployed.app.dir}/<MyApp>${oracle.deployed.app.ext}</url>
    </codesource>
  </grantee>
  <permissions>
    <permission>          
<class>oracle.security.jps.service.trust.TrustServiceAccessPermission</class>
        <name>appId=*</name>
        <actions>issue</actions>
     </permission>
    </permissions>
</grant>

この権限付与を有効にするには、Oracle WebLogic Serverを停止してから再起動する必要があります。

19.9.1.5 サーブレット・コード

次のサンプルは、サーブレットがアサートされたユーザー名を取得する方法を示しています。

public void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {
   String username = request.getRemoteUser();
   ServletOutputStream out = response.getOutputStream();
   out.print("Asserted username: " + username);
   out.close();
}

19.9.1.6 web.xml構成

次に示すように、web.xmlファイルで適切なログイン方法を設定します。

<web-app id="WebApp_ID"
…
 <login-config>
   <auth-method>CLIENT-CERT</auth-method>
   <realm-name>Identity Assertion</realm-name>
 </login-config>
…
</web-app>

19.9.1.7 WebLogicアサーション・プロバイダとトラスト・サービスの構成

WebLogicアサーション・プロバイダとトラスト・サービスの構成

WebLogicアサーション・プロバイダを構成するには、次の手順を実行します。

  1. 次のコマンドに示すように、WebLogic IDアサーション・プロバイダJARであるjps-wls-trustprovider.jar${domain.home}/lib/mbeantypesにコピーし、WebLogic Serverを再起動します。

    cp ${common.components.home}/modules/oracle.jps_11.1.1/jps-wls-trustprovider.jar ${domain.home}/lib/mbeantypes
    
  2. WebLogicコンソールを使用して、アサーション・プロバイダを次のように構成します。

    1. 管理者としてコンソールにログインします。

    2. 「セキュリティ設定」→「セキュリティ・レルム」→「myrealm」→「プロバイダ」タブ→「認証」に移動し、「新規」をクリックして、「新しい認証プロバイダの作成」ダイアログを開きます。

    3. そのダイアログで、名前ボックスにTrustServiceIdentityAsserterと入力し、タイプ・ボックスのプルダウンからTrustServiceIdentityAsserterを選択し、「OK」をクリックします。

  3. ポリシー・ストアに次のような権限付与が存在することを確認します。この権限付与は、アサーション・プロバイダがOPSSトラスト・サービスAPIを使用するために必要です。必要であれば、WSLTスクリプトを使用して次のコードソース・システム・ポリシーを指定します。

    <grant>
        <grantee>
            <codesource>
                <url>file:${domain.home}/lib/mbeantypes/jps-wls-trustprovider.jar</url>
            </codesource>
        </grantee>
        <permissions>
            <permission>
                <class>oracle.security.jps.service.trust.TrustServiceAccessPermission</class>
                <name>appId=*</name>
                <actions>validate</actions>
            </permission>
        </permissions>
    </grant>
    

    jps-config.xmlファイルに変更を加えた場合、更新を有効にするにはサーバーを再起動する必要があります。

19.9.1.8 WebSphere Trust Asserter Interceptorの構成

この項目の詳細は、Oracle Fusion Middlewareサード・パーティ・アプリケーション・サーバー・ガイドのTrust Association Interceptorの構成に関する項を参照してください。

19.9.2 複数ドメイン・シナリオ

このシナリオでは、Domain1とDomain2という2つのドメインが存在します。クライアント・アプリケーションはDomain1で、サーブレット・アプリケーションはDomain2で実行されています。各ドメインには、「単一ドメイン・シナリオ」の「WebLogicアサーション・プロバイダとトラスト・ストアの構成」の説明に従って適切に構成されたトラスト・ストア・サービスとキーストアがそれぞれ存在することを前提とします。このシナリオでは、クライアント・アプリケーションはトークンの生成にDomain1のトラスト・サービスを使用し、サーブレット・アプリケーションはトークンの検証にDomain2のトラスト・サービスを使用します。

Domain1では、クライアントのサンプル・コードと次の構成は、「単一ドメイン・シナリオ」で説明したものと同じです。

Domain2では、サーブレットのサンプル・コードとweb.xmlの構成は、「単一ドメイン・シナリオ」で説明したものと同じですが、追加の設定が必要になります。

  • サーブレット・アプリケーションのコードについては、「サーブレット・コード」を参照してください。

  • web.xmlファイルの構成については、「web.xmlの構成」を参照してください。

  • Domain1でトークンを署名するために使用されたクライアント証明書がDomain2のキーストアに存在する必要があります。したがって、管理者は次の手順を実行します。

    1. 次のコマンドを使用して、Domain1のキーストアから証明書をエクスポートします。

      JAVA_HOME/bin/keytool -export
      -orakey orakey.cer
      -keystore default-keystore.jks
      -storepass password
      
    2. 次のコマンドで示されるように、Domain 2のキーストアに証明書をインポートします。証明書のインポートに使用される別名は、クライアント側の発行者名と一致する必要があることに注意してください。

      JAVA_HOME/bin/keytool -importcert 
        -alias orakey 
        -keypass welcome 
        -keyalg RSA 
        -keystore default-keystore.jks 
        -storepass password
      
    3. OPSSスクリプトcreateCredを次のように使用して、Domain2のキーストア・パスワードを(Domain2の)資格証明ストアで設定します。

      createCred(map="oracle.wsm.security", key="keystore-csf-key", user="keystore", password="password")
      

19.9.3 両方のプロトコルを使用するドメイン

このシナリオでは、アプリケーションはHTTPプロトコルまたはSOAPプロトコルのいずれかを使用し、ドメイン内のすべてのアプリケーションが同じプロトコルを使用するわけではありません。このようなシナリオでは、HTTPプロトコルで使用されるトラスト・サービスとOracle Web Services Managerで使用されるSOAPサービスで、キーストアを共有できます。ただしこの場合にトラスト・サービスが機能するには、次の各項で説明するように、jps-config.xmlファイルで特別な構成が必要になります。

19.9.3.1 単一ドメイン・シナリオ

このシナリオでは、キーストアは1つしかありません。次のスニペットは、別名がorakeyの証明書に必要な構成を示しています。

<propertySet name="trust.provider.embedded">
    <property name="trust.provider.className"
     value="oracle.security.jps.internal.trust.provider.embedded.EmbeddedProviderImpl"/>
    <property name="trust.clockSkew" value="60"/>
    <property name="trust.token.validityPeriod" value="1800"/>
    <property name="trust.token.includeCertificate" value="false"/>
    
    <!-- The alias used to get the signing certificate from JKS -->
    <property name="trust.aliasName" value="orakey"/> 
 
    <!-- The issuer name to be added in the token used by the destination
    trust service instance as an alias to pick up the corresponding certificate 
    to validate the token signature -->
    <property name="trust.issuerName" value="orakey"/>
</propertySet>

19.9.3.2 複数ドメイン・シナリオ

このシナリオでは、2つのドメインと2つのキーストアが存在します。次のスニペットは、別名がorakeyの証明書に対するトークンを発行するドメインに必要な構成を示しています。

<!-- issuer domain trust store must have a signing certif. w. alias orakey -->
<propertySet name="trust.provider.embedded">
    <property name="trust.provider.className"
        value="oracle.security.jps.internal.trust.provider.embedded.EmbeddedProviderImpl"/>
    <property name="trust.clockSkew" value="60"/>
    <property name="trust.token.validityPeriod" value="1800"/>
    <property name="trust.token.includeCertificate" value="false"/>
 
    <!-- the signing certificate alias in local JKS -->
    <property name="trust.aliasName" value="orakey"/> 
    
    <!-- the token issuer's name -->
    <property name="trust.issuerName" value="domain1"/> 
</propertySet>

注意1:

クライアント側では、trust.issuerNameの値はtrust.aliasNameと同じ値にすることができます。ただし、発行者名の値は、(前述の例で示されたように)trust.issuerNameに別の値を設定することで、上書きすることが可能です。この発行者名は、クライアント側で生成されたトークンに設定されます。

注意2:

サーバーがトークンの検証のみに使用される場合は、サーバー側でtrust.aliasNameおよびtrust.issuerNameの設定は必須ではありません。トークンの生成中に設定された発行者名が、サーバー側で証明書を検索する間、使用されます。このため、クライアントからインポートされた証明書は、クライアント側の発行者名を別名としてサーバー側にエクスポートされます(前述の例のdomain1)。


次のスニペットは、別名がorakeyの証明書に対するトークンを受け取るドメインに必要な構成を示しています。

<!- important: recipient domain must have a token validation certificate for domain1, 
which is the one was used to sign the token with alias "domain1" -->
<propertySet name="trust.provider.embedded">
    <property name="trust.provider.className"
        value="oracle.security.jps.internal.trust.provider.embedded.EmbeddedProviderImpl"/>
    <property name="trust.clockSkew" value="60"/>
    <property name="trust.token.validityPeriod" value="1800"/>
    <property name="trust.token.includeCertificate" value="false"/>
    
    <!-- the signing certificate alias in local JKS -->
    <property name="trust.aliasName" value="orakey"/> 
 
    <!-- the token issuer's name -->
    <property name="trust.issuerName" value="domain2"/> 
</propertySet>