Oracle Containers for J2EE
セキュリティ・ガイド
10g(10.1.3.4.0) B50832-01 |
|
この章では、EJBに影響するセキュリティの問題について説明します。この章の内容は次のとおりです。
OC4J 10.1.3.x実装を開始するにあたり、EJBコンテナによってOracleAS JAAS Providerがサポートされます。
関連項目
|
標準のEJBデプロイメント・ディスクリプタでセキュリティ制約およびJ2EEロールを定義することで、EJBメソッドを保護できます。これらのJ2EEロールは、アプリケーションで定義したロールにリンクし、さらに必要に応じてセキュリティ・プロバイダ内のデプロイ・ロールにマップできます。(EJBの場合は、たとえばEJBがアクセスするバックエンド・データベース内のロールにデプロイ・ロールが対応している場合があります。)デプロイ・ロールへのマッピングは、デプロイ時にApplication Server Controlを介して実行でき(「Application Server Controlを介したセキュリティ・ロール・マッピングの指定」を参照)、それによってOC4J固有のデプロイメント・ディスクリプタに適切な構成が生成されます。
この項では、認証と認可についてEJBデプロイメント・ディスクリプタ内のXML構成に重点を置いて説明します。EJBの認可は、次のように処理されます。
system-jazn-data.xml
、jazn-data.xml
、Oracle Internet Directoryなどで構成)にマップされます。図18-1は、EJBロール定義およびロール・マッピング(この場合はファイルベース・プロバイダが対象)の概要を示しています。
EJBの認可の手順を次の各項で説明します。
トラブルシューティングのヒント
次の図18-2に示すように、Bean実装内で定義されているロールの名前(POMgr
など)を指定し、この名前を標準のEJBデプロイメント・ディスクリプタで定義されている適切なJ2EEユーザーまたはロール(myMgr
など)にリンクすることができます。(次の手順であるデプロイ・ロールへのマッピングは、OC4J固有のデプロイメント・ディスクリプタに反映されます
(「J2EEロールからデプロイ・ユーザーおよびデプロイ・ロールへのマッピング」を参照)。)
この設定を、次の手順でさらに詳しく説明します。
POMgr
など)を、標準のEJBデプロイメント・ディスクリプタの<enterprise-beans>
セクションにある<security-role-ref>
要素の<role-name>
サブ要素で宣言します。(この例では、このロールに発注権限があるものと想定しています。このロールには、発注と連動するように、isCallerInRole()
コールによる確認に従ってコール元をマップする必要があります。) <security-role-ref>
の<role-link>
サブ要素を使用して、アプリケーション・ロールを目的のJ2EE論理ロールにリンクします(これは、次の手順で標準のEJBデプロイメント・ディスクリプタにも定義します)。この機能によって、様々なJ2EE環境でBeanコードを変更することなくアプリケーションを使用できるようになります。アプリケーション・ロールPOMgr
は、J2EEロールmyMgr
にリンクされます。
<enterprise-beans> ... <security-role-ref> <role-name>POMgr</role-name> <role-link>myMgr</role-link> </security-role-ref> ... </enterprise-beans>
(<role-link>
設定内のJ2EEロールは、デプロイ・ロールと同じにするか、または後述の手順でデプロイ・ロールにマップできます。)
PurchaseOrder
内で実行されるあらゆるメソッドが、自己をmyMgr
として認可している必要があります。これは、<security-role>
の<role-name>
サブ要素で宣言されるJ2EEロールです。このJ2EEロールは、前の手順でアプリケーション・ロールPOMgr
にリンクされたものです。PurchaseOrder
は、<session>
または<entity>
要素のサブ要素である、<ejb-name>
要素内で宣言されている名前であることに注意してください。 次の例では、ロールmyMgr
を定義し、このロールにEJB PurchaseOrder
Beanのすべてのメソッド(*
記号で指定)にアクセスするためのパーミッションを付与しています。
<assembly-descriptor> ... <security-role> <description>Role for purchase order authorization</description> <role-name>myMgr</role-name> </security-role> <method-permission> <role-name>myMgr</role-name> <method> <ejb-name>PurchaseOrder</ejb-name> <method-name>*</method-name> </method> </method-permission> ... </assembly-descriptor>
手順1および2を実行すると、Bean実装内でPOMgr
を参照できるようになり、OC4JによりPOMgr
がmyMgr
にマップされます。
<method-permission>
要素をさらに詳しく見てみると、<method>
サブ要素を使用して、インタフェースまたは実装内で1つ以上のメソッドのセキュリティ・ロールが指定されています。EJB仕様によれば、この定義には次のいずれかの書式を使用できます。
*
文字を使用して、Bean内のすべてのメソッドを定義します。
<method-permission> <role-name>myMgr</role-name> <method> <ejb-name>EJBNAME</ejb-name> <method-name>*</method-name> </method> </method-permission>
<method-permission> <role-name>myMgr</role-name> <method> <ejb-name>myBean</ejb-name> <method-name>myMethodInMyBean</method-name> </method> </method-permission>
<method-permission> <role-name>myMgr</role-name> <method> <ejb-name>myBean</ejb-name> <method-name>myMethod</method-name> <method-params> <method-param>java.lang.String</method-param> <method-param>java.lang.String</method-param> </method-params> </method> </method-permission>
各パラメータは、メソッドの入力パラメータの完全修飾Java型です。メソッドに入力引数がない場合、<method-params
>要素にサブ要素は含まれません。
特定のメソッドをセキュリティ・ロールのチェック対象外にする場合は、次のように標準のEJBデプロイメント・ディスクリプタを使用して、それらのメソッドをチェック対象外として定義します。
<method-permission> <unchecked/> <method> <ejb-name>EJBNAME</ejb-name> <method-name>*</method-name> </method> </method-permission>
<role-name>
要素のかわりに、空の<unchecked>
要素を定義します。EJBNAME
Bean内のメソッドを実行すると、コンテナではセキュリティ・チェックが実行されません。チェック対象外のメソッドは、常に他のロール定義より優先されます。
標準のEJBデプロイメント・ディスクリプタで、EJBのすべてのメソッドが特定のアイデンティティを使用して実行されるように指定できます。つまり、コンテナでは、様々なロールで特定のメソッドを実行するためのパーミッションはチェックされず、指定されたセキュリティ・アイデンティティを使用するEJBメソッドがすべて実行されます。特定のロールまたはコール元のアイデンティティをセキュリティ・アイデンティティとして指定できます。
<enterprise-beans>
セクションの<security-identity>
要素内でrun-asセキュリティ・アイデンティティを指定します。次の例は、POMgr
ロールの下ですべてのエンティティBeanメソッドが実行されることを示しています。
<enterprise-beans> <entity> ... <security-identity> <run-as> <role-name>POMgr</role-name> </run-as> </security-identity> ... </entity> ... </enterprise-beans>
また、次の例に、Beanのすべてのメソッドをコール元のアイデンティティを使用して実行するように指定する方法を示します。
<enterprise-beans> <entity> ... <security-identity> <use-caller-identity/> </security-identity> ... </entity> </enterprise-beans>
前述したように、標準のEJBデプロイメント・ディスクリプタでJ2EEロールおよび関連するセキュリティ制約を定義して、EJBメソッドを保護できます。定義したJ2EEロールは、セキュリティ・プロバイダで定義されているデプロイ・ユーザーおよびロールにマップできます。このセキュリティ・ロールのマッピングは、「Application Server Controlを介したセキュリティ・ロール・マッピングの指定」で説明しているように、デプロイ中にApplication Server Controlを使用して行えます。
マッピングの反映先は、この後の説明で示すように、Oracle固有のディスクリプタ内の<security-role-mapping>
設定です。
ロールのマッピングにはApplication Server Controlを使用することが推奨されますが、次の説明で示すのは、J2EEロールmyMgr
をデプロイ・ロールmanagers
にマップしたときにorion-ejb-jar.xml
に生成される構成の参考情報です。managers
ロールのメンバーとしてログインできるユーザーは、myMgr
ロール(前にPOMgr
アプリケーション論理ロールにリンクされていたロール)のパーミッションを持つものとみなされ、PurchaseOrder
Beanのメソッドを実行することができます。
標準のEJBデプロイメント・ディスクリプタ:
<assembly-descriptor> ... <security-role> <role-name>myMgr</role-name> </security-role> <method-permission> <role-name>myMgr</role-name> <method>...</method> </method-permission> ... </assembly-descriptor
OC4J固有のデプロイメント・ディスクリプタ:
<assembly-descriptor> ... <security-role-mapping name="myMgr"> <group name="managers" /> </security-role-mapping> ... </assembly-descriptor>
特定のユーザーにマップする場合:
<security-role-mapping name="myMgr"> <user name="guest" /> </security-role-mapping>
特定のロール内の特定のユーザーにマップする場合:
<security-role-mapping name="myMgr"> <group name="managers" /> <user name="guest" /> </security-role-mapping>
アプリケーションにEJBが含まれている場合は、アプリケーションのサーバー・サイドJNDIコンテキストでオブジェクトの読取り(検索)および書込み(バインド)を行うためのネームスペース・アクセス権を、必要に応じてリモート・クライアントに付与する必要があります。読取りおよび書込みは、javax.naming.Context
オブジェクトのlookup()
メソッドとbind()
メソッドにそれぞれ対応します。
リモート・クライアントのユーザー資格証明(リモート・クライアント・コンテキストに渡されるJNDIプロパティ)を、アプリケーションのJNDIコンテキストへのアクセス権を付与されているロールの1つにマップする必要があります。
orion-application.xml
から抜粋した次の例では、読取り操作を行うためのネームスペース・アクセス権をmanagers
およびdevelopers
ロールに付与する方法を示しています。
<orion-application ... > ... <namespace-access> <read-access> <namespace-resource root=""> <security-role-mapping name="sr_developer"> <group name="developers"/> </security-role-mapping> <security-role-mapping name="myMgr"> <group name="managers"/> </security-role-mapping> </namespace-resource> </read-access> </namespace-access> ... </orion-application>
ここでは、示されたロール・マッピングがすでにorion-application.xml
内で設定されていることを前提にしています。
メソッドがロール・マッピングに関連付けられていない場合は、orion-ejb-jar.xml
ファイル内の<default-method-access>
要素を介してデフォルトのセキュリティ・ロールにマップされます。次の例に、セキュアでないメソッドの自動マッピングを示します。
<assembly-descriptor> ... <default-method-access> <security-role-mapping name="<default-ejb-caller-role>" impliesAll="true" /> </default-method-access> ... </assembly-descriptor>
デフォルト・ロールは、name
属性で指定されている<default-ejb-caller-role>
です。この文字列は、任意のデフォルト・ロール名で置き換えることができます。impliesAll
属性は、これらのメソッドに対するセキュリティ・ロール・チェックが発生するかどうかを示します。true
の設定は、セキュリティ・ロール・チェックが行われないことを示します。false
の設定は、コンテナがこれらのメソッドでこのデフォルト・ロールをチェックすることを示します。
orion-ejb-jar.xml
ファイルでは、impliesAll
属性がデフォルトで次のように設定されます。
orion-ejb-jar.xml
で<security-role-mapping>
が指定され、かつimpliesAll
が設定されていない場合は、この属性がデフォルトでfalse
に設定され、コンテナがこれらのメソッドでこのデフォルト・ロールをチェックします。
orion-ejb-jar.xml
で<security-role-mapping>
が指定されていない場合は、OC4J EJBレイヤーがデフォルトでimpliesAll
にtrue
を設定し、これらのメソッドに対してセキュリティ・ロール・チェックが行われません。
impliesAll
属性がfalse
の場合は、<user>
または<group>
サブ要素を介して、name
属性に定義されているデフォルト・ロールをデプロイ・ユーザーまたはロールにマップする必要があります。次の例に、メソッド・パーミッションに関連付けられていないすべてのメソッドをothers
ロールにマップする方法を示します。
<default-method-access> <security-role-mapping name="default-role" impliesAll="false" /> <group name="others" /> </security-role-mapping> </default-method-access>
リモート・コンテナ内のEJBにアクセスする場合は、このコンテナに有効な資格証明を渡す必要があります。
client.jar
(標準のJ2EEクライアント・モジュール)にデプロイされているjndi.properties
ファイルで定義します。
InitialContext
内で資格証明を渡します。リモート・コンテナ内のEJBにアクセスする場合は、このコンテナに有効な資格証明を渡す必要があります。スタンドアロン・クライアントは、その資格証明を、クライアントのコードでデプロイされているjndi.properties
ファイルで次のプロパティを使用して定義します。
java.naming.security.principal=username java.naming.security.credentials=password
たとえば、リモートEJBにPOMGR/welcome
としてアクセスする場合は、次のようにプロパティを設定します。java.naming.factory.initial
設定は、Oracle JNDI実装を使用することを示します。
java.naming.security.principal=POMGR java.naming.security.credentials=welcome java.naming.factory.initial= oracle.j2ee.naming.ApplicationClientInitialContextFactory java.naming.provider.url=ormi://myhost/ejbsamples
アプリケーション・プログラムで、次の例に示すようにリモートEJBを認証してアクセスします。
InitialContext ic = new InitialContext(); CustomerHome = (CustomerHome)ic.lookup("java:comp/env/purchaseOrderBean");
コンテナ内で実行されるJavaBeansは、リモートEJBの検索用に作成されるjavax.naming.InitialContext
インスタンス内で資格証明を渡します。
たとえば、Hashtable
環境でJNDIセキュリティ・プロパティを渡すには、次のようにします。
Hashtable env = new Hashtable(); env.put("java.naming.provider.url", "ormi://myhost/ejbsamples"); env.put("java.naming.factory.initial", "oracle.j2ee.naming.ApplicationClientInitialContextFactory"); env.put(Context.SECURITY_PRINCIPAL, "guest"); env.put(Context.SECURITY_CREDENTIALS, "welcome"); Context ic = new InitialContext (env); Object homeObject = ic.lookup("java:comp/env/employeeBean"); // Narrow the reference to a TemplateHome. EmployeeHome empHome = (EmployeeHome) PortableRemoteObject.narrow(homeObject, EmployeeHome.class);
アプリケーションでRMIを使用してEJBにアクセスするには、適切なユーザーまたはロールにRMIパーミッションloginを付与する必要があります。これを行うには、OracleAS JAAS ProviderのAdmintoolを使用します。
次の例では、このパーミッションをロール(users
)に対して設定します。
% java -jar jazn.jar -grantperm myrealm -role users \ com.evermind.server.rmi.RMIPermission login
さらに次の例では、ユーザー(JDOE_ENDUSER
)に対してパーミッションを設定します。
% java -jar jazn.jar -grantperm myrealm -user JDOE_ENDUSER \ com.evermind.server.rmi.RMIPermission login
ファイルベース・プロバイダの場合は、Application Server Controlでロールを選択し、RMI権限の付与チェック・ボックスを選択しても、ロールにこのパーミッションを付与できます。(「ロールの作成」または「ロールの編集」も参照してください。)
OC4Jを再起動して、変更を有効にします。
EJBアプリケーションをセキュリティ・マネージャがアクティブになっているクライアントとしてダウンロードする場合は、実行前に次のパーミッションを付与する必要があります。
permission java.net.SocketPermission "*:*", "connect,resolve"; permission java.lang.RuntimePermission "createClassLoader"; permission java.lang.RuntimePermission "getClassLoader"; permission java.util.PropertyPermission "*", "read"; permission java.util.PropertyPermission "LoadBalanceOnLookup", "read,write";
匿名EJB検索は、ほとんどの場合、開発中または非常に特別な状況においてのみ検討対象となるモードです。このモードでは、InitialContext
の作成時にプリンシパルおよび資格証明を指定しないので、リモートでEJBにアクセスする際にプリンシパルや資格証明を指定する必要がありません。jndi.properties
ファイルは次のようになります。
java.naming.factory.initial= oracle.j2ee.naming.ApplicationClientInitialContextFactory java.naming.provider.url=ormi://localhost:23791/ejb30slsb java.naming.security.principal= java.naming.security.credentials=
このモードは、次のようにして有効にできます。
system-jazn-data.xml
にanonymous
ユーザーが構成され、このユーザーがアクティブになっていることを確認します。
system-jazn-data.xml
内の適切なレルム下で、RMIパーミッションが付与されているロールにanonymous
ユーザーを割り当てます。たとえば、users
ロールにRMIパーミッションが付与されていると仮定します。
<jazn-data> ... <jazn-realm> <realm> <name>myrealm</name> ... <roles> <role> <name>users</name> <members> <member> <type>user</type> <name>anonymous</name> </member> </members> </role> ... </roles> ... </realm> ... </jazn-realm> ... </jazn-data>
users
)に適切なネームスペース・アクセス権を付与して、このロールがアプリケーションのサーバー・サイドJNDIコンテキストで読取り(検索)および書込み(バインド)操作を実行できるようにします。アプリケーションのorion-application.xml
ファイルで、次のような構成を使用します。
<orion-application> ... <namespace-access> <read-access> <namespace-resource root=""> <security-role-mapping name="jndi-user-role"> <group name="administrators" /> <group name="users" /> </security-role-mapping> </namespace-resource> </read-access> <write-access> <namespace-resource root=""> <security-role-mapping name="jndi-user-role"> <group name="administrators" /> <group name="users" /> </security-role-mapping> </namespace-resource> </write-access> </namespace-access> ... </orion-application>
この構成では、プリンシパルや資格証明を指定しなくてもリモートEJBにアクセスできます。
この項では、OC4Jでのサブジェクト伝播、およびORMIを使用するサブジェクト伝播を有効にする方法について説明します。(サブジェクト伝播では、CSIv2仕様に従って、常にIIOPが使用されます。)内容は次のとおりです。
重要
rmi.xml
の<access-mask>
要素を使用)、またはRMIサブジェクト伝播制限(「サブジェクト伝播制限の削除と構成」で説明しているrmi.xml
の<subject-propagation-mask>
要素を使用)を使用することを検討してください。
OC4Jでは、図18-3で概要を説明しているように、サブジェクト伝播がサポートされています。この機能を使用することで、Webクライアントはそのアイデンティティの認証をサーブレットから受け、サーブレットはそのアイデンティティを使用して他のEJBやサーブレットと通信できます。この場合、アイデンティティは適切なサブジェクト(javax.security.auth.Subject
インスタンス)です。同様に、リモートEJBファット・クライアントは、この機能を使用してEJBコンテナをコールできます。
クライアントの現在のサブジェクトが取得された後、Subject.getSubject()
コールを介して、サブジェクト伝播は次のように行われます。
サブジェクトは、たとえば一連のEJB起動によって伝播できます。EJBは、クライアントのアイデンティティを使用するように構成されている場合は、クライアントのアイデンティティを取り込みます。EJBは、特定のロールでrun-asモードを使用するようには構成できません。
サブジェクト伝播を使用するには、次の手順を実行する必要があります。
OC4Jでは、ORMIを使用するサブジェクト伝播は、クライアントおよびサーバーの両方で有効にした場合にのみ使用できます。(CSIv2仕様に従い、IIOPに対しては常にサブジェクト伝播が有効となります。)そのためには、クライアント上およびサーバー上で次のシステム・プロパティ設定を使用します。
-Dsubject.propagation=true
現行リリースでは、この設定により、グローバルOC4Jレベルでサブジェクト伝播が設定されます。
サブジェクト伝播が正しく行われるようにするには、サブジェクトの伝播元となるWebアプリケーションおよび伝播先となるEJBでJAASモードを有効にしておく必要があります。そこで、「JAASモードの概要」で説明されているように、orion-application.xml
ファイルの<jazn>
要素で、jaas-mode="doAs"
またはjaas-mode="doAsPrivileged"
の設定が必要になります。
伝播されたサブジェクトがサーバーによって受け入れられるのは、EJBコール元にRMIPermission
subject.propagation
が付与されている場合に限られます。次の例では、OracleAS JAAS ProviderのAdmintoolを使用して、このパーミッションをユーザーoc4jadmin
に付与して、このユーザーのサブジェクトがサーバーに伝播されるようにします。
% java -jar jazn.jar -grantperm myrealm -user oc4jadmin \ com.evermind.server.rmi.RMIPermission subject.propagation
subject.propagation
パーミッションは、ロールに付与することもできます。次の例では、users
ロール内のあらゆるユーザーのサブジェクトがサーバーに伝播されるようにします。
% java -jar jazn.jar -grantperm myrealm -role users \ com.evermind.server.rmi.RMIPermission subject.propagation
サーバーがサブジェクト内で受け入れるプリンシパル名を指定することで、サブジェクト伝播を制限できます。次の例では、再びusers
ロール内のユーザーにsubject.propagation
パーミッションを付与しますが、今度は伝播されたサブジェクトからdeveloper
およびmanager
プリンシパルを除くすべてがサーバーによって排除されます。(この選別は、プリンシパル・タイプではなくプリンシパル名によって行われることに注意してください。)
% java -jar jazn.jar -grantperm myrealm -role users \ com.evermind.server.rmi.RMIPermission subject.propagation developer,manager
デフォルトでは、制限なしにサブジェクト内のすべてのプリンシパルが受け入れられます。ただし、subject.propagation
パラメータを"*"
(引用符も含めて指定)に設定することで、この動作を明示的に指定することもできます。
% java -jar jazn.jar -grantperm myrealm -user oc4jadmin \ com.evermind.server.rmi.RMIPermission subject.propagation "*"
これは、前述の最初の例に相当します。
java.security.Subject
がJDKに付属のクラスであるのに対し、java.security.Principal
は必要に応じて実装可能なインタフェースです。サブジェクト伝播がORMIで正しく行われるようにするには、リモート・クライアント、アプリケーションおよびOC4Jのすべてに、すべてのPrincipal
クラス定義へのアクセス権がある必要があります。
このようにするには、「ライブラリを共有するためのタスク」で説明されているように、OC4J共有ライブラリとしてロードされているライブラリにこれらのクラス定義を追加します。
デフォルトでは、すべてのORMIクライアントが、サブジェクト伝播へのアクセスを拒否されています。アクセスが可能になるように構成するには、rmi.xml
内の<subject-propagation-mask>
要素およびそのサブ要素<host-access>
と<ip-access>
の設定を使用します。
サブジェクト伝播へのアクセスは、除外的または包含的にできます。
<subject-propagation-mask>
でmode="deny"
を使用してから、<host-access>
サブ要素、<ip-access>
サブ要素またはこの両方でmode="allow"
を使用することで、アクセスを許可する特定のホストまたはIPアドレスを指定します。
<subject-propagation-mask>
でmode="allow"
を使用してから、<host-access>
サブ要素、<ip-access>
サブ要素またはこの両方でmode="deny"
を使用することで、アクセスを拒否するホストまたはIPアドレスを指定します。
次の例は、除外モードを構成して、localhost
および192.168.1.0
に対してのみサブジェクト伝播を許可しています。(255.255.255.0
は適用されるサブネット・マスクです。)
<rmi-server ... > ... <subject-propagation-mask default="deny"> <host-access domain="localhost" mode="allow"/> <ip-access ip="192.168.1.0" netmask="255.255.255.0" mode="allow"/> </subject-propagation-mask> ... </rmi-server>
デフォルト設定は、次のとおりです。
<subject-propagation-mask default="deny"/>
|
Copyright © 2003, 2008 Oracle Corporation. All Rights Reserved. |
|