プライマリ・コンテンツに移動
Oracle® Fusion Middleware Oracle Platform Security Servicesによるアプリケーションの保護
12c (12.2.1.1.0)
E77301-01
  目次へ移動
目次

前
 
次
 

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

この章では、ドメイン内およびドメイン間のアイデンティティの伝播を含め、様々なセキュリティのユースケースと、Oracle Application Development Framework (Oracle ADF)アプリケーション・セキュリティの一般的なライフ・サイクルについて説明します。

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

16.1 セキュリティの課題について

この章では、いくつかの一般的なセキュリティの課題を解決するユースケースを紹介します。これらのユースケースを、特定のアプリケーション・セキュリティ要件を解決するための出発点として使用します。対象読者は、開発者、セキュリティ設計者およびセキュリティ管理者であり、記載されている解決策では、宣言的アプローチとプログラム的アプローチの両方を提供します。

直面する上位のセキュリティの課題には、ユーザーの管理、ユーザー・パスワードの管理、リソースへのアクセスの制御などがあります。OPSSでは、次をサポートすることでこれらの課題に対する解決策を提供します。

  • 外部セキュリティ・アーティファクトのアプリケーション・ロジックからの分離

  • セキュリティに対する宣言的アプローチ

  • 完全なユーザー・アイデンティティ・ライフ・サイクル

  • ポリシー主導のアクセス制御

図16-1に、アプリケーションがセキュリティ・ストアにアクセスする方法と、それらの管理に使用するツールを示します。

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

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

関連項目:

第1.2項「OPSSアーキテクチャの概要」

Oracle Security Token Serviceを伴うOracle Fusion Middleware Oracle Access Manager管理者ガイド

Oracle Application Development FrameworkによるFusion Webアプリケーションの開発

『Oracle Fusion Middleware Reference for Oracle Security Developer Tools』

付録G「OPSS APIリファレンス」


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

次の各項では、ユースケースをいくつか紹介します。

各ユースケースには、解決を試みる問題の簡単な説明、関連するセキュリティおよび機能、詳細情報へのリンクが含まれています。

16.2.1 認証

次の各項では、認証のユースケースについて説明します。

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

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

  • 単一のLDAPストア。

  • 同じ種類の複数のLDAPストア。

  • 異なる種類の複数のLDAPストア(Microsoft Active DirectoryとOracle Internet Directoryなど)。

  • 単一のDBストア。

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

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

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

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

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

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

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

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

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

  • 複数のユーザー・リポジトリ - LDAPプロバイダを構成します。

  • DBリポジトリ - データベース・プロバイダを構成します。

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

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

デプロイメント・ディスクリプタを使用しないJava EEアプリケーションで、構成済のアイデンティティ・ストアに対してユーザーをプログラムにより認証する必要があります。

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

  • Javaコンテナ用の認証プロバイダの構成

  • ユーザーを認証するためのoracle.security.jps.service.login.LoginServiceインタフェースの使用

認証の詳細は、第23.1項「Java EEアプリケーションでの認証について」を参照してください。

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

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

このユースケースでは、認証先となるアイデンティティ・ストアを構成し、oracle.security.jps.service.login.LoginServiceインタフェースを使用する必要があります。Java SEアプリケーションで使用できるアイデンティティ・ログイン・モジュールは1つのみです。

プログラムによるログイン・モジュールの使用の詳細は、第24.3.3項「Java SEアプリケーションでのログイン・モジュールの使用」を参照してください。

16.2.2 アイデンティティ

次の各項では、アイデンティティのユースケースについて説明します。

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

2つの異なる環境で実行可能なアプリケーションで、LDAPストアに格納されているユーザー・プロファイル情報にアクセスする必要があります。LDAPサーバーは環境によって異なる場合があります。

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

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

  • 一方の環境では、Microsoft Active Directoryサーバーでメールが構成されています。

    mail.attr = msad_email
    
  • 他方の環境では、Oracle Identity Directoryサーバーでメールが構成されています。

    mail.attr = mail
    

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

Microsoft Active Directoryでは、アイデンティティ・ストア・プロバイダのnameプロパティを次のように設定します。

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

Oracle Identity Directoryでは、アイデンティティ・ストア・プロバイダのnameプロパティを次のように設定します。

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

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

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

アプリケーションで、複数のLDAPストア・サーバーにあるユーザー・プロファイル情報にアクセスする必要があります。このシナリオでは、複数のLDAPストア用に環境を構成する必要があります。手順の詳細は、第8.3.2.8項「単一および複数のLDAPの構成」を参照してください。

