プライマリ・コンテンツに移動
Oracle® Database Real Application Security管理者および開発者ガイド
12cリリース1 (12.1)
B71274-08
目次へ移動
目次
索引へ移動
索引

前
次

6 JavaアプリケーションでのReal Application Securityの使用

中間層の初期化について

XSSessionManagerクラスは、セッションのライフ・サイクルを管理します。セッションを作成、連結、割当て、連結解除および破棄するメソッドを提供します。キャッシュ・アクティビティを実行するメソッドも提供します。

中間層構成モードについて

1つの中間層構成モードを使用できます。

  • ディスパッチャ・モード - ディスパッチャ接続でセッション・マネージャを取得します

ディスパッチャ・モードでは、ディスパッチャ・ユーザーにセッション管理およびキャッシュ・アクセスの権限が必要です。アプリケーション・ユーザーには、セッションまたはキャッシュ権限は不要です。2つの事前定義済データベース・ロールxs_session_adminおよびxs_cache_adminをディスパッチャに付与できます。

セキュリティのベスト・プラクティスでは、アプリケーション・ユーザーに最小限の権限を付与する必要があるため、中間層構成にはディスパッチャ・モードをお薦めします。

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

中間層キャッシュ設定の変更について

セッション・マネージャは、初期化されると、ACLやSecurityクラス情報などの一部のデータのキャッシュへの追加を開始します。このキャッシュ・データは再利用できます。キャッシュは、後で変更できるデフォルト設定で初期化されます。

最大キャッシュ・アイドル時間の設定について

最大キャッシュ・アイドル時間を設定するには、XSSessionManagerクラスのsetCacheMaxIdleTimeメソッドを使用します。setCacheMaxIdleTimeメソッドは、キャッシュが更新なしで存続できる最大時間(分)を設定します。

キャッシュからオブジェクトのフェッチが試行され、XSSessionManagersetCacheMaxIdleTimeメソッドで設定された値と同じ期間にわたってupdateCacheメソッドをコールしていない場合は、オブジェクトを戻す前にupdateCacheメソッドが強制的に起動されて、キャッシュされたすべてのオブジェクトがまだ有効であることが確認されます。setCacheMaxIdleTimeメソッドのコール元には、JAAS権限XSSecurityPermission("setCacheMaxIdleTime")が必要です。

最大キャッシュ・サイズの設定について

最大キャッシュ・サイズを設定するには、XSSessionManagerクラスのsetCacheMaxSizeメソッドを使用します。このメソッドは、中間層のキャッシュのサイズを設定します。

キャッシュのデフォルト・サイズは10MBです。最小キャッシュ・サイズは1MBです。setCacheMaxSizeメソッドのコール元には、JAAS権限XSSecurityPermission("setCacheMaxSize")が必要です。

最大キャッシュ・アイドル時間の取得について

最大キャッシュ・アイドル時間を取得するには、XSSessionManagerクラスのgetCacheMaxIdleTimeメソッドを使用します。このメソッドは、キャッシュを更新するためのupdateCacheコールがキャッシュに対して行われない最大時間(分)を戻します。getCachemaxIdleTimeメソッドのコール元には、JAAS権限XSSecurityPermission("getCacheMaxIdleTime")が必要です。

最大キャッシュ・サイズの取得について

最大キャッシュ・サイズを取得するには、XSSessionManagerクラスのgetCacheMaxSizeメソッドを使用します。このメソッドは、キャッシュの最大サイズをバイト単位で戻します。getCacheMaxSizeメソッドのコール元には、JAAS権限XSSecurityPermission("getCacheMaxSize")が必要です。

キャッシュからのエントリの削除について

キャッシュからエントリを削除するには、キャッシュ削除アルゴリズムが水位標レベルとともに使用されます。水位標レベルは、データが削除される前にメモリー・キャッシュに存続する必要のある期間を決定します。キャッシュ・サイズが高水位標に達すると、キャッシュ削除アルゴリズムによって、キャッシュ・サイズが低水位標に達するまでエントリが削除されます。

この項では、キャッシュからエントリを削除するための次のアクティビティについて説明します。
水位標の設定について

水位標を設定するには、XSSessionManagerクラスのsetWaterMarkメソッドを使用します。setWaterMarkメソッドのコール元には、JAAS権限XSSecurityPermission("setWaterMark")が必要です。

高水位標の取得について

キャッシュの高水位標を取得するには、XSSessionManagerクラスのgetHighWaterMarkメソッドを使用します。

低水位標の取得について

キャッシュの低水位標を取得するには、XSSessionManagerクラスのgetLowWaterMarkメソッドを使用します。

キャッシュの消去について

中間層からキャッシュを明示的にクリアするには、XSSessionManagerクラスのclearCacheメソッドを使用します。このメソッドは、中間層から共有キャッシュを明示的にクリアします。clearCacheメソッドのコール元には、JAAS権限XSSecurityPermission("clearCache")が必要です。

Real Application Securityセッションの管理について

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

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

アプリケーション・セッションの連結

