Oracle® Fusion Middleware Oracle Platform Security Servicesによるアプリケーションの保護 12c (12.2.1) E72537-01 |
|
前 |
次 |
この章では、ドメイン内およびドメイン間のアイデンティティの伝播を含め、様々なセキュリティのユースケースと、Oracle Application Development Framework (Oracle ADF)アプリケーション・セキュリティの一般的なライフ・サイクルについて説明します。
この章の内容は次のとおりです。
この章では、いくつかの一般的なセキュリティの課題を解決するユースケースを紹介します。これらのユースケースを、特定のアプリケーション・セキュリティ要件を解決するための出発点として使用します。対象読者は、開発者、セキュリティ設計者およびセキュリティ管理者であり、記載されている解決策では、宣言的アプローチとプログラム的アプローチの両方を提供します。
直面する上位のセキュリティの課題には、ユーザーの管理、ユーザー・パスワードの管理、リソースへのアクセスの制御などがあります。OPSSでは、次をサポートすることでこれらの課題に対する解決策を提供します。
外部セキュリティ・アーティファクトのアプリケーション・ロジックからの分離
セキュリティに対する宣言的アプローチ
完全なユーザー・アイデンティティ・ライフ・サイクル
ポリシー主導のアクセス制御
図16-1に、アプリケーションがセキュリティ・ストアにアクセスする方法と、それらの管理に使用するツールを示します。
関連項目: 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』 |
次の各項では、ユースケースをいくつか紹介します。
各ユースケースには、解決を試みる問題の簡単な説明、関連するセキュリティおよび機能、詳細情報へのリンクが含まれています。
次の各項では、認証のユースケースについて説明します。
認証されたユーザーが必要なJava EEアプリケーション - Java EEアプリケーションにアクセスするには、ユーザーは認証を受ける必要があります。
プログラム認証が必要なJava EEアプリケーション - Java EEアプリケーションで、ユーザーをプログラムにより認証する必要があります。
認証が必要なJava SEアプリケーション - Java SEアプリケーションで、ドメイン・アイデンティティ・ストアに対して認証を行う必要があります。
Java EEアプリケーションにアクセスするために、ユーザーはアイデンティティ・ストアに対して認証される必要があり、この場合、アイデンティティ・ストアは次のいずれかになります。
単一のLDAPストア。
同じ種類の複数のLDAPストア。
異なる種類の複数のLDAPストア(Microsoft Active DirectoryとOracle Internet Directoryなど)。
単一のDBストア。
複数のLDAPストアおよびDBストア。
このユースケースでは、次のことが求められます。
アプリケーションへのアクセスを認証されたユーザーにのみ許可する
顧客が別のリポジトリでユーザー・アイデンティティを管理している場合でも、アプリケーション・コードは変更しない
このユースケースでは、次の機能を使用します。
特定のユーザー・リポジトリのセットに応じた適切な認証プロバイダの構成。
LDAPタイプが混在するか、LDAPタイプとDBタイプが混在する場合の認証プロバイダの構成。
使用されているリポジトリに応じて、このユースケースの詳細は、次のシナリオに分かれます。
単一のユーザー・リポジトリ - 適切なWebLogic認証プロバイダを構成します。
複数のユーザー・リポジトリ - LDAPプロバイダを構成します。
DBリポジトリ - データベース・プロバイダを構成します。
認証プロバイダの詳細は、第3.2.1項「WebLogic認証プロバイダ」を参照してください。
デプロイメント・ディスクリプタを使用しないJava EEアプリケーションで、構成済のアイデンティティ・ストアに対してユーザーをプログラムにより認証する必要があります。
このユースケースでは、ユーザーを認証するためにOPSS APIを使用する必要があり、次の機能を使用します。
Javaコンテナ用の認証プロバイダの構成
ユーザーを認証するためのoracle.security.jps.service.login.LoginService
インタフェースの使用
認証の詳細は、第23.1項「Java EEアプリケーションでの認証について」を参照してください。
Java SEアプリケーションで、ドメイン内で使用されているLDAPアイデンティティ・ストアに対してユーザーを認証する必要があります。認証をリクエストするアプリケーション・コードは、ドメインのアイデンティティ・ストアの詳細に関係なく同じである必要があります。
このユースケースでは、認証先となるアイデンティティ・ストアを構成し、oracle.security.jps.service.login.LoginService
インタフェースを使用する必要があります。Java SEアプリケーションで使用できるアイデンティティ・ログイン・モジュールは1つのみです。
プログラムによるログイン・モジュールの使用の詳細は、第24.3.3項「Java SEアプリケーションでのログイン・モジュールの使用」を参照してください。
次の各項では、アイデンティティのユースケースについて説明します。
2つの環境で実行されるアプリケーション - 2つの異なる環境で実行されるアプリケーションで、単一のLDAPストア内のユーザー・プロファイル情報にアクセスする必要があります。
複数のストア内のユーザー・プロファイルにアクセスするアプリケーション - アプリケーションで、複数のLDAPストアに格納されたユーザー・プロファイル情報にアクセスする必要があります。
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項「アイデンティティ・ストア・プロバイダの構成」を参照してください。
アプリケーションで、複数のLDAPストア・サーバーにあるユーザー・プロファイル情報にアクセスする必要があります。このシナリオでは、複数のLDAPストア用に環境を構成する必要があります。手順の詳細は、第8.3.2.8項「単一および複数のLDAPの構成」を参照してください。
次の各項では、認可のユースケースについて説明します。
特定のロールのみアクセス可能なJava EEアプリケーション - Webディスクリプタで構成されているユーザーのみがアクセスできるJava EEアプリケーションです。
ファイングレイン認可が必要なOracle ADFアプリケーション - Oracle ADFアプリケーションにファイングレイン認可が必要です。
Webサービスを保護するアプリケーション - アプリケーションで、Webサービスを保護する必要があります。
コードソース・パーミッションが必要なJava EEアプリケーション - Java EEアプリケーションにコードソース・パーミッションが必要です。
ファイングレイン認可が必要な非Oracle ADFアプリケーション - 非Oracle ADFアプリケーションにファイングレイン認可が必要です。
Webディスクリプタで特定のロールが割り当てられたユーザーのみがアクセスできるJava EEアプリケーションの場合、グループ対ロールの割当ては、顧客の環境に基づいてデプロイ時に構成できる必要があります。
宣言によるセキュリティの詳細は、『WebLogicセキュリティ・サービスによるアプリケーションの開発』のWebアプリケーションでの宣言によるセキュリティの使用に関する項およびEJBでの宣言によるセキュリティの使用に関する項を参照してください。
アプリケーションのページ上の個々のコントロール・レベルでファイングレイン認可が必要なOracle ADFアプリケーションの場合、ポリシーを外部化し、アプリケーションのデプロイ後にカスタマイズする必要があります。
関連項目: 『Oracle Application Development FrameworkによるFusion Webアプリケーションの開発』の「Fusion WebアプリケーションでのADFセキュリティの有効化」 |
アプリケーションで、ファイングレイン認可を使用してWebサービスを保護する必要があります。Webサービスの詳細は、『Oracle Web Services ManagerによるWebサービスの保護とポリシーの管理』を参照してください。
Java EEアプリケーションで、特定のアクションを実行するためにコードソース・パーミッションが必要です。典型的な例として、資格証明ストアからの資格証明の読取りやポリシーの検索があります。パーミッションの詳細は、「権限付与の構成」を参照してください。
非Oracle ADFアプリケーションで、ファイングレイン認可チェックが必要です。このシナリオでは、次のようにします。
アプリケーション・コードにチェックを挿入します。
適切なポリシーを構成します。
プログラムによるポリシーの管理およびチェックの詳細は、第17.3項「JAAS/OPSS認可モデル」を参照してください。
次の項では、資格証明のユースケースについて説明します。
システムへのアクセスに資格証明が必要なアプリケーション - アプリケーションにバックエンド・システムにアクセスするための資格証明が必要です。
あるアプリケーションには、データベースまたはLDAPサーバーなどのバックエンド・システムに接続するために資格証明が必要です。アプリケーション・コードは、デプロイメント後にアプリケーション・コードを変更することなく顧客ごとに資格証明の詳細が変更可能になるよう、この資格証明を参照する必要があります。さらにこのユースケースでは、資格証明ストアにアクセスできるユーザー、および認可されたユーザーが資格証明ストアで実行できる操作を指定する必要もあります。
このユースケースでは、次の機能を使用します。
資格証明を永続化するための資格証明ストアの使用
アプリケーション・コード内での資格証明ストア・フレームワークAPIによる実行時の資格証明のフェッチ
コードソースでのシステム・ポリシーの定義と施行
次の各項では、監査のユースケースについて説明します。
セキュリティ関連アクティビティの監査 - アプリケーションは、セキュリティ関連のアクティビティを記録する必要があります。
ビジネス関連アクティビティの監査 - アプリケーションは、フローのコンテキストでビジネス・アクティビティを記録する必要があります。
このユースケースで説明する設定は、ドメイン内のすべてのアプリケーションおよびコンポーネントに当てはまります。ドメイン内で実行されているアプリケーションで、ポリシー、資格証明または鍵がいつ変更されたかと、特定の時間間隔内に評価されたポリシーを記録する必要があります。
このユースケースでは、次の機能を使用します。
アプリケーションとOracle Platform Security Services共通監査フレームワークとの統合。
セキュリティ領域内でのアプリケーションの監査カテゴリおよび監査イベントの定義と、アプリケーションの監査対応化。
各アプリケーションでの適切なフィルタ・レベルの設定。
このユースケースで説明する設定は、ドメイン内のすべてのアプリケーションおよびコンポーネントに当てはまります。アプリケーションで、機能フローのコンテキストでビジネス関連アクティビティを記録する必要があります。具体的には、ユーザーおよびそのユーザーにより特定の間隔で実行されるビジネス・アクションのロギングを行う必要があります。
このシナリオを実現するには、ビジネス・ニーズに基づいて監査イベントを作成し、アプリケーションでイベント・アクティビティを監査ストアに記録します。さらに、監査イベントから監査レポートを生成し、実行時監査ポリシーを管理し、必要に応じて監査イベント定義を変更します。
このユースケースでは、次の機能を使用します。
アプリケーションがビジネス機能領域(監査カテゴリとして)、ビジネス・アクティビティ(カテゴリ内の監査イベントとして)、および各カテゴリ内に属性を定義することを可能にする
デプロイ時のアプリケーションの登録、監査定義の更新、デプロイ後のアプリケーションの登録解除。
Oracle Enterprise Manager Fusion Middleware Control (Fusion Middleware Control)またはWebLogic Scripting Tool (WLST)コマンドを使用した監査アーティファクトの管理。
次の各項では、アイデンティティ伝播のユースケースについて説明します。
コンテナ内のクライアント・アプリケーションで、シンプル・オブジェクト・アクセス・プロトコル(SOAP)を介してWebサービスに実行ユーザー・アイデンティティを伝播する必要があります。Webサービスは、同じドメイン内(同じまたは異なる管理対象サーバー)でも異なるドメイン内でも実行されています。
OWSMの詳細は、『Oracle Web Services ManagerによるWebサービスの保護とポリシーの管理』を参照してください。
コンテナ内のクライアント・アプリケーションで、SOAPを介してWebサービスにユーザー・アイデンティティ(実行ユーザー・アイデンティティとは異なる)を伝播する必要があります。
このユースケースでは、アプリケーションで伝播する特定のアイデンティティを資格証明ストアから取得し、OWSM機能を使用してそのアイデンティティをリモート・サーバーに伝播します。
OWSMの詳細は、『Oracle Web Services ManagerによるWebサービスの保護とポリシーの管理』を参照してください。
コンテナ内のクライアント・アプリケーションで、ユーザー・アイデンティティ(セキュリティ・ストアに格納されている)を、別のWebLogic Serverドメインに伝播する必要があります。
ドメインの信頼の詳細は、『Oracle WebLogic Server WebLogic Webサービスの保護』のWebLogic Serverドメイン間の信頼の有効化に関する項を参照してください。
コンテナ内のクライアント・アプリケーションで、HTTPを介してアイデンティティを伝播する必要があります。OPSSトラスト・サービスを使用して実現することをお薦めします。
次の各項では、管理のユースケースについて説明します。
アプリケーションで、ポリシー、資格証明、監査構成、信頼および鍵の中央リポジトリと、それを管理する一連のツールが必要です。このユースケースを実現するには、OPSSサービスおよびツールを使用してセキュリティ・サービスを管理します。
アプリケーションで、外部化したセキュリティ・データを管理するためのカスタム・ツールが必要です。このユースケースを実現するには、アプリケーションに有意味なコンテキストでセキュリティ・データを表示および管理するためのOPSS APIをコールするカスタム・グラフィカル・ユーザー・インタフェースを作成する必要があります。
管理サーバーで変更を開始し、管理対象サーバーのデータがキャッシュ・ポリシーに基づいてリフレッシュされる場合に、ドメイン(複数のサーバー・インスタンスが複数のマシンに分散されている)内で実行されているアプリケーションで、セキュリティ・データの変更を伝播する必要があります。どこで実行されているかにかかわらず、アプリケーションのすべてのコンポーネントで変更を反映する必要があります。このユースケースを実現するには、OPSS MBeanまたはOPSS APIを使用してセキュリティ・データを変更します。
製品で、複数のWebLogic Serverドメインを実行する必要があり、これらのドメインは単一の中央セキュリティ・ストアを共有する必要があります。このユースケースを実現するには、他のドメイン内のストアに結合するためのreassociateSecurityStore
コマンドと、複数のドメインが1つの集中管理されたセキュリティ・ストアを共有するためのOPSSのサポートを使用します。
セキュリティ・ストアへの結合がサポートされるのは、新しいドメインを作成する場合のみです。
OPSSトラスト・サービスでは、アイデンティティ・アサータを使用してトークンの提供および検証が行われるため、アプリケーションではHTTP対応のアプリケーション間でアイデンティティを伝播できます。
関連項目: 『Oracle Fusion Middlewareインフラストラクチャ・セキュリティWLSTコマンド・リファレンス』のupdateTrustServiceConfigに関する項 |
図16-2に、HTTPを使用したアイデンティティ伝播の典型的なフローを示します。
Domain1のクライアント・アプリケーションが、認証されたユーザーについて、Domain1のOPSSトラスト・インスタンスからのトークンをリクエストします。
サービスがDomain1のキーストアにアクセスし、クライアント・アプリケーション用にトークンを生成します。
クライアント・アプリケーションがトークンをHTMLヘッダー内にエンコードし、HTTPリクエストをDomain2のJavaサーブレットにディスパッチします。Domain 2のアサーション・プロバイダがリクエストをインターセプトし、トークンを抽出します。
アサータがDomain2のOPSSトラスト・インスタンスからのそのトークンの検証をリクエストします。
サービスがトークンを検証するためにDomain2のキーストアにアクセスし、レスポンスを返します。
検証が成功したとみなし、アサータはアサートされたアイデンティティを使用してリクエストをJavaサーブレットに送信します。
Javaサーブレットが、クライアント・アプリケーションのリクエストに対するHTTPレスポンスを送信します。
すぐに使用できる構成では、鍵の別名はサーバー名に基づいて設定されています。
複数のドメイン間または単一ドメイン内の複数のコンテナ間でアイデンティティを伝播するには、次の各項で説明しているように、OPSSトラスト・サービスを使用することをお薦めします。
このユースケースでは、2つの異なるWebLogic ServerドメインDomain1とDomain2があります。クライアント・アプリケーションはDomain1で、JavaサーブレットはDomain2で実行されています。クライアント・アプリケーションではトークンの生成にDomain1のサービスを使用し、Javaサーブレットではトークンの検証にDomain2のサービスを使用します。
次の各項では、このユースケースを実現するための例と構成を示します。
トークンが生成されるクライアント側(Domain1)で、次の作業を実行します。
クライアント・アプリケーションは、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());
トラストストアは、クライアント証明書および秘密鍵を使用してプロビジョニングする必要があります。証明書は、キーストアからエクスポートされ、トラストストアにインポートされます。キーストアとトラストストアはいずれも、クライアント・ドメイン内でキーストア・サービス(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()
次の権限(アプリケーションの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に関する項 |
次の例は、トラスト・プロバイダのプロパティを示しています。
<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>
トークンが検証されるサーバー側(Domain2)で、次の作業を実行します。
まず、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(); }
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>
次のいずれかの方法でアサータを構成します。
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()
次の例に示すように、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()
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に関する項 |
次の例は、トラスト・プロバイダのプロパティを示しています。
<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
属性は、トークンの検証には使用されないため、オプション属性です。この場合、トークンを検証するために、プロバイダではトークンに含まれている名前を使用して証明書を探します。
このユースケースでは、クライアント・アプリケーションとサーバー・アプリケーションは同じドメインで稼働し、どちらのアプリケーションも同じキーストアを使用できるため、(その他のキーストアに)クライアント証明書をインポートする必要はありません。その他の情報はすべて、複数ドメインのシナリオで説明された内容と同じです。
トラスト・プロバイダを構成するには、次のプロパティを使用します。
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に関する項を参照してください。
この項では、ポリシーを管理するためにカスタム・グラフィカル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に、アプリケーション・ロール、ユーザーおよびグループのこの階層と、アプリケーション・ロールからユーザーおよびグループへのマッピングを示します。
このロール階層は、ロール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のメンバーです。
例の詳細は、次の各項を参照してください。
各例では、次の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;
次の例は、アイデンティティ・ストア内のユーザーに対する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(); }
次の例は、アプリケーション・ロールを作成する方法と、ロールを別のロールのメンバーにする方法を示しています。
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(); }
次の例は、アプリケーション・ロールを問い合せる方法をいくつか示しています。
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(); }
次の例は、アプリケーション・ロールをユーザーおよびグループにマップする方法を示しています。
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(); }
次の例は、特定のユーザーを含むロールをすべて取得する方法を示しています。
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()); } } }
次の例は、アプリケーション・ロールからグループへのマッピングを削除する方法を示しています。
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(); }
次の各項では、Oracle JDeveloper (JDeveloper)を使用して開発したOracle ADFアプリケーションで実行される一般的なタスクについて説明します。
関係する担当者は、アプリケーション製品マネージャ、開発者およびセキュリティ管理者です。
開発フェーズでは、開発者によってOracle Fusion Middlewareで使用可能な広範なセキュリティ・オプション機能がアプリケーションと連携するように設計されます。開発者は、JDeveloper、組込みのOracle ADFフレームワークおよびOracle WebLogic Server(これらすべてにより、アプリケーションの存続期間全体にわたってセキュリティへの一貫したアプローチが保証されます)で公開される豊富な一連のセキュリティ・サービスを利用できます。
ADFセキュリティ・ウィザード(認可エディタ)および式言語エディタを使用しますが、いずれもJDeveloper内にあります。さらに、必要に応じて、OPSS APIを使用してより複雑なセキュリティ・タスクを実行することもできます。このように、アプリケーションのある部分では宣言によるセキュリティを使用し、別の部分ではプログラムによるセキュリティを使用しますが、いずれも開発環境および実行時環境で使用可能なセキュリティ機能に基づいています。
また、アプリケーションの保護に必要なアプリケーション権限およびロールを多数定義しますが、このデータはアプリケーションのソース・コードとともにソース制御システムに格納されます。
アプリケーションを開発したら、本番環境にデプロイする前にステージング環境でテストします。本番環境では、アプリケーションとランタイム・サービスは、シングル・サインオン、ユーザー・プロビジョニング、監査などの他のセキュリティ・コンポーネントと統合されます。
通常、セキュリティ・サービスのタイプはフェーズとともに変化します。たとえば、開発時は資格証明をファイルまたはOracleウォレットに格納しますが、本番環境ではLDAPサーバーに格納します。
デプロイメント・フェーズでは、ポリシーを本番のセキュリティ・ストアに移行し、アプリケーション・ポリシーに応じてアプリケーション・ロールをエンタープライズ・グループにマップします。
管理フェーズは、アプリケーションを本番環境にデプロイした後に始まります。このフェーズでは、アプリケーション・リソースへのアクセス権のユーザーへの付与、監査ログの確認、セキュリティ・インシデントへの対応、セキュリティ・パッチの適用など、日常的なセキュリティ・タスクを管理します。
次の各表はセキュリティ・ライフ・サイクルのフェーズごとに、担当者別に主要な担当任務をまとめたものです。図16-4は、基本的なフローを示します。
表16-1 アプリケーション設計者のセキュリティ・タスク
フェーズ | タスク |
---|---|
開発 |
機能のセキュリティ要件およびデータのセキュリティ要件に基づいてアプリケーション・ロールをおおまかに定義します。初期のセキュリティ・ストアにデータを移入します。 |
デプロイメント |
QA (品質保証)チームのテストに使用する実際のカスタマ・シナリオを定義します。 |
管理 |
アプリケーション・ポリシーのカスタマイズ要件を理解し、特定します。垂直産業向けのテンプレートの定義を検討します。 |
表16-2 アプリケーション開発者のセキュリティ・タスク
フェーズ | タスク |
---|---|
開発 |
ツールおよびプロセス(特にJDeveloper)を使用して、アプリケーションを構築し、アプリケーション・ロールやパーミッションなどのセキュリティ・データを作成します。 権限付与を使用して、データレベルのセキュリティを指定します。 ローカル・セキュリティ・ストアをユーザーおよびロールとともに使用してアプリケーションをテストします。 |
デプロイメント |
QAチームによる実行時の問題のトラブルシューティングおよび解決を支援します。 |
表16-3 アプリケーション・セキュリティ管理者のセキュリティ・タスク
フェーズ | タスク |
---|---|
デプロイメント |
デプロイメント・サービスを使用して、 セキュリティ・ポリシーを施行できるように、アプリケーション・ロールをエンタープライズ・グループにマップします。 |
管理 |
必要に応じて、ソフトウェアにパッチおよびアップグレードを適用します。 エンタープライズ・ユーザーおよびアプリケーション・ロールの階層は時間とともに変化するため、それに応じてユーザーとロールを管理します。 アプリケーションとともにパックされたポリシーを管理し、新しいポリシーを作成します。 アイデンティティ・インフラストラクチャとの統合および管理を行います。 |
次の各項では、このガイドの他の章に記載されているコードおよび構成の例を示します。
次の各項では、一般的なセキュリティ関連のプログラミング・タスクの例が記載されています。
すぐに使用できる構成では、トークン名および鍵の別名はサーバー名に基づいて設定されています。これらのデフォルト値を変更するには、第16.9.1.8項「トラスト・パラメータの更新」で説明されている手順を使用します。
次の各項では、Javaキーストア(JKS)を使用してHTTPを介したアイデンティティの伝播について説明します。
このシナリオでは、クライアントとJavaサーブレットはいずれも同じサービスを使用して、トークンを生成および検証します。次の各項では、クライアントおよびJavaサーブレットが同じドメイン内で実行されている場合のアイデンティティ伝播の実装に必要なタスクについて説明します。
次の例は、クライアント・アプリケーションを示しています。jps-api.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());
サーバー名を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 >
キーストアを開くために使用するマップ/キー・ペアと、トークンを生成するために使用する別のマップ/キー・ペアを作成します。次のコマンドは、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を使用した資格証明の管理」を参照してください。
トラスト・メソッドの使用をクライアント・アプリケーションに許可するコードソースの権限付与を含むシステム・ポリシーを追加します。
<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を停止して再起動する必要があります。
次の例は、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(); }
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>
アサータを構成するには、次の手順を実行します。
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
WebLogic Serverを再起動します。
WebLogic Server管理コンソールを使用してアサータを構成します。
管理者としてログインし、「セキュリティ設定」→「セキュリティ・レルム」→「プロバイダ」→「認証」タブの順に移動し、「新規」をクリックします。「新規認証プロバイダの作成」ダイアログが表示されます。
このダイアログで、名前のテキスト・フィールドにTrustServiceIdentityAsserter
と入力し、プルダウン・リストからTrustServiceIdentityAsserter
を選択します。次に、「OK」をクリックします。
セキュリティ・ストアに次のような権限付与が存在することを確認します。この権限付与は、アサータで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
ファイルを変更した場合は、サーバーの再起動が必要です。
この項では、スクリプトの実行によって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"
このシナリオでは、Domain1とDomain2という2つのドメインが存在します。クライアント・アプリケーションはDomain1で、JavaサーブレットはDomain2で実行されています。この2つのドメインそれぞれに、「単一ドメイン・シナリオ」の説明に従って適切に構成されたトラスト・サービスが1つあることを前提とします。クライアントではトークンの生成にDomain1のトラスト・サービスを使用し、Javaサーブレットではトークンの検証にDomain2のトラスト・サービスを使用します。
Domain1では、クライアントのコードと次の構成は、「単一ドメイン・シナリオ」で説明したものと同じです。
クライアント・アプリケーションについては、「クライアント・アプリケーションの作成」を参照してください。
キーストアの構成については、「キーストアの構成」を参照してください。
資格証明ストア・フレームワークの構成については、「マップおよびキーの構成」を参照してください。
権限付与の構成については、「権限付与の構成」を参照してください。
Domain2では、Javaサーブレットのコードとweb.xml
の構成は、「単一ドメイン・シナリオ」で説明したものと同じです。
Javaサーブレットのコードについては、「Javaサーブレットの作成」を参照してください。
web.xml
ファイルの構成については、「web.xmlの構成」を参照してください。
Domain1でトークンの署名に使用されたクライアント証明書はDomain2のキーストアに存在する必要があります。そのためには、次の手順を実行します。
証明書をDomain 1のキーストアからエクスポートします。
JAVA_HOME/bin/keytool -export -orakey orakey.cer -keystore default-keystore.jks -storepass password
その証明書をDomain 2のキーストアにインポートします。証明書のインポートに使用された別名はクライアント側の証明書の名前と一致する必要があります。
JAVA_HOME/bin/keytool -importcert -alias orakey -keypass welcome -keyalg RSA -keystore default-keystore.jks -storepass password
createCred
WLSTコマンドを使用して、Domain2のキーストア・パスワードを(Domain2の)資格証明ストアで設定します。
createCred(map="oracle.wsm.security", key="keystore-csf-key", user="keystore", password="password")
『Oracle Fusion Middlewareインフラストラクチャ・セキュリティWLSTコマンド・リファレンス』のcreateCredに関する項を参照してください。
このシナリオでは、アプリケーションではHTTPまたはSOAPのいずれかを使用し、ドメイン内のすべてのアプリケーションが同じプロトコルを使用するわけではありません。このようなシナリオでは、キーストアをHTTPサービスとSOAPサービスで共有できます。
次の各項では、この場合に必要となる特殊な構成について説明します。
このシナリオでは、キーストアは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>
このシナリオでは、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>