16.2.3 認可

次の各項では、認可のユースケースについて説明します。

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

Webディスクリプタで特定のロールが割り当てられたユーザーのみがアクセスできるJava EEアプリケーションの場合、グループ対ロールの割当ては、顧客の環境に基づいてデプロイ時に構成できる必要があります。

宣言によるセキュリティの詳細は、『WebLogicセキュリティ・サービスによるアプリケーションの開発』のWebアプリケーションでの宣言によるセキュリティの使用に関する項およびEJBでの宣言によるセキュリティの使用に関する項を参照してください。

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

アプリケーションのページ上の個々のコントロール・レベルでファイングレイン認可が必要なOracle ADFアプリケーションの場合、ポリシーを外部化し、アプリケーションのデプロイ後にカスタマイズする必要があります。


関連項目:

「Oracle ADFアプリケーションの保護」

『Oracle Application Development FrameworkによるFusion Webアプリケーションの開発』の「Fusion WebアプリケーションでのADFセキュリティの有効化」


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

アプリケーションで、ファイングレイン認可を使用してWebサービスを保護する必要があります。Webサービスの詳細は、『Oracle Web Services ManagerによるWebサービスの保護とポリシーの管理』を参照してください。

16.2.3.4 コードソース・パーミッションが必要なJava EEアプリケーション

Java EEアプリケーションで、特定のアクションを実行するためにコードソース・パーミッションが必要です。典型的な例として、資格証明ストアからの資格証明の読取りやポリシーの検索があります。パーミッションの詳細は、「権限付与の構成」を参照してください。

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

非Oracle ADFアプリケーションで、ファイングレイン認可チェックが必要です。このシナリオでは、次のようにします。

  • アプリケーション・コードにチェックを挿入します。

  • 適切なポリシーを構成します。

プログラムによるポリシーの管理およびチェックの詳細は、第17.3項「JAAS/OPSS認可モデル」を参照してください。

16.2.4 資格証明

次の項では、資格証明のユースケースについて説明します。

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

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

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

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

  • アプリケーション・コード内での資格証明ストア・フレームワークAPIによる実行時の資格証明のフェッチ

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

16.2.5 監査

次の各項では、監査のユースケースについて説明します。

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

このユースケースで説明する設定は、ドメイン内のすべてのアプリケーションおよびコンポーネントに当てはまります。ドメイン内で実行されているアプリケーションで、ポリシー、資格証明または鍵がいつ変更されたかと、特定の時間間隔内に評価されたポリシーを記録する必要があります。

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

  • アプリケーションとOracle Platform Security Services共通監査フレームワークとの統合。

  • セキュリティ領域内でのアプリケーションの監査カテゴリおよび監査イベントの定義と、アプリケーションの監査対応化。

  • 各アプリケーションでの適切なフィルタ・レベルの設定。

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

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

このシナリオを実現するには、ビジネス・ニーズに基づいて監査イベントを作成し、アプリケーションでイベント・アクティビティを監査ストアに記録します。さらに、監査イベントから監査レポートを生成し、実行時監査ポリシーを管理し、必要に応じて監査イベント定義を変更します。

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

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

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

  • Oracle Enterprise Manager Fusion Middleware Control (Fusion Middleware Control)またはWebLogic Scripting Tool (WLST)コマンドを使用した監査アーティファクトの管理。

16.2.6 アイデンティティ伝播

次の各項では、アイデンティティ伝播のユースケースについて説明します。

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

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

OWSMの詳細は、『Oracle Web Services ManagerによるWebサービスの保護とポリシーの管理』を参照してください。

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

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

このユースケースでは、アプリケーションで伝播する特定のアイデンティティを資格証明ストアから取得し、OWSM機能を使用してそのアイデンティティをリモート・サーバーに伝播します。

OWSMの詳細は、『Oracle Web Services ManagerによるWebサービスの保護とポリシーの管理』を参照してください。

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

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

ドメインの信頼の詳細は、『Oracle WebLogic Server WebLogic Webサービスの保護』のWebLogic Serverドメイン間の信頼の有効化に関する項を参照してください。

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

コンテナ内のクライアント・アプリケーションで、HTTPを介してアイデンティティを伝播する必要があります。OPSSトラスト・サービスを使用して実現することをお薦めします。

16.2.7 管理

次の各項では、管理のユースケースについて説明します。

16.2.7.1 集中管理されたストアが必要なアプリケーション