アプリケーション・セッションを連結するには、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);

アプリケーション・ユーザーの割当てまたは切替え

匿名セッションがある場合は、後で別のアプリケーション・ユーザーに再割当てできます。または、セッションがすでにアプリケーション・ユーザーに割り当てられている場合は、セッションを別のアプリケーション・ユーザーに切り替えることができます。どちらの場合も、アプリケーション・ユーザーを割り当てるか切り替える前に、セッションが連結されている必要があります。

以前の匿名アプリケーション・ユーザーに名前を割り当てるには、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);

Real Application Securityアプリケーション・ロールの有効化

Real Application Securityアプリケーション・ロールは、Real Application Securityアプリケーション・ユーザーまたは別のReal Application Securityアプリケーション・ロールにのみ付与できるロールです。Real Application Securityアプリケーション・ロールは、データベース・ロールを通じて付与されるデータベース権限です。データベース権限はデータベース・ロールに付与され、データベース・ロールはReal Application Securityアプリケーション・ロールに付与されます。Real Application Securityアプリケーション・ユーザーおよびアプリケーション・ロールの詳細は、プリンシパル: ユーザーおよびロールを参照してください。

この項では、アプリケーション・ロールに関連付けられている次の操作について説明します。

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

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

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

セッション・ユーザーとしてのネームスペース操作の実行について

ネームスペースは、セッション・コンテキストの追加属性のグループです。アプリケーションは、ネームスペースを使用して、アプリケーションで定義された属性と値のペアを格納します。現在のセッション・ユーザーには、(ネームスペースに対する) MODIFY_NAMESPACEおよび(属性に対する) MODIFY_ATTRIBUTEアプリケーション権限が必要です。ネームスペースの詳細は、ネームスペース・テンプレートを使用したネームスペースの作成を参照してください。

この項では、次のアクティビティの実行方法について説明します。

ネームスペースの作成

Javaでネームスペースを作成するには、SessionインタフェースのcreateNamespaceメソッドを使用します(例6-10を参照)。createNamespaceメソッド(太字)は、名前が指定した名前と一致するネームスペース・テンプレート・ドキュメントを使用して、新しいセッション・ネームスペースを作成します。イベント・ハンドラがテンプレート・ドキュメントで指定されている場合は、指定されたイベント・ハンドラが、そのテンプレートを使用して作成されたすべてのネームスペースに適用されます。

注意:

前の項で説明したcreateSessionおよびattachSessionメソッドにネームスペース名をパラメータとして渡すことにより、ネームスペースを作成することもできます。

例6-10 Javaでのネームスペースの作成方法

Session lws = null;
...
SessionNamespace ns = lws.createNamespace("TESTNS1");

ネームスペースの削除

Javaでネームスペースを削除するには、SessionインタフェースのdeleteNamespaceメソッドを使用します(例6-11を参照)。deleteNamespaceメソッド(太字)は、セッションからネームスペースを削除します。

例6-11 Javaでのネームスペースの削除方法

Session lws = null;
...
SessionNamespace ns = lws.createNamespace("TESTNS1");
...
lws.deleteNamespace("TESTNS1");

ネームスペースの暗黙的な作成

セッション・ネームスペースを表すネームスペース・オブジェクトを暗黙的に作成するには、SessionインタフェースのgetNamespaceメソッドを使用します(例6-12を参照)。getNamespaceメソッドは太字で示されています。指定されたネームスペースがすでに存在する場合は、エラーがスローされます。

ネームスペースの文字列表現を取得するには、SessionNamespaceインタフェースのtoStringメソッドを使用します。

例6-12 Javaでネームスペースを暗黙的に作成する方法

Session lws = null;
...
SessionNamespace ns2 = lws.getNamespace("TESTNS1");

ネームスペース属性の使用方法について

セッション・ネームスペースは、単一のアプリケーション・モジュールがセッションの継続時間にわたって格納する属性を管理します。セッション・ネームスペースは、単一のネームスペース、単一のアクセス制御制限セット、またはそのネームスペースの属性変更イベントをディスパッチする単一のイベント・ハンドラ・プロシージャを格納します。

この項では、次のアクティビティの実行方法について説明します。

セッション・ネームスペース属性の作成

Javaでセッション・ネームスペース属性を作成するには、SessionNamespaceインタフェースのcreateAttributeメソッドを使用します(例6-13を参照)。createAttributeメソッド(太字)は、ネームスペースに新しい属性を作成します。

例6-13 Javaでのセッション・ネームスペース属性の作成方法

String name1="empid';
String value1="JB007";
SessionNamespace ns;
...
SessionNamespaceAttribute sa1=ns.createAttribute(name1,value1);
...
セッション・ネームスペース属性の設定について

Javaでセッション・ネームスペース属性を設定するには、SessionNamespaceインタフェースのsetAttributeメソッドを使用します。

セッション・ネームスペース属性の取得

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");
...
属性のリスト

ネームスペース内の属性をリストするには、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());
}
...
属性のリセット

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");
...
属性の削除

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");
...

