注意:
この章では、SSLについては説明しません。SSLの詳細な説明は、「SSLを使用した通信の保護」を参照してください。
この章の内容は次のとおりです。
アクセス・コントローラは、クラスタ・リソースおよび操作へのアクセスを保護します。コール元の認証にはローカルのログイン・モジュールが使用され、1つ以上のクラスタ・ノードにあるアクセス・コントローラは、コール元のアクセス権を検証します。ログイン・モジュールの詳細は、JAASリファレンス・ガイドを参照してください。
アクセス・コントローラは、次のことを行います。
コール元の権限に基づいて、保護されているクラスタ化リソースへのアクセスを付与または拒否します。
コール元のプライベート資格証明に基づいて送信通信を暗号化します。
コール元のパブリック資格証明に基づいて受信通信を復号化します。
デフォルト・アクセス・コントローラの実装が提供されています。この実装は、HotSpot JDKの標準コンポーネントとして出荷されるキー管理インフラストラクチャに基づいています。「デフォルト・アクセス・コントローラの実装の使用方法」を参照してください。
図3-1 は、アクセス・コントローラを使用して2つのクラスタ・メンバーを保護する場合の概念を示しています。
セキュリティ・コンテキストの理解
クラスタ化サービスごとに、上位のサービス・メンバーの概念が維持されており、これが特定のサービスの制御エージェントの役割を果たしています。上位のメンバーは、クラスタ化リソースにアクセスするときに他のメンバーと情報のやり取りをしません。しかし、サービスに参加する下位のメンバーは、上位のメンバーにリクエストして確認を得る必要があります。上位のメンバーは、参加メンバーについて他のすべてのクラスタ・メンバーに通知します。
データはクラスタ・メンバー間に分散されるため、セキュリティ・サブシステムは、ある程度の耐環境性を意図して設計されています。すべてのメンバーは悪意のあるメンバーと見なされます。つまりメンバーは、クラスタ化サービスに参加したり、クラスタ化リソースにアクセスするための十分な資格証明を持っていないと想定されています。
ファイル・システム・メカニズムおよび標準のJavaセキュリティ・ポリシーは、単一ノードの信頼性を保証します。ただし、メンバーの通信について考慮すべき2つのシナリオがあります。
悪質なノードがローカル・アクセス・チェックを迂回して、クラスタ化サービスに参加したり、信頼できるノードが管理しているクラスタ化リソースにアクセスしたりしようとします。
悪質なノードがクラスタ化サービスまたはクラスタ化リソースを作成し、そのコントローラになります。
セキュリティ・サブシステムは、これら2つのシナリオが発生しないようにするために、双方向の暗号化アルゴリズムを使用します。すべてのクライアント・リクエストはIDを証明する必要があり、すべてのサービス・レスポンスは信頼性を証明する必要があります。
IDの証明
次のクライアント・コードの例では、コール元を認証し、必要なアクションを実行します。
import com.tangosol.net.security.Security; import java.security.PrivilegedAction; import javax.security.auth.Subject; ... Subject subject = Security.login(sName, acPassword); PrivilegedAction action = new PrivilegedAction() { public Object run() { // all processing here is taking place with access // rights assigned to the corresponding Subject // for example: CacheFactory.getCache().put(key, value); ... } }; Security.runAs(subject, action);
login
コール時に、コール元は、コール元のノード上のJAASを使用して認証されます。認証に成功すると、ローカルのアクセス・コントローラが次の処理を行います。
ローカルのコール元に、保護されているクラスタ化リソースにアクセスできる権限があるかどうかを確認します(ローカル・アクセス・チェック)。
認証フェーズで取得したコール元のプライベート資格証明を使用して、リソースへのアクセスに関する送信通信を暗号化します。
リクエスタのパブリック資格証明を使用して、リモート・チェックの結果を復号化します。
レスポンダがアクセス権付与対象としての十分な権限を持っているかどうかを検証します。
暗号化の手順では、レスポンダのIDの証明が提供され、悪質なノードがローカル・アクセス・チェック・フェーズをパスしたかのように偽装する事態を防ぐことができます。
クライアント認証情報は、次の2つの方法でも提供できます。1つ目の方法は、ユーザー名とパスワードのかわりにCallbackHandler
クラスへの参照を渡すことです。2つ目の方法は、すでに認証済のSubject
を使用することです。後者の方法は、Java EEアプリケーションがOracle Coherenceを使用しており、アプリケーション・コンテナから認証済のSubject
を取得する場合に適しています。
コール元のリクエストに認証コンテキストが含まれていない場合、CallbackHandler
実装がインスタンス化されコールされます。オペレーション・オーバーライド・ファイルで実装が宣言され、適切な資格証明が取得されます。ただし、この遅延アプローチは非常に非効率的です。外部で定義されたコール・スコープがないと、保護されているクラスタ化リソースにアクセスするたびに、認証コールが強制的に繰り返し実行されるためです。
信頼性の証明
クラスタ化メンバーは、明示的なAPIコールを使用してクラスタ化リソースを作成します。上位のサービス・メンバーは、このコール時に提示されたプライベート資格証明を、信頼性の証明として保持します。上位のサービス・メンバーが、保護されているクラスタ化リソースに対するアクセス・リクエストを受信すると、ローカル・アクセス・コントローラは次の処理を行います。
リモートのコール元のパブリック資格証明を使用して、受信通信を復号化します。
サービスのプライベート資格証明を使用して、アクセス・チェックのレスポンスを暗号化します。
リモートのコール元に、保護されているクラスタ化リソースにアクセスできる権限があるかどうかを確認します(リモート・アクセス・チェック)。
標準的なJavaキーストアを使用するデフォルト・アクセス・コントローラの実装が提供されています。実装クラスは、com.tangosol.net.security.DefaultController
クラスです。これは、オペレーション・デプロイメント・ディスクリプタの<security-config
要素内で構成されています。<security-config要素およびそのサブ要素の詳細は、『Oracle Coherenceでのアプリケーションの開発』を参照してください。デフォルト・アクセス・コントローラを使用するには、この項の手順を実行してください。
この項には次のトピックが含まれます:
<security-config>
要素内でデフォルト・アクセス・コントローラの実装を有効にするには、true
に設定された<enabled>
要素を追加します。次に例を示します。
<security-config> <enabled system-property="coherence.security">true</enabled> </security-config>
coherence.security
システム・プロパティもアクセス・コントローラを有効にできます。次に例を示します。
-Dcoherence.security=true
注意:
アクセス・コントローラ・セキュリティが有効になっている場合、CacheFactory.getCache()
またはConfigurableCacheFactory.ensureCache()
APIへのコールごとにセキュリティ・チェックが行われます。これらのコールが頻繁に実行されると、これはアプリケーションのパフォーマンスに悪影響を及ぼします。ベスト・プラクティスは、アプリケーションがキャッシュ参照を保持し、それを再使用することにより、セキュリティ・チェックが初期コール時にのみ実行されるようにすることです。この方法の場合は、アプリケーションが、認可された方法でのみ参照を使用するようにしてください。
アクセス・コントローラは、コントローラとログイン・モジュールの両方で使用されるキーストアを必要とします。Java keytool
ユーティリティを使用して、必要なプリンシパルを持つキーストアを作成します。実行時にキーストアがクラスパス上に確実に見つかるようにするか、coherence.security.keystore
システム・プロパティを使用してキーストアの名前と場所を明示的に入力します。次に例を示します。
-Dcoherence.security.keystore=keystore.jks
次の例では、admin
(Javaセキュリティ・フレームワークで使用)、manager
、およびworker
(Oracle Coherenceで使用)という3つのプリンシパルを作成します。
keytool -genkey -v -keystore ./keystore.jks -storepass password -alias admin -keypass password -dname CN=Administrator,O=MyCompany,L=MyCity,ST=MyState keytool -genkey -v -keystore ./keystore.jks -storepass password -alias manager -keypass password -dname CN=Manager,OU=MyUnit keytool -genkey -v -keystore ./keystore.jks -storepass password -alias worker -keypass password -dname CN=Worker,OU=MyUnit
Oracle Coherenceには、COHERENCE_HOME
/lib/security/
coherence-login.jar
Javaキーストア(JKS)ログイン・モジュールが組み込まれています。これは、標準的なJavaランタイム・クラスにのみ依存します。JRE lib/ext
(標準拡張)ディレクトリにライブラリを配置します。<security-config>
要素内の<login-module-name>
要素の名前は、COHERENCE_HOME
/lib/security/login.config
ログイン・モジュール・ファイル内でアプリケーション名の役割を果たします。ログイン・モジュール宣言には、キーストアへのパスが含まれています。keyStorePath
変数をキーストアの場所に変更します。
// LoginModule Configuration for Oracle Coherence Coherence { com.tangosol.security.KeystoreLogin required keyStorePath="${user.dir}${/}security${/}keystore.jks"; };
アクセス・コントローラは、プリンシパルのアクセス権を宣言するpermissions.xml
ファイルを必要とします。パーミッション・ファイルの構文については、COHERENCE_HOME
/lib/security/permissions.xsd
スキーマを参照してください。実行時にファイルがクラスパス上に確実に見つかるようにするか、coherence.security.permissions
システム・プロパティを使用してパーミッション・ファイルの名前と場所を明示的に入力します。次に例を示します。
-Dcoherence.security.permissions=permissions.xml
次の例では、Manager
プリンシパルにはすべてのパーミッションを、名前の先頭にcommon
が付いているキャッシュのWorker
プリンシパルにはjoin
のパーミッションのみを、invocation
という名前の起動サービスのWorker
プリンシパルにはすべてのパーミッションを割り当てます。
<?xml version='1.0'?> <permissions> <grant> <principal> <class>javax.security.auth.x500.X500Principal</class> <name>CN=Manager,OU=MyUnit</name> </principal> <permission> <target>*</target> <action>all</action> </permission> </grant> <grant> <principal> <class>javax.security.auth.x500.X500Principal</class> <name>CN=Worker,OU=MyUnit</name> </principal> <permission> <target>cache=common*</target> <action>join</action> </permission> <permission> <target>service=invocation</target> <action>all</action> </permission> </grant> </permissions>
他のすべての認証方式が成功しなかった場合、アクセス・コントローラは、認証コールバック・ハンドラを使用してクライアントを認証します。コールバック・ハンドラを作成するには、javax.security.auth.callback.CallbackHandler
インタフェースを実装します。
注意:
このハンドラ・アプローチは非常に非効率的です。外部で定義されたコール・スコープがないと、保護されているクラスタ化リソースにアクセスするたびに、認証コールが強制的に繰り返し実行されるためです。
<security-config>
要素内でカスタム・コールバック・ハンドラを構成するには、実装クラスの完全修飾名を含む<callback-handler>
要素を追加します。次の例では、MyCallbackHandler
という名前のコールバック・ハンドラを構成します。
<security-config> <callback-handler> <class-name>package.MyCallbackHandler</class-name> </callback-handler> </security-config>
セキュリティ監査ログを使用して、各ユーザーが実行しているクラスタ操作を追跡できます。それぞれの操作は、出力されるログ・メッセージに表示されます。次に例を示します。
"Destroy" action for cache "Accounts" has been permitted for the user "CN=Bob, OU=Accounting".
セキュリティ監査ログは、デフォルトで有効ではありません。監査ログを<security-config>
要素内で有効にするには、セキュリティ・ログ初期化パラメータを<access-controller>
要素内でオーバーライドし、パラメータ値をtrue
に設定します。次に例を示します。
<security-config> <access-controller> <init-params> <init-param id="3"> <param-type>boolean</param-type> <param-value system-property="coherence.security.log"> true</param-value> </init-param> </init-params> </access-controller> </security-config>
coherence.security.log
システム・プロパティもセキュリティ監査ログを有効にできます。次に例を示します。
-Dcoherence.security.log=true
カスタム・アクセス・コントローラでは、com.tangosol.net.security.AccessController
インタフェースを実装する必要があります。このAPIの使用方法の詳細は、Oracle Coherence Java APIリファレンスを参照してください。<security-config
要素内でカスタム・アクセス・コントローラを構成するには、実装クラスの完全修飾名を含む<access-controller
要素を追加します。次の例では、MyAccessController
というカスタム・アクセス・コントローラを構成します。
<security-config> <enabled system-property="coherence.security">true</enabled> <access-controller> <class-name>package.MyAccessController</class-name> </access-controller> </security-config>
<init-params>
要素を使用して、必要な初期化パラメータを指定します。次の例には、MyAccessController
クラスにキーストアとパーミッション・ファイルを渡すパラメータが含まれています。
<security-config> <enabled system-property="coherence.security">true</enabled> <access-controller> <class-name>package.MyAccessController</class-name> <init-params> <init-param> <param-type>java.io.File</param-type> <param-value>./keystore.jks</param-value> </init-param> <init-param> <param-type>java.io.File</param-type> <param-value>./permissions.xml</param-value> </init-param> </init-params> </access-controller> </security-config>