アプリケーションで、ポリシー、資格証明、監査構成、信頼および鍵の中央リポジトリと、それを管理する一連のツールが必要です。このユースケースを実現するには、OPSSサービスおよびツールを使用してセキュリティ・サービスを管理します。

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

アプリケーションで、外部化したセキュリティ・データを管理するためのカスタム・ツールが必要です。このユースケースを実現するには、アプリケーションに有意味なコンテキストでセキュリティ・データを表示および管理するためのOPSS APIをコールするカスタム・グラフィカル・ユーザー・インタフェースを作成する必要があります。

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

管理サーバーで変更を開始し、管理対象サーバーのデータがキャッシュ・ポリシーに基づいてリフレッシュされる場合に、ドメイン(複数のサーバー・インスタンスが複数のマシンに分散されている)内で実行されているアプリケーションで、セキュリティ・データの変更を伝播する必要があります。どこで実行されているかにかかわらず、アプリケーションのすべてのコンポーネントで変更を反映する必要があります。このユースケースを実現するには、OPSS MBeanまたはOPSS APIを使用してセキュリティ・データを変更します。

16.2.8 統合

製品で、複数のWebLogic Serverドメインを実行する必要があり、これらのドメインは単一の中央セキュリティ・ストアを共有する必要があります。このユースケースを実現するには、他のドメイン内のストアに結合するためのreassociateSecurityStoreコマンドと、複数のドメインが1つの集中管理されたセキュリティ・ストアを共有するためのOPSSのサポートを使用します。

セキュリティ・ストアへの結合がサポートされるのは、新しいドメインを作成する場合のみです。

16.3 OPSSトラスト・サービス

OPSSトラスト・サービスでは、アイデンティティ・アサータを使用してトークンの提供および検証が行われるため、アプリケーションではHTTP対応のアプリケーション間でアイデンティティを伝播できます。


関連項目:

第F.2.6項「トラスト・サービスのプロパティ」

『Oracle Fusion Middlewareインフラストラクチャ・セキュリティWLSTコマンド・リファレンス』のupdateTrustServiceConfigに関する項


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


注意:

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

図16-2に、HTTPを使用したアイデンティティ伝播の典型的なフローを示します。

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

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

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

  4. アサータがDomain2のOPSSトラスト・インスタンスからのそのトークンの検証をリクエストします。

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

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

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

図16-2 HTTPを介したアイデンティティ伝播

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

すぐに使用できる構成では、鍵の別名はサーバー名に基づいて設定されています。

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

複数のドメイン間または単一ドメイン内の複数のコンテナ間でアイデンティティを伝播するには、次の各項で説明しているように、OPSSトラスト・サービスを使用することをお薦めします。

16.5.1 複数のWebLogic Serverドメイン間でのアイデンティティの伝播

このユースケースでは、2つの異なるWebLogic ServerドメインDomain1とDomain2があります。クライアント・アプリケーションはDomain1で、JavaサーブレットはDomain2で実行されています。クライアント・アプリケーションではトークンの生成にDomain1のサービスを使用し、Javaサーブレットではトークンの検証にDomain2のサービスを使用します。

次の各項では、このユースケースを実現するための例と構成を示します。

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

トークンが生成されるクライアント側(Domain1)で、次の作業を実行します。

16.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());
16.5.1.1.2 トラストストアの構成

トラストストアは、クライアント証明書および秘密鍵を使用してプロビジョニングする必要があります。証明書は、キーストアからエクスポートされ、トラストストアにインポートされます。キーストアとトラストストアはいずれも、クライアント・ドメイン内でキーストア・サービス(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="", algorithm="RSA")
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()
16.5.1.1.3 TrustServiceAccessPermission権限の追加

次の権限(アプリケーションの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>

この権限は、grantPermission WLSTコマンドを使用してセキュリティ・ストアに追加するか、アプリケーションがJava EEアプリケーションであり、jazn-data.xmlファイルがアプリケーションとともにパックされる場合は、アプリケーションのデプロイ時にセキュリティ・ストアに移行されます。


関連項目:

『Oracle Fusion Middlewareインフラストラクチャ・セキュリティWLSTコマンド・リファレンス』のgrantPermissionに関する項

第23.3項「フィルタおよびインターセプタの構成」


16.5.1.1.4 プロバイダの構成

次の例は、トラスト・プロバイダのプロパティを示しています。

<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>

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

トークンが検証されるサーバー側(Domain2)で、次の作業を実行します。

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

まず、Javaサーブレット・コードで、アサートされたユーザーを取得します。

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();
}
16.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>
16.5.1.2.3 アサータの構成