セッション・マネージャとしてのネームスペース操作の実行について

各ネームスペースには、誰がネームスペースとその属性を操作できるかを決定するためにACLが関連付けられています。アプリケーションで現在のセッション・ユーザーがネームスペースを操作できないようにし、セッション・マネージャには操作を許可する場合は、セッション・マネージャXSSessionManagerとしてこれを行うことができます。

XSSessionManagerには、ネームスペースを管理するためのSessionとしてオーバーロードされたメソッドのセットがあります。使用方法は、セッション・ユーザーとしてのネームスペース操作の実行についてでのセッション・ユーザーに関する説明と同様です。

セッション・マネージャ・インスタンスXSSessionManagerはアプリケーション・コードで使用可能でない場合があり、信頼されたインフラストラクチャ・レイヤーだけがセッション・マネージャを使用して、このようなセキュリティで保護されたネームスペースを操作できます。

その他のセッション関連アクティビティの実行について

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

セッションに関連付けられたOracle接続の取得について

現在セッションにバインドされている場合に、セッションに関連付けられているOracle接続を取得するには、SessionインタフェースのgetConnectionメソッドを使用します。

セッションのアプリケーション・ユーザーIDの取得について

特定のセッションのアプリケーション・ユーザー識別子(ID)を取得するには、SessionインタフェースのgetUserIdメソッドを使用します。

セッションのアプリケーション・ユーザーが匿名かどうかを確認するには、SessionインタフェースのisAnonymousメソッドを使用します。

セッションのセッションIDの取得

特定のセッションのセッション識別子(ID)を取得するには、SessionインタフェースのgetIdメソッドを使用します(例6-18を参照)。getIdメソッドは太字で示されています。

例6-18 JavaでセッションのセッションIDを取得する方法

Session lws=null;
...
System.out.println( "The Session ID is" +  lws.getId());

セッションの文字列表現の取得について

セッションの文字列表現を取得するには、SessionインタフェースのtoStringメソッドを使用します。

セッションCookieの取得

セッションに使用されるセキュアなセッションCookieを取得するには、SessionインタフェースのgetSessionCookieメソッドを使用します(例6-19を参照)。getSessionCookieメソッドは太字で示されています。

例6-19 JavaでセキュアなセッションCookieを取得する方法

static Session lws;
...
System.out.println(lws.getSessionCookie());

セッション・マネージャとしてのセッション非アクティブ・タイムアウトの設定

セッションでタイムアウトを設定するには、SessionManagerインタフェースのsetInactivityTimeoutメソッドを使用します。このメソッドは、分単位のセッション・タイムアウトを設定します。

setInactivityTimeoutメソッドは、通常のセッション・タイムアウト構成をオーバーライドします。メソッドは次のとおりです。

sessionManager.setInactivityTimeout(Session session, int minutes);

セッション・マネージャとしてのセッション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");

アプリケーション・セッションの連結解除

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

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

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

ACLを使用したアプリケーション・ユーザーの認可について

認可も、アプリケーションで必要な主要セキュリティ機能です。Real Application Securityでは、認可ポリシーはアクセス制御リスト(ACL)とアプリケーション権限から構成されます。これらはReal Application Securityデータベースで定義され、中間層のキャッシュで管理されます。アプリケーション権限はデータ権限です。データ権限は、ファンクションのアクセスまたはデータの操作の定義に使用されます。ファンクションがセッションへの接続を連結すると、接続にパススルーされた問合せはデータベース・サーバーによって自動的に施行されます。

AclIdクラスは、次の操作を実行する各種メソッドを提供します。

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");
...

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

特定のACLに関連付けられているデータ権限の取得について

特定のACLで付与されているデータ権限の集合を取得するには、SessionクラスのgetPrivilegesメソッドを使用します。

注意:

データ・セキュリティにはcheckAclメソッドを使用し、機能セキュリティにはcheckPrivilegeメソッドを使用します。

人事管理のユースケース: 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();
    }
  }
 
  1. JavaでのセキュリティHRデモの実行では、Real Application Securityコンポーネントを設定するためにセキュリティHRデモ・コンポーネントの設定で説明した設定スクリプトが実行されていることを前提とします。
  2. Javaコードをコンパイルします。
    $ORACLE_HOME/jdk6/bin/javac -classpath $ORACLE_HOME/rdbms_ho/jlib/xs.jar:$ORACLE_HOME/dbjava/lib/ojdbc6.jar HRdemo.java
    

    注意:

    JDK 6をOracleホーム・ディレクトリにあるxs.jarおよびojdbc6.jarとともに使用する必要があります。異なるjarおよびJDKでは動作しないことがあります。

  3. Javaコードを実行します。
    $ORACLE_HOME/jdk6/bin/java -classpath $ORACLE_HOME/rdbms_ho/jlib/xs.jar:$ORACLE_HOME/dbjava/lib/ojdbc6.jar
    
    HRdemo db_hr db_hr jdbc:oracle:thin:@myserver:myport:mysid
    

出力

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列のすべてのデータを含むすべての従業員レコードを表示できます。