6 JavaアプリケーションでのReal Application Securityの使用
6.1 中間層の初期化について
XSSessionManager
クラスは、セッションのライフ・サイクルを管理します。セッションを作成、連結、割当て、連結解除および破棄するメソッドを提供します。キャッシュ・アクティビティを実行するメソッドも提供します。
6.1.1 中間層構成モードについて
-
ディスパッチャ・モード - ディスパッチャ接続でセッション・マネージャを取得します
ディスパッチャ・モードでは、ディスパッチャ・ユーザーにセッション管理およびキャッシュ・アクセスの権限が必要です。アプリケーション・ユーザーには、セッションまたはキャッシュ権限は不要です。2つの事前定義済データベース・ロールxs_session_admin
およびxs_cache_admin
をディスパッチャに付与できます。
セキュリティのベスト・プラクティスでは、アプリケーション・ユーザーに最小限の権限を付与する必要があるため、中間層構成にはディスパッチャ・モードをお薦めします。
6.1.2 getSessionManagerメソッドの使用方法
中間層構成モードについてで説明した中間層構成モードに従ってセッション・マネージャを取得する方法が1つあります。
-
ディスパッチャ・ユーザーの接続または接続のプールを渡します。この方法では、必要な権限がディスパッチャに付与されます。2つの事前定義済データベース・ロール
xs_session_admin
およびxs_cache_admin
をディスパッチャ・ユーザーに付与する必要があります。ディスパッチャ・ユーザーは、直接ログオンReal Application Securityユーザーです。
ディスパッチャ・モードを使用して、セッション・マネージャのインスタンスを取得することで、Real Application Security中間層を開始できます(例6-1を参照)。XSSessionManager
クラスのgetSessionManager
メソッド(太字)を使用して、セッション・マネージャのインスタンスを取得します。このメソッドは、単一の接続または接続のプールを使用してReal Application Securityセッション・マネージャを初期化します。getSessionManager
メソッドのコール元には、Java Authentication and Authorization Service (JAAS)権限XSSecurityPermission("initSecurityManager")
が必要です。
セッション・マネージャの権限
Real Application Securityセッション・マネージャは、標準のReal Application Securityアプリケーション・ユーザーにかわってセッション操作を認可する特権ユーザーの接続で初期化されます。セッション・マネージャにセッション操作権限がある場合、セッション・マネージャの下の各アプリケーション・ユーザーにはセッション操作権限は不要で、アプリケーション・ユーザーのセッション操作は信頼されるパーティとして実行できます。セッション・マネージャは、接続に対するセッション操作を認可するため、createSession
およびattachToSession
権限を標準のReal Application Securityアプリケーション・ユーザーに直接付与する必要はありません。このセッション・マネージャには次の権限が必要です。
-
中間層のキャッシュされたデータを管理するためのReal Application Securityデータベース・オブジェクト権限。
-
セッション・マネージャがReal Application Securityアプリケーション・ユーザーおよび外部ユーザーにかわってセッションを作成または連結するためのセッション・ライフサイクル管理権限。
セッション・マネージャのロール
セッション・マネージャがセッション・マネージャの権限で示した権限を持つためには、次の2つのロールが必要です。
-
次の権限を持つデータベース・ロール
xs_cache_admin
。-
Real Application Securityエンティティの問合せおよびメタデータの同期を行う権限
-
キー交換用のコードを実行するための権限
-
-
ADMIN_SESSION
権限を持つReal Application Securityロールxs_session_admin
これらのロールはシステムで事前定義されています。
例6-1 単一接続を使用してJavaでセッション・マネージャのインスタンスを取得する方法
static XSSessionManager manager;
static Connection dispatcherConn = null;
int cacheMaxIdleTime=30;
int cacheMaxsize=2048000;
String host;
String port;
String sid;
...
dispatcherConn = DriverManager.getConnection("jdbc:oracle:thin:@" + host + ":" + port + ":" + sid, dispatcherUser, dispatcherPassword);
...
manager = XSSessionManager.getSessionManager(dispatcherConn, cacheMaxIdleTime, cacheMaxsize);
6.1.3 中間層キャッシュ設定の変更について
セッション・マネージャは、初期化されると、ACLやSecurityクラス情報などの一部のデータのキャッシュへの追加を開始します。このキャッシュ・データは再利用できます。キャッシュは、後で変更できるデフォルト設定で初期化されます。
6.1.3.1 最大キャッシュ・アイドル時間の設定について
最大キャッシュ・アイドル時間を設定するには、XSSessionManager
クラスのsetCacheMaxIdleTime
メソッドを使用します。setCacheMaxIdleTime
メソッドは、キャッシュが更新なしで存続できる最大時間(分)を設定します。
キャッシュからオブジェクトのフェッチが試行され、XSSessionManager
がsetCacheMaxIdleTime
メソッドで設定された値と同じ期間にわたってupdateCache
メソッドをコールしていない場合は、オブジェクトを戻す前にupdateCache
メソッドが強制的に起動されて、キャッシュされたすべてのオブジェクトがまだ有効であることが確認されます。setCacheMaxIdleTime
メソッドのコール元には、JAAS権限XSSecurityPermission("setCacheMaxIdleTime")
が必要です。
6.1.3.5 キャッシュからのエントリの削除について
キャッシュからエントリを削除するには、キャッシュ削除アルゴリズムが水位標レベルとともに使用されます。水位標レベルは、データが削除される前にメモリー・キャッシュに存続する必要のある期間を決定します。キャッシュ・サイズが高水位標に達すると、キャッシュ削除アルゴリズムによって、キャッシュ・サイズが低水位標に達するまでエントリが削除されます。
6.2 Real Application Securityセッションの管理について
6.2.1 Real Application Securityユーザー・セッションの作成
Real Application Securityユーザー・セッション(たとえばユーザーlwuser
に対するlws
)を作成するには、XSSessionManager
クラスのcreateSession
メソッドを使用します(例6-2を参照)。createSession
メソッド(太字)は、指定したパラメータを渡してサーバーにセッションを作成します。この操作を実行するにはデータベースのラウンドトリップが必要です。
匿名Real Application Securityアプリケーション・セッションを作成するには、XSSessionManager
クラスのcreateAnonymousSession
メソッドを使用します。このセッションのアプリケーションは事前定義済の匿名ユーザーであるため、このメソッドにユーザー・パラメータは渡されません。
どちらのメソッドも、Cookieとネームスペースの使用をサポートします。
Cookieを使用して、Cookie値が変更されるかセッションが破棄されるまで、新規に作成されたReal Application Securityアプリケーション・セッションを将来のコールで識別できます。
パラメータとして渡されるネームスペースを使用して、セッションにネームスペースを作成できます。詳細は、セッション・ユーザーとしてのネームスペース操作の実行についてを参照してください。
このセッションを引き継ぐ特定のアプリケーション・ユーザーを再割当てできます。この場合、匿名ユーザーのセッションの状態の一部はまだ保持されています。詳細は、アプリケーション・ユーザーの割当てまたは切替えを参照してください。
例6-2 JavaでのReal Application Securityセッションの作成方法
Session lws = null;
static XSSessionManager manager;
static Connection lwsConn = null;
static String user = "lwuser";
String cookie="nst";
...
lws = manager.createSession(lwsConn, user, cookie, null);
...
6.2.2 アプリケーション・セッションの連結
アプリケーション・セッションを連結するには、XSSessionManager
クラスのattachSession
メソッドを使用します(例6-3を参照)。attachSession
メソッド(太字)は、JDBC接続を指定されたReal Application Securityアプリケーション・セッション・オブジェクトに連結します。動的アプリケーション・ロールの有効化または無効化、セッションのネームスペースの作成および認証時間の設定も行います。
例6-4に示すように、IDまたはCookieを使用してセッションに連結することもできます。Cookieを使用したセッションの連結の別の例は、例7-2を参照してください。
例6-3 JavaでのReal Application Securityセッションの連結方法
Session lws = null;
static Connection lwsConn = null;
static XSSessionManager manager;
static String user = "lwuser";
String cookie = "lwscookie";
List <String> edynamicRoles = new ArrayList <String>();
edynamicRoles.add("EDYNROLE001");
edynamicRoles.add("EDYNROLE002");
List <String> ddynamicRoles = new ArrayList <String>();
ddynamicRoles.add("DDYNROLE001");
ddynamicRoles.add("DDYNROLE002");
...
lws = manager.createSession(lwsConn, user, cookie, null);
manager.attachSession(lwsConn, lws, edynamicRoles, ddynamicRoles, null, new Timestamp(System.currentTimeMillis()));
例6-4 Cookieを使用して連結する方法
Session lws = null; static Connection lwsConn = null; static XSSessionManager manager; ... lws = manager.attachSessionByCookie(lwsConn, "myCookie", null, null, null, null, null);
6.2.3 アプリケーション・ユーザーの割当てまたは切替え
匿名セッションがある場合は、後で別のアプリケーション・ユーザーに再割当てできます。または、セッションがすでにアプリケーション・ユーザーに割り当てられている場合は、セッションを別のアプリケーション・ユーザーに切り替えることができます。どちらの場合も、アプリケーション・ユーザーを割り当てるか切り替える前に、セッションが連結されている必要があります。
以前の匿名アプリケーション・ユーザーに名前を割り当てるには、XSSessionManager
クラスのassignUser
メソッドを使用します(例6-5を参照)。assignUser
メソッド(太字)は、セッション・コンテキスト(ユーザーおよびロール)をlwuser
などの特定のユーザーに変更しますが、既存のネームスペースを保持します。attachSession
メソッドと同じ方法で、特定の動的ロールおよびネームスペース・パラメータで同時にセッションを変更することもできます。関連セッション属性は、別のコールを通じて削除されないかぎり有効なままになります。
セッション・ユーザーを名前付きユーザー(匿名ではない)から別の名前付きユーザーに変更するには、SessionオブジェクトのswitchUser
メソッドを使用します。
セッションの連結時に割り当てられた動的アプリケーション・ロールを保持するリクエストは無効になります。動的アプリケーション・ロールは、新規アプリケーション・ユーザーの動的アプリケーション・ロール・リストにも含まれる場合にのみ、新規アプリケーション・ユーザーに対して保持されます。関連セッション属性は、セッション属性リストがリセットされないかぎり有効なままになります。
このメソッドは、セッション・コンテキスト(ユーザーおよびロール)をターゲット・ユーザーに変更しますが(ロールの変更の詳細は、「現在のアプリケーション・セッションの別のアプリケーション・ユーザーへの現在のアプリケーション・ユーザーの切替え」を参照)、デフォルトでは既存のネームスペースを保持しません。既存のネームスペースを保持する場合は、SessionオブジェクトのswitchUserKeepState
メソッドを使用できます。attachSession
メソッドと同じ方法で、特定の動的ロールおよびネームスペース・パラメータで同時にセッションを変更することもできます。
例6-6に、アプリケーション・ユーザーをlwuser
からlwuser1
に切り替える方法を示します。switchUser
メソッドは太字で示されています。
例6-5 Javaでアプリケーション・ユーザーをセッションに割り当てる方法
Session lws = null;
static XSSessionManager manager;
static String user = "lwuser";
...
manager.assignUser(lws, user, null, null, null, new Timestamp(System.currentTimeMillis()));
例6-6 Javaでセッションのアプリケーション・ユーザーを切り替える方法
Session lws = null;
Vector<String> listOfNamespaces;
static String user = "lwuser";
List<String> nslist1 = new ArrayList<String>();
...
manager.assignUser(lws, user, nslist1, nslist2, nslist3, new Timestamp(System.currentTimeMillis()));
...
lws.switchUser("lwuser1",listOfNamespaces);
6.2.4 Real Application Securityアプリケーション・ロールの有効化
Real Application Securityアプリケーション・ロールは、Real Application Securityアプリケーション・ユーザーまたは別のReal Application Securityアプリケーション・ロールにのみ付与できるロールです。Real Application Securityアプリケーション・ロールは、データベース・ロールを通じて付与されるデータベース権限です。データベース権限はデータベース・ロールに付与され、データベース・ロールはReal Application Securityアプリケーション・ロールに付与されます。Real Application Securityアプリケーション・ユーザーおよびアプリケーション・ロールの詳細は、「プリンシパル: ユーザーおよびロール」を参照してください。
6.2.4.1 Real Application Securityアプリケーション・ロールの有効化
セッションの現在のアプリケーション・ユーザーに付与されているReal Application Securityアプリケーション・ロールを有効にするには、Session
インタフェースのenableRole
メソッドを使用します(例6-7を参照)。
特定のアプリケーション・ロールが現在無効になっている場合、enableRole
メソッド(太字)の効果はありません。この操作にはデータベースのラウンドトリップが必要です。
例6-7 JavaでReal Application Securityアプリケーション・ロールを有効にする方法
static Session lws;
static Roles r1;
...
r1=new Role("HROLE1",null,0);
lws.enableRole(r1);
6.2.4.2 Real Application Securityアプリケーション・ロールの無効化
セッションの現在のアプリケーション・ユーザーに付与されているReal Application Securityアプリケーション・ロールを有効にするには、Session
インタフェースのdisableRole
メソッドを使用します(例6-8を参照)。この操作にはデータベースのラウンドトリップが必要です。disableRole
メソッドは太字で示されています。
例6-8 JavaでReal Application Securityアプリケーション・ロールを無効にする方法
static Session lws;
static Roles r1;
...
r1=new Role("HROLE1",null,0);
lws.enableRole(r1);
...
lws.disableRole(r1);
6.2.4.3 Real Application Securityアプリケーション・ロールが有効かどうかの確認
指定されたアプリケーション・ロールがReal Application Securityアプリケーション・セッションで有効になっているかどうかをテストするには、Session
インタフェースのisRoleEnabled
メソッドを使用します(例6-9を参照)。isRoleEnabled
メソッドは太字で示されています。
このメソッドに関連付けられているデータベース操作はありません。このメソッドをコールするにはadministerSession
Real Application Securityアプリケーション権限が必要です。
例6-9 JavaでReal Application Securityアプリケーション・ロールが有効になっているかどうかをテストする方法
static Session lws;
...
lws.enableRole("HROLE1");
...
boolean b = lws.isRoleEnabled("HROLE1");
6.2.5 セッション・ユーザーとしてのネームスペース操作の実行について
ネームスペースは、セッション・コンテキストの追加属性のグループです。アプリケーションは、ネームスペースを使用して、アプリケーションで定義された属性と値のペアを格納します。現在のセッション・ユーザーには、(ネームスペースに対する) MODIFY_NAMESPACE
および(属性に対する) MODIFY_ATTRIBUTE
アプリケーション権限が必要です。ネームスペースの詳細は、「ネームスペース・テンプレートを使用したネームスペースの作成について」を参照してください。
6.2.5.1 ネームスペースの作成
Javaでネームスペースを作成するには、Session
インタフェースのcreateNamespace
メソッドを使用します(例6-10を参照)。createNamespace
メソッド(太字)は、名前が指定した名前と一致するネームスペース・テンプレート・ドキュメントを使用して、新しいセッション・ネームスペースを作成します。イベント・ハンドラがテンプレート・ドキュメントで指定されている場合は、指定されたイベント・ハンドラが、そのテンプレートを使用して作成されたすべてのネームスペースに適用されます。
注意:
前の項で説明したcreateSession
およびattachSession
メソッドにネームスペース名をパラメータとして渡すことにより、ネームスペースを作成することもできます。
例6-10 Javaでのネームスペースの作成方法
Session lws = null;
...
SessionNamespace ns = lws.createNamespace("TESTNS1");
6.2.5.2 ネームスペースの削除
Javaでネームスペースを削除するには、Session
インタフェースのdeleteNamespace
メソッドを使用します(例6-11を参照)。deleteNamespace
メソッド(太字)は、セッションからネームスペースを削除します。
例6-11 Javaでのネームスペースの削除方法
Session lws = null;
...
SessionNamespace ns = lws.createNamespace("TESTNS1");
...
lws.deleteNamespace("TESTNS1");
6.2.5.3 ネームスペースの暗黙的な作成
セッション・ネームスペースを表すネームスペース・オブジェクトを暗黙的に作成するには、Session
インタフェースのgetNamespace
メソッドを使用します(例6-12を参照)。getNamespace
メソッドは太字で示されています。指定されたネームスペースがすでに存在する場合は、エラーがスローされます。
ネームスペースの文字列表現を取得するには、SessionNamespace
インタフェースのtoString
メソッドを使用します。
例6-12 Javaでネームスペースを暗黙的に作成する方法
Session lws = null;
...
SessionNamespace ns2 = lws.getNamespace("TESTNS1");
6.2.5.4 ネームスペース属性の使用方法について
セッション・ネームスペースは、単一のアプリケーション・モジュールがセッションの継続時間にわたって格納する属性を管理します。セッション・ネームスペースは、単一のネームスペース、単一のアクセス制御制限セット、またはそのネームスペースの属性変更イベントをディスパッチする単一のイベント・ハンドラ・プロシージャを格納します。
6.2.5.4.1 セッション・ネームスペース属性の作成
Javaでセッション・ネームスペース属性を作成するには、SessionNamespace
インタフェースのcreateAttribute
メソッドを使用します(例6-13を参照)。createAttribute
メソッド(太字)は、ネームスペースに新しい属性を作成します。
例6-13 Javaでのセッション・ネームスペース属性の作成方法
String name1="empid';
String value1="JB007";
SessionNamespace ns;
...
SessionNamespaceAttribute sa1=ns.createAttribute(name1,value1);
...
6.2.5.4.3 セッション・ネームスペース属性の取得
Javaでセッション・ネームスペース属性を取得するには、SessionNamespace
インタフェースのgetAttribute
メソッドを使用します(例6-14を参照)。getAttribute
メソッド(太字)は、パラメータで指定された名前の属性を戻します。
例6-14 Javaでのセッション・ネームスペース属性の取得方法
String name="empid'; String value="JB007"; SessionNamespace ns; ... SessionNamespaceAttribute sa=ns.createAttribute(name,value); ... String attrvalue = ns.getAttribute("empid").getValue(); ns.getAttribute("empid").setValue("newValue"); ...
6.2.5.4.4 属性のリスト
ネームスペース内の属性をリストするには、SessionNamespace
インタフェースのlistAttributes
メソッドを使用します(例6-15を参照)。listAttributes
メソッド(太字)は、ネームスペースの属性名の集合を戻します
例6-15 Javaで属性をリストする方法
String name1="empid';
String value1="JB007";
SessionNamespace ns;
...
SessionNamespaceAttribute sa1=ns.createAttribute(name1,value1);
...
for (Enumeration e = ns.listAttributes() ; e.hasMoreElements() ;) {
System.out.println(" -- " + e.nextElement());
}
...
6.2.5.4.5 属性のリセット
Javaで属性をリセットするには、SessionNamespace
インタフェースのresetAttribute
メソッドを使用します(例6-16を参照)。resetAttribute
メソッド(太字)は、ネームスペースの属性をデフォルト値にリセットします。
例6-16 Javaで属性をリセットする方法
String name1="empid';
String value1="JB007";
SessionNamespace ns;
...
SessionNamespaceAttribute sa1=ns.createAttribute(name1,value1);
...
ns.resetAttribute("empid");
...
6.2.5.4.6 属性の削除
Javaで属性を削除するには、SessionNamespace
インタフェースのdeleteAttribute
メソッドを使用します(例6-17を参照)。deleteAttribute
メソッド(太字)は、ネームスペース内の特定の属性を削除します。
例6-17 Javaでの属性の削除方法
String name1="empid';
String value1="JB007";
SessionNamespace ns;
...
SessionNamespaceAttribute sa1=ns.createAttribute(name1,value1);
...
ns.deleteAttribute("empid");
...
6.2.6 セッション・マネージャとしてのネームスペース操作の実行について
各ネームスペースには、誰がネームスペースとその属性を操作できるかを決定するためにACLが関連付けられています。アプリケーションで現在のセッション・ユーザーがネームスペースを操作できないようにし、セッション・マネージャには操作を許可する場合は、セッション・マネージャXSSessionManager
としてこれを行うことができます。
XSSessionManager
には、ネームスペースを管理するためのSessionとしてオーバーロードされたメソッドのセットがあります。使用方法は、「セッション・ユーザーとしてのネームスペース操作の実行について」でのセッション・ユーザーに関する説明と同様です。
セッション・マネージャ・インスタンスXSSessionManager
はアプリケーション・コードで使用可能でない場合があり、信頼されたインフラストラクチャ・レイヤーだけがセッション・マネージャを使用して、このようなセキュリティで保護されたネームスペースを操作できます。
6.2.7 その他のセッション関連アクティビティの実行について
6.2.7.3 セッションのセッションIDの取得
特定のセッションのセッション識別子(ID)を取得するには、Session
インタフェースのgetId
メソッドを使用します(例6-18を参照)。getId
メソッドは太字で示されています。
例6-18 JavaでセッションのセッションIDを取得する方法
Session lws=null;
...
System.out.println( "The Session ID is" + lws.getId());
6.2.7.5 セッションCookieの取得
セッションに使用されるセキュアなセッションCookieを取得するには、Session
インタフェースのgetSessionCookie
メソッドを使用します(例6-19を参照)。getSessionCookie
メソッドは太字で示されています。
例6-19 JavaでセキュアなセッションCookieを取得する方法
static Session lws;
...
System.out.println(lws.getSessionCookie());
6.2.7.7 セッション・マネージャとしてのセッションCookieの設定
セッションに使用されるセキュアなセッションCookieを設定するには、SessionManager
インタフェースのsetCookie
メソッドを使用します(例6-20を参照)。setCookie
メソッド(太字)は、このセッションで使用されるセキュアなセッションCookieを戻します。メソッドは次のとおりです。
sessionManager.setCookie(lws,"newCookieValue");
例6-20 JavaでセキュアなセッションCookieを設定する方法
static XSSessionManager manager;
...
manager.sessionManager.setCookie(lws,"chocolate chip");
6.2.8 アプリケーション・セッションの連結解除
JavaでReal Application Securityアプリケーション・セッションを連結解除するには、XSSessionManager
クラスのdetachSession
メソッドを使用します(例6-21を参照)。detachSession
メソッド(太字)は、オブジェクトをパラメータとして受け入れるセッションを連結解除します。detachSession
メソッド・コールは、データベース・レベルのリクエストのすべての変更をコミットします。この操作を実行するにはデータベースのラウンドトリップが必要です。
例6-21 JavaでReal Application Securityセッションを連結解除する方法
Session lws = null;
static XSSessionManager manager;
static Connection lwsConn = null;
static String user = "lwuser";
String cookie;
...
lws = manager.createSession(lwsConn, user, cookie, null);
manager.attachSession(lwsConn, lws, null, null, null, new Timestamp(System.currentTimeMillis()));
...
manager.detachSession(lws);
...
6.2.9 Real Application Securityアプリケーション・セッションの破棄
JavaでReal Application Securityアプリケーション・セッションを破棄するには、XSSessionManager
クラスのdestroySession
メソッドを使用します(例6-22を参照)。destroySession
メソッド(太字)は、データベース接続オブジェクトとセッション・オブジェクトをパラメータとして受け入れます。このメソッドをコールした後、破棄されたセッションはJVMからアクセスできなくなります。この操作の実行およびセッションの作成にもデータベースのラウンドトリップが必要です。
例6-22 JavaでReal Application Securityセッションを破棄する方法
Session lws = null;
static Connection lwsConn = null;
static XSSessionManager manager;
static String user = "lwuser";
String cookie;
...
lws = manager.createSession(lwsConn, user, cookie, null);
manager.attachSession(lwsConn, lws, null, null, null, new Timestamp(System.currentTimeMillis()));
...
manager.detachSession(lws);
manager.destroySession(lwsConn, lws);
...
6.3 Java APIを使用したアプリケーション・ユーザーの認証
アプリケーション・ユーザーの認証は、アプリケーションで必要な主要セキュリティ機能です。アプリケーション・ユーザーの認証にはXSAuthenticationModule
クラスを使用します。XSAuthenticationModule
クラスのauthenticate
メソッドを使用して、アプリケーション・ユーザー資格証明を検証します(例6-23を参照)。authenticate
メソッドは太字で示されています。
例6-23 Javaでのアプリケーション・ユーザーの認証方法
boolean authOk = false;
String dbUser;
String passwd;
String host;
String port;
String sid;
...
authOk = XSAuthenticationModule.authenticate(host + ":" + port + ":" + sid, dbUser, passwd);
...
6.4 ACLを使用したアプリケーション・ユーザーの認可について
認可も、アプリケーションで必要な主要セキュリティ機能です。Real Application Securityでは、認可ポリシーはアクセス制御リスト(ACL)とアプリケーション権限から構成されます。これらはReal Application Securityデータベースで定義され、中間層のキャッシュで管理されます。アプリケーション権限はデータ権限です。データ権限は、ファンクションのアクセスまたはデータの操作の定義に使用されます。ファンクションがセッションへの接続を連結すると、接続にパススルーされた問合せはデータベース・サーバーによって自動的に施行されます。
AclId
クラスは、次の操作を実行する各種メソッドを提供します。
6.4.1 ACL識別子の作成
アクセス制御リスト(ACL)識別子を作成するには、AclId
クラスのオーバーロードされたパラメータ化コンストラクタの1つを使用します(例6-24を参照)。RAWバイナリ・データからACL識別子を作成する場合は、次のコンストラクタを使用します。
public AclId(byte[] raw)
このコンストラクタを起動すると、問合せのora_get_aclids
演算子から戻されたRAWバイナリを使用してACL識別子が作成されます。
内部ACL識別子からACL識別子を作成する場合は、次のコンストラクタを使用します。
public AclId(java.util.List<java.lang.Long> ids)
このコンストラクタを起動すると、内部ACL識別子を使用してACL識別子が作成されます。
例6-24 ACL識別子の作成方法
Session lws = null; static byte[] aclRaw; ... AclId id = new AclId(aclRaw); boolean ret = lws.checkAcl(aclRaw, "UPDATE_INFO"); ...
6.4.2 checkAclメソッドの使用方法
指定されたデータ権限の1つ以上のACLをチェックするには、XSAccessController
クラスのcheckAcl
メソッドを使用します。データ権限は、AclId
オブジェクトで定義されている1つ以上のACLと照合してチェックされます。checkAcl
メソッドは、すべてのデータ権限がACLで付与されている場合にのみtrue
を戻します。単一のACLですべての権限を付与する必要はないことに注意してください。例6-25に示すように、checkAcl
メソッドを使用するにはセッションが必要です。
例6-25に、データ権限privileges22
に関連付けられているACLの取得方法を示します。
例6-25 指定したデータ権限のACLを取得する方法
boolean ret; Session lws = null; AclId id2 = new AclId(ids); List <String> privileges22 = new ArrayList<String>(); ... ret = XSAccessController.checkAcl(lws, id2, privileges22);
6.5 人事管理のユースケース: Javaでの実装
この項では、中間層のデータ・セキュリティ関連アプリケーション権限を検証する方法を説明します。このJava例は、「Real Application Security: 全体のまとめ」で説明したセキュリティ人事管理(HR)シナリオに基づいています。サンプルHR
スキーマのEMPLOYEES
表を使用します。例では、2人のReal Application Securityアプリケーション・ユーザーDAUSTIN
およびSMAVRIS
を使用して、Real Application Securityの概念を示します。例は、次のモジュールに分割できます。
中間層関連構成の設定
中間層構成を設定するには、DISPATCHER
ユーザーおよびパスワードを作成し、このユーザーにxscacfeadmin
およびxsessionadmin
Real Application Security管理権限を付与します。
exec xs_principal.create_user(name=>'dispatcher', schema=>'HR');
exec sys.xs_principal.set_password('dispatcher', 'password');
exec xs_principal.grant_roles('dispatcher', 'xscacheadmin');
exec xs_principal.grant_roles('dispatcher', 'xssessionadmin');
接続の設定と中間層の初期化
この例では、setupConnection
メソッドを使用してデータベースへの接続を作成します。setupConnection
メソッドは、次のような文字列配列を引数として受け入れます。
args[0]
=データベース・ユーザー
args[1]
=パスワード
args[2]
=ホスト
このメソッドは、oracle.security.xs.XSSecurityManager
クラスのgetSessionManager
メソッドをコールして中間層の初期化も行います。
public static void setupConnection(String[] args) throws Exception {
mgrConnection =
DriverManager.getConnection(args[2], "dispatcher", "password");
mgr = XSSessionManager.getSessionManager(mgrConnection, 30, 2048000);
appConnection = DriverManager.getConnection(args[2], args[0], args[1]);
}
セッションの設定と中間層APIでの認可
この例では、queryAsUser
メソッドを使用してセッションを設定し、中間層checkAcl
メソッドで認可します。この例では、セッションを作成し、連結してから、queryEmployees
メソッドをコールします。データベースでの問合せの実行のqueryEmployees
メソッドは、ACLでUPDATE
権限をチェックし、TRUE
の場合は更新を許可します。ACLでVIEW_SALARY
アプリケーション権限を再度チェックし、TRUE
の場合は、SALARY
列へのアクセスと、SALARY
列の機密データを含むすべての従業員レコードの表示を許可します。従業員レコードを表示した後で、セッションを連結解除し、セッションを破棄します。
private static void queryAsUser(String user) throws SQLException { System.out.println("\nQuery HR.EMPLOYEES table as user \"" + user + "\""); try { Session lws = mgr.createSession(appConnection, user, null,null); mgr.attachSession(appConnection, lws, null, null, null, null, null); queryEmployees(lws); mgr.detachSession(lws); mgr.destroySession(appConnection, lws); } catch (Exception e) { e.printStackTrace(); } }
データベースでの問合せの実行
この例では、queryEmployees
メソッドを使用してHRデータベースに対して問合せを実行します。
public static void queryEmployees(Session lws) throws SQLException { Connection conn = lws.getConnection(); String query = " select email, first_name, last_name, department_id, salary, ora_get_aclids(emp) from hr.employees emp where department_id in (40, 60, 100) order by email"; Statement stmt = null; ResultSet rs = null; System.out.printf(" EMAIL | FIRST_NAME | LAST_NAME | DEPT | SALARY | UPDATE | VIEW_SALARY\n"); try { stmt = conn.createStatement(); rs = stmt.executeQuery(query); while (rs.next()) { String email = rs.getString("EMAIL"); String first_name = rs.getString("FIRST_NAME"); String last_name = rs.getString("LAST_NAME"); String department_id = rs.getString("DEPARTMENT_ID"); String salary; if (((OracleResultSet)rs).getAuthorizationIndicator("SALARY") == AuthorizationIndicator.NONE) { salary = rs.getString("SALARY"); } else { salary = "*****"; } byte[] aclRaw = rs.getBytes(6); String update, viewSalary; if (XSAccessController.checkAcl(lws, aclRaw, "UPDATE")) { update = "true"; } else { update = "false"; } if (XSAccessController.checkAcl(lws, aclRaw, "VIEW_SALARY")) { viewSalary = "true"; } else { viewSalary = "false"; } System.out.printf("%9s|%12s|%12s|%6s|%8s|%8s|%8s\n", email, first_name, last_name, department_id, salary, update, viewSalary); } } catch (Exception e) { e.printStackTrace(); } finally { try { if (rs != null) rs.close(); } catch (Exception e) {}; try { if (stmt != null) stmt.close(); } catch (Exception e) {}; } } }
queryEmployees
メソッドは、アプリケーション・ユーザーDAUSTIN
およびSMAVRIS
の両方に対して実行されます。
クリーン・アップ操作の実行
この例では、システム・クリーンアップ操作にcleanup
メソッドを使用します。
public static void cleanupConnection() throws Exception { mgrConnection.close(); appConnection.close(); }
mainメソッド
この項では、説明したJava例のmain
メソッドを示します。この項には、プログラムを実行するためにインポートする必要のある様々なパッケージも含まれます。
import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; import oracle.jdbc.OracleDriver; import oracle.jdbc.OracleResultSet; import oracle.jdbc.OracleResultSet.AuthorizationIndicator; import oracle.security.xs.Role; import oracle.security.xs.Session; import oracle.security.xs.XSAccessController; import oracle.security.xs.XSSessionManager; /** * HR demo java version, check data security related privilege at mid-tier */ public class HRDemo { static Connection mgrConnection = null; static Connection appConnection = null; static XSSessionManager mgr = null; static String user = null; public static void main(String[] args) { try { DriverManager.registerDriver(new OracleDriver()); if (args.length >=3) { user = args[0]; } else { System.out.println("Usage HRDemo user pwd dbURL"); System.exit(1); } setupConnection(args); queryAsUser("DAUSTIN"); queryAsUser("SMAVRIS"); cleanupConnection(); } catch (Exception e1) { e1.printStackTrace(); } }
6.5.1 出力
JavaでのセキュリティHRデモの実行では、Real Application Securityコンポーネントを設定するためにセキュリティHRデモ・コンポーネントの設定で説明した設定スクリプトが実行されていることを前提とします。セキュリティHRデモを実行すると、2つの問合せの結果が返されます。
最初の問合せは、アプリケーション・ロールEMP_ROLE
およびIT_ROLE
を持つアプリケーション・ユーザーDAUSTIN
で実行されるため、このユーザーはIT部門の従業員レコードを表示できますが、自分の給与レコード以外のSALARY
列は表示できません。問合せの結果は次のとおりです。
Query HR.EMPLOYEES table as user "DAUSTIN" EMAIL | FIRST_NAME | LAST_NAME | DEPT | SALARY | UPDATE | VIEW_SALARY AHUNOLD| Alexander| Hunold| 60| *****| false| false BERNST| Bruce| Ernst| 60| *****| false| false DAUSTIN| David| Austin| 60| 4800| false| true DLORENTZ| Diana| Lorentz| 60| *****| false| false VPATABAL| Valli| Pataballa| 60| *****| false| false
アプリケーション・ユーザーDAUSTIN
は、自分のレコードのSALARY
列データのみ表示でき、他のユーザーのレコードについてはこの列データを表示できません。
2番目の問合せは、アプリケーション・ロールEMP_ROLE
およびHR_ROLE
を持つアプリケーション・ユーザーSMAVRISで実行されるため、このユーザーはすべての従業員レコードを表示および更新できます。問合せの結果は次のとおりです。
Query HR.EMPLOYEES table as user "SMAVRIS" EMAIL | FIRST_NAME | LAST_NAME | DEPT | SALARY | UPDATE | VIEW_SALARY AHUNOLD| Alexander| Hunold| 60| 9000| true| true BERNST| Bruce| Ernst| 60| 6000| true| true DAUSTIN| David| Austin| 60| 4800| true| true DFAVIET| Daniel| Faviet| 100| 9000| true| true DLORENTZ| Diana| Lorentz| 60| 4200| true| true ISCIARRA| Ismael| Sciarra| 100| 7700| true| true JCHEN| John| Chen| 100| 8200| true| true JMURMAN| Jose Manuel| Urman| 100| 7800| true| true LPOPP| Luis| Popp| 100| 6900| true| true NGREENBE| Nancy| Greenberg| 100| 12008| true| true SMAVRIS| Susan| Mavris| 40| 6500| true| true VPATABAL| Valli| Pataballa| 60| 4800| true| true
アプリケーション・ユーザーSMAVRIS
は、SALARY
列のすべてのデータを含むすべての従業員レコードを表示できます。