次のいずれかの方法でアサータを構成します。

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

    このアサータは、トラスト・メソッドをコールして着信リクエストからのトークンをデコードして検証し、ユーザー名を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()
    
16.5.1.2.4 キーストアのプロビジョニング

次の例に示すように、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()
16.5.1.2.5 パーミッションの追加

grantPermission WLSTコマンドを使用して、アプリケーションのjazn-data.xmlファイルにコードソースの権限付与を追加します。

たとえば、次のコードソースの権限付与は、MyAppアプリケーションでトラスト・メソッドを使用するのに必要です。

<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>

関連項目:

『Oracle Fusion Middlewareインフラストラクチャ・セキュリティWLSTコマンド・リファレンス』のgrantPermissionに関する項


16.5.1.2.6 プロバイダの構成

次の例は、トラスト・プロバイダのプロパティを示しています。

<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属性は、トークンの検証には使用されないため、オプション属性です。この場合、トークンを検証するために、プロバイダではトークンに含まれている名前を使用して証明書を探します。

16.5.2 単一のWebLogic Serverドメイン内のコンテナ間でのアイデンティティの伝播

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

16.5.3 トラスト・プロバイダのプロパティ

トラスト・プロバイダを構成するには、次のプロパティを使用します。

  • trust.keyStoreType

  • trust.keyStoreName

  • trust.trustStoreName

  • trust.aliasName

  • trust.issuerName

  • trust.provider.className

  • trust.clockSkew

  • trust.token.validityPeriod

  • trust.token.includeCertificate

次の例は、トラスト・プロバイダ構成の例を示しています。

<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>

トラスト・プロバイダのプロパティを変更するには、updateTrustServiceConfig WLSTコマンドを使用します。このコマンドの詳細は、『Oracle Fusion Middlewareインフラストラクチャ・セキュリティWLSTコマンド・リファレンス』のupdateTrustServiceConfifに関する項を参照してください。

16.6 カスタム・グラフィカル・ユーザー・インタフェースの実装

この項では、ポリシーを管理するためにカスタム・グラフィカルUIを実装する場合などに必要な操作の一部を示します。各例では、OPSS APIを使用し、次の方法に関するデモを示します。

  • アイデンティティ・ストアへのユーザーのキューイング。

  • セキュリティ・ストアへのアプリケーション・ロールのキューイング。

  • ユーザーおよびグループからアプリケーション・ロールへのマッピングのキューイング。具体的には、ユーザーが自分にマップされているすべてのアプリケーション・ロールを特定する場合です(ユーザーおよびグループからアプリケーション・ロールへのマッピングは多対多の関係です)。

  • ユーザーおよびグループからアプリケーション・ロールへのマッピングの作成、読取り、更新および削除。

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

  • アイデンティティ・ストアは、LDAPストアです。

  • セキュリティ・ストアは、LDAPストアです。

  • アイデンティティ・ストアには、次のユーザーおよびグループの階層があります。

    • ユーザー: Mary、John、TomおよびHelen。

    • グループ: IT、TrainingおよびDevelopment。

    • グループITのメンバー: グループTrainingおよびDevelopment。

    • グループTrainingのメンバー: ユーザーMary。

    • グループDevelopmentのメンバー: ユーザーTomおよびJohn。

  • セキュリティ・ストアには、次のアプリケーション・ポリシーおよびアプリケーション・ロールの階層があります。

    • アプリケーション・ポリシー: ApplicationPolicy1およびApplicationPolicy2。

    • ポリシーApplicationPolicy1で参照されるアプリケーション・ロール: ロールSystem Manager、System DeveloperおよびSystem Analyst。ロールSystem Managerは、ロールSystem Developerのメンバーです。ロールSystem Developerは、ロールSystem Analystのメンバーです。

    • ポリシーApplicationPolicy2で参照されるアプリケーション・ロール: ロールDirector、InstructorおよびLecturer。ロールDirectorは、ロールInstructorのメンバーです。ロールInstructorは、ロールLecturerのメンバーです。

  • アプリケーション・ロールは、次のようにユーザーおよびグループにマップされています。

    • ロールSystem ManagerはユーザーHelenにマップされています。

    • ロールSystem DeveloperはグループDevelopmentにマップされています。

    • ロールDirectorはユーザーTomにマップされています。

    • ロールInstructorはグループTrainingおよびDevelopmentにマップされています。

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

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

アプリケーション・ロールからユーザーおよびグループへのマッッピング

このロール階層は、ロールSystem ManagerのユーザーはロールSystem Developerにも含まれ、他のロールについても同様であることを意味します。4人のユーザーそれぞれのロール・メンバーシップをまとめると、次のとおりです。

  • ユーザーTomは、アプリケーション・ロールSystem Developer、System Analyst、Director、InstructorおよびLecturerのメンバーです。

  • ユーザーHelenは、アプリケーション・ロールSystem Manager、System DeveloperおよびSystem Analystのメンバーです。

  • ユーザーMaryは、アプリケーション・ロールInstructorおよびLecturerのメンバーです。

  • ユーザーJohnは、アプリケーション・ロールSystem Developer、System Analyst、InstructorおよびLecturerのメンバーです。

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

16.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;

16.6.2 アイデンティティ・ストアの問合せの例

次の例は、アイデンティティ・ストア内のユーザーに対する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();
    }

16.6.3 ロールの作成の例

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

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();
    }

16.6.4 ロールの問合せの例

次の例は、アプリケーション・ロールを問い合せる方法をいくつか示しています。

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();
    }

16.6.5 ロールのマッピングの例

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

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();
    }

16.6.6 ユーザーが含まれるロールの取得の例

次の例は、特定のユーザーを含むロールをすべて取得する方法を示しています。

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.
        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());
            }
        }
    }

16.6.7 ロール・マッピングの削除の例

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

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();
    }

16.7 Oracle ADFアプリケーションの保護

次の各項では、Oracle JDeveloperを使用して開発したOracle ADFアプリケーションで実行される一般的なタスクについて説明します。

関係する担当者は、アプリケーション製品マネージャ、開発者およびセキュリティ管理者です。

16.7.1 開発フェーズ

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

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

また、アプリケーションの保護に必要なアプリケーション権限およびロールを多数定義しますが、このデータはアプリケーションのソース・コードとともにソース制御システムに格納されます。

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

アプリケーションを開発したら、本番環境にデプロイする前にステージング環境でテストします。本番環境では、アプリケーションとランタイム・サービスは、シングル・サインオン、ユーザー・プロビジョニング、監査などの他のセキュリティ・コンポーネントと統合されます。

通常、セキュリティ・サービスのタイプはフェーズとともに変化します。たとえば、開発時は資格証明をファイルまたはOracleウォレットに格納しますが、本番環境ではLDAPサーバーに格納します。

デプロイメント・フェーズでは、ポリシーを本番のセキュリティ・ストアに移行し、アプリケーション・ポリシーに応じてアプリケーション・ロールをエンタープライズ・グループにマップします。

16.7.3 管理フェーズ

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

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

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

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

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

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

フェーズ タスク

開発

機能のセキュリティ要件およびデータのセキュリティ要件に基づいてアプリケーション・ロールをおおまかに定義します。初期のセキュリティ・ストアにデータを移入します。

デプロイメント

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

管理

アプリケーション・ポリシーのカスタマイズ要件を理解し、特定します。垂直産業向けのテンプレートの定義を検討します。


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

フェーズ タスク

開発

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

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

ローカル・セキュリティ・ストアをユーザーおよびロールとともに使用してアプリケーションをテストします。

デプロイメント

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


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

フェーズ タスク

デプロイメント

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

セキュリティ・ポリシーを施行できるように、アプリケーション・ロールをエンタープライズ・グループにマップします。

管理

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

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

アプリケーションとともにパックされたポリシーを管理し、新しいポリシーを作成します。

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


16.8 コードおよび構成例

次の各項では、このガイドの他の章に記載されているコードおよび構成の例を示します。

16.9 JKSを使用したアイデンティティの伝播

すぐに使用できる構成では、トークン名および鍵の別名はサーバー名に基づいて設定されています。これらのデフォルト値を変更するには、第16.9.1.8項「トラスト・パラメータの更新」で説明されている手順を使用します。

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

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

このシナリオでは、クライアントとJavaサーブレットはいずれも同じサービスを使用して、トークンを生成および検証します。次の各項では、クライアントおよびJavaサーブレットが同じドメイン内で実行されている場合のアイデンティティ伝播の実装に必要なタスクについて説明します。

16.9.1.1 クライアント・アプリケーションの作成

次の例は、クライアント・アプリケーションを示しています。jps-api.jarファイルおよびosdt_ws_sx.jarosdt_core.jarosdt_xmlsec.jarosdt_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());

16.9.1.2 キーストアの構成

サーバー名をjrfServer_adminとした場合、次のコマンドは、生成された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 >

16.9.1.3 マップおよびキーの構成

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

// 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")

createCredの詳細は、第11.4項「WLSTを使用した資格証明の管理」を参照してください。

16.9.1.4 権限付与の構成

トラスト・メソッドの使用をクライアント・アプリケーションに許可するコードソースの権限付与を含むシステム・ポリシーを追加します。

<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>

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

16.9.1.5 Javaサーブレットの作成

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

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();
}

16.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>

16.9.1.7 アサータの構成

アサータを構成するには、次の手順を実行します。

  1. jps-wls-trustprovider.jarアイデンティティ・アサーション・ファイルを${domain.home}/lib/mbeantypesにコピーします。

    cp ${common.components.home}/modules/oracle.jps_12.2.1/jps-wls-trustprovider.jar ${domain.home}/lib/mbeantypes
    
  2. WebLogic Serverを再起動します。

  3. WebLogic Server管理コンソールを使用してアサータを構成します。

    1. 管理者としてログインし、「セキュリティ設定」「セキュリティ・レルム」「プロバイダ」「認証」タブの順に移動し、「新規」をクリックします。「新規認証プロバイダの作成」ダイアログが表示されます。

    2. このダイアログで、名前のテキスト・フィールドにTrustServiceIdentityAsserterと入力し、プルダウン・リストからTrustServiceIdentityAsserterを選択します。次に、「OK」をクリックします。

  4. セキュリティ・ストアに次のような権限付与が存在することを確認します。この権限付与は、アサータでOPSSトラスト・メソッドを使用できるようにするために必要です。

    <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ファイルを変更した場合は、サーバーの再起動が必要です。

16.9.1.8 トラスト・パラメータの更新

この項では、スクリプトの実行によってjps-config.xmlファイルのトラスト・パラメータを変更する方法について説明します。

デフォルトでは、trust.aliasNameパラメータとtrust.issuerNameパラメータはサーバー名に設定されています。これらの値を変更するには、次のように変更したスクリプトを使用します。

import sys
 
wlsAdmin = 'weblogic'
wlsPwd ='password_value'
wlUrl='t3://localhost:7001'
issuer= 'issuer'
alias = 'alias'
 
print "OPSS Trust Service provider configuration management script.\n"
 
instance = 'trust.provider'
name = 'trust.provider.embedded'
cfgProps = HashMap()
cfgProps.put("trust.issuerName", issuer)
cfgProps.put("trust.aliasName", alias)
pm = PortableMap(cfgProps);
 
connect(wlsAdmin, wlsPwd, wlUrl)
domainRuntime()
 
params = [instance, name, pm.toCompositeData(None)]
sign = ["java.lang.String", "java.lang.String", "javax.management.openmbean.CompositeData"]
on = ObjectName("com.oracle.jps:type=JpsConfig")
mbs.invoke(on, "updateTrustServiceConfig", params, sign)
mbs.invoke(on, "persist", None, None)
 
print "Done.\n"

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

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

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

Domain2では、Javaサーブレットのコードとweb.xmlの構成は、「単一ドメイン・シナリオ」で説明したものと同じです。

  • Javaサーブレットのコードについては、「Javaサーブレットの作成」を参照してください。

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

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

    1. 証明書をDomain 1のキーストアからエクスポートします。

      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. createCred WLSTコマンドを使用して、Domain2のキーストア・パスワードを(Domain2の)資格証明ストアで設定します。

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

    『Oracle Fusion Middlewareインフラストラクチャ・セキュリティWLSTコマンド・リファレンス』のcreateCredに関する項を参照してください。

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

このシナリオでは、アプリケーションではHTTPまたはSOAPのいずれかを使用し、ドメイン内のすべてのアプリケーションが同じプロトコルを使用するわけではありません。このようなシナリオでは、キーストアをHTTPサービスとSOAPサービスで共有できます。

次の各項では、この場合に必要となる特殊な構成について説明します。

16.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 add in the token used by the target
    trust service instance as an alias to pick up the corresponding certificate 
    to validate the token signature -->
    <property name="trust.issuerName" value="orakey"/>
</propertySet>

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

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

<!-- issuer domain truststore 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>

クライアント側では、trust.issuerNameの値はtrust.aliasNameと同じ値にすることができます。ただし、名前の値は、(例で示しているように)trust.issuerNameに別の値を設定することで、オーバーライドできます。この名前は、クライアント側で生成されたトークンに設定されます。

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

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

<!- the 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>