この章の内容は、次のとおりです。
この項の内容は、次のとおりです。
アプリケーション・コンテキストとは、Oracle Databaseがメモリーに格納する名前と値のペアです。アプリケーション・コンテキストには、ネームスペースと呼ばれるラベル(たとえば、従業員IDを取得するアプリケーション・コンテキストはempno_ctx
)があります。コンテキスト内は名前と値のペア(結合配列)です。名前は、値を保持するメモリー内の場所を指定します。アプリケーションはアプリケーション・コンテキストを使用して、ユーザーに関するセッション情報(ユーザーIDまたは他のユーザー固有の情報など)またはクライアントIDにアクセスして、その情報をデータベースに安全に引き渡すことができます。この情報を使用して、ユーザーがアプリケーションを通じてデータにアクセスできるようにしたりアクセスできないようにできます。アプリケーション・コンテキストを使用して、データベース・ユーザーと非データベース・ユーザーの両方を認証できます。
名前:値に関連付けられている属性セットの名前を示します。たとえば、empno_ctx
アプリケーション・コンテキストは従業員IDをHR.EMPLOYEES
表から取得する場合、名前をemployee_id
にすることができます。
値:属性により設定される値を示します。たとえば、empno_ctx
アプリケーション・コンテキストでは、HR.EMPLOYEES
表から従業員IDを取得する場合、このIDの値を設定する、emp_id
と呼ばれる値を作成できます。
アプリケーション・コンテキストは、データベース・セッション中にアクセスされる情報を保持するグローバル変数と考えてください。セキュア・アプリケーション・コンテキストの値を設定するには、DBMS_SESSION.SET_CONTEXT
プロシージャを使用するPL/SQLパッケージ・プロシージャを作成する必要があります。実際、コンテキストがINITIALIZED EXTERNALLY
またはINITIALIZED GLOBALLY
とマークされていない場合は、事実上、この方法がアプリケーション・コンテキスト値を設定できる唯一の方法となります。アプリケーション・コンテキスト属性には、アプリケーション・コンテキストの作成時ではなく、実行時に値を割り当てることができます。ユーザーではなくトラステッド・プロシージャによって値が割り当てられるため、これはセキュア・アプリケーション・コンテキストと呼ばれます。クライアント・セッション・ベースのアプリケーション・コンテキストの場合、Oracle Call Interface(OCI)コールを使用してアプリケーション・コンテキストを設定することもできます。
アプリケーション・コンテキストの値は、ユーザー・グローバル領域(UGA)またはシステム・グローバル領域(SGA)(共有グローバル領域と呼ばれる場合もあります)内の使用可能な保護データ・キャッシュに格納されます。格納されたアプリケーション・コンテキストの値はセッション中に取得されます。アプリケーション・コンテキストには、このデータ・キャッシュ内の値が格納されるため、アプリケーションのパフォーマンスが向上します。アプリケーション・コンテキストは単独で使用でき、Oracle Virtual Private Databaseポリシーまたはその他のファイングレイン・アクセス制御ポリシーと併用することもできます。アプリケーション・コンテキストと仮想プライベート・データベース・ポリシーの併用については、「Oracle Virtual Private Databaseでのアプリケーション・コンテキストの使用」を参照してください。
ほとんどのアプリケーションには、アプリケーション・コンテキストに使用可能なある種の情報が含まれています。たとえば、ORDER_NUMBER
列とCUSTOMER_NUMBER
列を備えた表を使用する受注管理アプリケーションでは、それらの列の値をセキュリティ属性として使用して、顧客によるアクセスをその顧客のIDに基づいて顧客自身の注文のみに制限できます。
アプリケーション・コンテキストは、次の目的で使用されます。
ファイングレイン・アクセス・コントロールの規定(Oracle Virtual Private Databaseポリシーなどで)
複数層環境でのユーザー識別情報の保持
アプリケーションに対する強力なセキュリティの規定(アプリケーション・コンテキストはユーザーではなくトラステッド・プロシージャによって制御されるため)
アプリケーションがファイングレイン監査やPL/SQL条件文またはループで使用する際に必要な属性に対して、保護データ・キャッシュとしての機能を果たすことによるパフォーマンスの向上
このキャッシュによって、これらの属性が必要になるたびにデータベースに問い合せるというオーバーヘッドが軽減されます。アプリケーションはセッション・データを表から繰り返し取得する必要がなく、このデータがアプリケーション・コンテキストによってキャッシュに格納されるため、アプリケーションのパフォーマンスが大幅に向上します。
アプリケーションで定義、変更およびアクセスできる名前と値のペアの保持領域として機能
アプリケーション・コンテキストには、3種類の一般的なカテゴリがあります。
データベース・セッション・ベースのアプリケーション・コンテキスト。このタイプのアプリケーション・コンテキストは、データベース・ユーザー・セッション(つまりUGA)のキャッシュに格納されているデータを取得します。データベース・セッション・ベースのアプリケーション・コンテキストは、3つのカテゴリに分類されます。
ローカルで初期化。ユーザーのセッションに対してアプリケーション・コンテキストをローカルで初期化します。
外部で初期化。Oracle Call Interface(OCI)アプリケーション、ジョブ・キュー・プロセスまたは接続ユーザーのデータベース・リンクからアプリケーション・コンテキストを初期化します。
グローバルに初期化。LDAPディレクトリなどの集中格納場所から属性と値を使用します。
このタイプのアプリケーション・コンテキストについては、「データベース・セッション・ベースのアプリケーション・コンテキストの使用」を参照してください。
グローバル・アプリケーション・コンテキスト。このタイプは、システム・グローバル領域(SGA)に格納されるデータを取得するため、3層アーキテクチャの中間層アプリケーションなど、セッションを使用しないアプリケーションに対して使用できます。グローバル・アプリケーション・コンテキストは、セッション・コンテキストをセッション間で、たとえば接続プールの実装を通じて共有する場合に便利です。
このタイプのアプリケーション・コンテキストについては、「グローバル・アプリケーション・コンテキストの使用」を参照してください。
クライアント・セッション・ベースのアプリケーション・コンテキスト。このタイプのアプリケーション・コンテキストは、クライアント側のOracle Call Interface関数を使用してユーザー・セッション・データを設定し、次に、必要なセキュリティ・チェックを実行してユーザー・アクセスを制限します。
このタイプのアプリケーション・コンテキストについては、「クライアント・セッション・ベースのアプリケーション・コンテキストの使用」を参照してください。
表6-1に、異なるタイプのアプリケーション・コンテキストの要約を示します。
表6-1 アプリケーション・コンテキストの種類
アプリケーション・コンテキストの種類 | UGAへの格納 | SGAへの格納 | 接続ユーザー・データベース・リンクのサポート | ユーザーのアプリケーション・コンテキストの集中保管のサポート | セッションを使用しない複数層アプリケーションのサポート |
---|---|---|---|---|---|
ローカルで初期化されるデータベース・セッション・ベースのアプリケーション・コンテキスト |
あり |
なし |
なし |
なし |
なし |
外部で初期化されるデータベース・セッション・ベースのアプリケーション・コンテキスト |
あり |
なし |
あり |
なし |
なし |
グローバルに初期化されるデータベース・セッション・ベースのアプリケーション・コンテキスト |
あり |
なし |
なし |
あり |
なし |
グローバル・アプリケーション・コンテキスト |
なし |
あり |
なし |
なし |
あり |
クライアント・セッション・ベースのアプリケーション・コンテキスト |
あり |
なし |
あり |
なし |
あり |
データベース・ユーザーのセッション情報を取得する必要がある場合は、データベース・セッション・ベースのアプリケーション・コンテキストを使用します。このタイプのアプリケーション・コンテキストは、Oracle Database内でPL/SQLプロシージャを使用し、管理の対象となるデータを取得、設定および保護します。
注意: ユーザーがアプリケーション・ユーザー(つまり、データベースに存在しないユーザー)の場合は、グローバル・アプリケーション・コンテキストの使用を考慮してください。詳細は、「グローバル・アプリケーション・コンテキストの使用」を参照してください。 |
データベース・セッション・ベースのアプリケーション・コンテキストは、Oracle Databaseの中で完全管理されます。Oracle Databaseが値を設定し、ユーザーがセッションを終了すると、キャッシュに保管されたアプリケーション・コンテキスト値を自動的に消去します。ユーザー接続が異常終了すると(たとえば停電)、PMONバックグラウンド・プロセスはアプリケーション・コンテキスト・データをクリーン・アップします。アプリケーション・コンテキストをキャッシュから消去する必要はありません。
アプリケーション・コンテキストをOracle Databaseで管理する利点は、アプリケーション・コンテキストを集中管理できる点です。このデータベースにアクセスするアプリケーションは、このアプリケーション・コンテキストを使用して、そのアプリケーションに対するユーザーのアクセスを許可または防止する必要があります。これによって、パフォーマンス向上とセキュリティ強化の両方の利点が得られます。
データベース・セッション・ベースのアプリケーション・コンテキストを作成して使用するには、次のコンポーネントを使用します。
アプリケーション・コンテキスト。アプリケーション・コンテキストを作成するには、CREATE CONTEXT
SQL文を使用します。この文は、アプリケーション・コンテキスト(ネームスペース)名を設定し、セッション・データを取得してアプリケーション・コンテキストを設定するように設計されたPL/SQLプロシージャに対して、その名前を関連付けます。
データの取得とコンテキストの設定を実行するPL/SQLプロシージャ。このプロシージャで実行する必要があるタスクについては、「データベース・セッション・ベースのアプリケーション・コンテキストを管理するパッケージの概要」を参照してください。理想的には、必要に応じて他のプロシージャ(タスクのエラー・チェックなど)を挿入できるように、このプロシージャは1つのパッケージ内に作成します。
ユーザーのログイン時にアプリケーション・コンテキストを設定する手段。アプリケーション・コンテキストを使用するアプリケーションにログインするユーザーは、そのアプリケーション・コンテキストを設定するPL/SQLパッケージを実行する必要があります。そのためには、ユーザーがログインするたびに起動するログイン・トリガーを使用するか、この機能をアプリケーションに埋め込むことができます。
ローカルで初期化されるデータベース・セッション・ベースのアプリケーション・コンテキストの作成方法と使用方法は、「例: データベース・セッション・ベースのアプリケーション・コンテキストの作成と使用」を参照してください。
セッション・ベースのアプリケーション・コンテキストは外部で、またはグローバルに初期化することもできます。いずれの場合も、コンテキスト情報はユーザー・セッションに格納されます。
外部での初期化。この初期化は、OCIインタフェース、ジョブ・キュー・プロセスまたは接続ユーザーのデータベース・リンクから発生します。詳細は、「データベース・セッション・ベースのアプリケーション・コンテキストの外部での初期化」を参照してください。
グローバルな初期化。この初期化では、LDAPディレクトリなどの集中格納場所から属性と値を使用します。詳細は、「データベース・セッション・ベースのアプリケーション・コンテキストのグローバルな初期化」を参照してください。
データベース・セッション・ベースのアプリケーション・コンテキストを作成するには、CREATE
CONTEXT
SQL文を使用します。ここで、アプリケーション・コンテキストのネームスペースを作成してから、ユーザーのセッション情報を保持する名前と値のペアを管理するPL/SQLパッケージに関連付けます。この文を実行するために、CREATE ANY CONTEXT
システム権限が必要です。アプリケーション・コンテキストを削除する場合は、DROP CONTEXT
文を使用するためにDROP ANY CONTEXT
権限が必要になります。データベース・セッション・ベースのアプリケーション・コンテキストでは、データはデータベース・ユーザー・セッション(UGA)のネームスペース内に保管され、これはCREATE CONTEXT
SQL文を使用して作成されます。
各アプリケーション・コンテキストには一意の属性が必要で、1つのネームスペースに属している必要があります。つまり、コンテキスト名は、スキーマ内のみでなくデータベース内でも一意である必要があります。
アプリケーション・コンテキストの所有権については、CREATE ANY CONTEXT
権限とDROP ANY CONTEXT
権限を付与されたユーザーがそのアプリケーション・コンテキストを作成および削除できた場合でも、SYS
スキーマが所有しています。Oracle Databaseは、作成したスキーマ・アカウントにコンテキストを関連付けますが、このユーザーを削除した場合、コンテキストはそれでもSYS
スキーマの中に存在します。ユーザーSYS
であれば、アプリケーション・コンテキストを削除できます。
例6-1に、CREATE CONTEXT
を使用してデータベース・セッション・ベースのアプリケーション・コンテキストを作成する方法を示します。
ここで、empno_ctx
はコンテキスト・ネームスペース、set_empno_ctx_pkg
はそのempno_ctx
ネームスペースの属性を設定するパッケージです。PL/SQLパッケージは、アプリケーション・コンテキストの作成時には不要ですが、実行時には存在している必要があります。このアプリケーション・コンテキストで使用可能なパッケージの作成方法の例は、「手順3: セッション・データを取得してアプリケーション・コンテキストを設定するパッケージの作成」を参照してください。
コンテキストを作成するときは、そのコンテキストの名前/値の属性をCREATE CONTEXT
文に設定しないでください。これらの属性は、アプリケーション・コンテキストに関連付けるパッケージに設定してください。これは、不正なユーザーによって、適切な属性の検証なしにコンテキスト属性が変更されないようにするためです。
注意: CLIENTCONTEXT というコンテキストは作成できません。これは、クライアント・セッション・ベースのアプリケーション・コンテキストで使用される予約語です。このタイプのアプリケーション・コンテキストの詳細は、「クライアント・セッション・ベースのアプリケーション・コンテキストの使用」を参照してください。 |
各アプリケーションには、独自の属性を持つアプリケーション・コンテキストを作成できます。たとえば、General Ledger(一般会計)、Order Entry(受注管理)およびHuman Resources(人事管理)という3つのアプリケーションがあるとします。これらの各アプリケーションには、異なる属性を指定できます。
受注管理アプリケーション・コンテキストには、CUSTOMER_NUMBER
属性を指定できます。
一般会計アプリケーション・コンテキストには、SET_OF_BOOKS
属性とTITLE
属性を指定できます。
人事管理アプリケーション・コンテキストには、ORGANIZATION_ID
、POSITION
、COUNTRY
の各属性を指定できます。
属性がアクセスするデータは、アプリケーション外の表に保管されます。たとえば、受注管理アプリケーションではOE.CUSTOMERS
という名前の表が使用されており、この中のCUSTOMER_NUMBER
列にはCUSTOMER_NUMBER
属性のデータが入ります。いずれの場合にも、アプリケーション・コンテキストを厳密なセキュリティ・ニーズに適用できます。
PL/SQLパッケージは、通常、セキュリティ管理者のスキーマに作成され、アプリケーション・コンテキストによって表されるセッション・データを管理するプロシージャを定義します。次のタスクを実行する必要があります。
セッション情報の取得。ユーザー・セッション情報の取得には、SYS_CONTEXT
SQL関数を使用できます。このSYS_CONTEXT
関数は、コンテキストのネームスペースに関連付けられているパラメータの値を戻します。この関数は、SQL文とPL/SQL文の両方で使用できます。通常は、組み込まれているUSERENV
ネームスペースを使用してユーザーのセッション情報を取得します。(SYS_CONTEXT
関数の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。)
CREATE CONTEXTで作成したアプリケーション・コンテキストの名前/値の属性の設定。アプリケーション・コンテキストの名前/値の属性の設定には、DBMS_SESSION.SET_CONTEXT
プロシージャを使用できます。この名前/値の属性には、ユーザーID、IPアドレス、認証モード、アプリケーション名などの情報を格納できます。設定した属性の値は、再設定するまで、またはユーザーがセッションを終了するまでそのまま残ります。次のことに注意してください。
ネームスペース内のパラメータの値がすでに設定されている場合は、SET_CONTEXT
によってこの値が上書きされます。
コンテキストの値が変更された場合、その内容はただちに反映され、SYS_CONTEXT
ファンクションによって値を取得する後続のコールでは、最新の値が戻されます。
ユーザーによる実行。パッケージを作成した後、ログインする場合ユーザーはそのパッケージを実行する必要があります。ユーザーがログインするときパッケージを自動的に実行するためのログイン・トリガーを作成するか、この機能をアプリケーションに埋め込むことができます。アプリケーション・コンテキスト・セッション値はユーザーがセッションを終了すると自動的に消去されるので、セッション・データを手動で削除する必要はありません。
プロシージャはトラステッド・プロシージャであることに注意してください。ユーザーが自分独自のアプリケーション・コンテキスト属性値を設定できないように設計されています。ユーザーはプロシージャを実行しますが、プロシージャがアプリケーション・コンテキスト値を設定します、ユーザーではありません。
データベース・セッション・ベースのアプリケーション・コンテキストの作成方法は、「例: データベース・セッション・ベースのアプリケーション・コンテキストの作成と使用」を参照してください。
PL/SQLファンクションのSYS_CONTEXT
の構文は、次のとおりです。
SYS_CONTEXT ('namespace','parameter'[,length])
次のように値を指定します。
namespace
: アプリケーション・コンテキストの名前。文字列、または文字列として評価される式を指定できます。SYS_CONTEXT
ファンクションは、現時点でコンテキストのネームスペースに関連付けられているパラメータの値を戻します。ネームスペース内のパラメータの値がすでに設定されている場合は、SET_CONTEXT
によってこの値が上書きされます。
parameter
: namespace
アプリケーション・コンテキスト内のパラメータ。この値には、文字列または式を指定できます。
length
: オプションです。戻り型の最大サイズはデフォルトで256バイトですが、最大で4000バイトの値を指定して長さを変更できます。NUMBER
データ型の値を入力するか、NUMBER
に明示的に変換できる値を入力します。SYS_CONTEXT
戻り型のデータ型はVARCHAR2
です。
SYS_CONTEXT
関数には、ログインしたユーザーのカレント・セッションを表すデフォルト・ネームスペースUSERENV
があります。SYS_CONTEXT
を使用して、ユーザー・ホスト・コンピュータID、ホストIPアドレス、オペレーティング・システム・ユーザー名など、ユーザーに関する様々なタイプのセッション・ベースの情報を取得できます。セッション・データを設定
ではなく、取得するにはUSERENVのみを使用することに注意してください。事前定義の属性は、『Oracle Database SQL言語リファレンス』のPL/SQLファンクションの説明でリストされています。
たとえば、次のようにUSERENV
のHOST
パラメータを使用して、クライアントが接続しているホスト・コンピュータの名前を取得できます。
SYS_CONTEXT ('userenv','host')
SYS_CONTEXT
設定は、DUAL表に対してSELECT
SQL文を発行することでチェックできます。DUAL
表はデータ・ディクショナリ内の小さい表で、既知の結果を保証するためにOracle Databaseおよびユーザーが記述したプログラムから参照できます。この表には、DUMMY
という列と、値X
が格納されている行があります。
例6-2では、ログインしたホスト・コンピュータの検索方法を示しています。この例では、EMP_USERS
の下のSHOBEEN_PC
ホスト・コンピュータにログインしたと想定しています。
指定した問合せを実行する間にポリシーの変更が予想されるセッション中は、その問合せに動的SQLを使用する必要があります。静的SQLと動的SQLでは文の解析方法が異なるため、必ず動的SQLを使用してください。
静的SQL文はコンパイル時に解析されます。パフォーマンス上の理由から実行時には再解析されません。
動的SQL文は、実行されるたびに解析されます。
SQL文のコンパイル時にはポリシーAを規定し、その後、ポリシーBに変更して文を実行する場合を考えてみます。静的SQLでは、ポリシーAが規定されたままです。文はコンパイル時に解析されますが、実行時には再解析されません。動的SQLでは、文は実行時に解析されるため、ポリシーBへの切替えが有効となります。
たとえば、次のポリシーを考えてみます。
EMPLOYEE_NAME = SYS_CONTEXT ('USERENV', 'SESSION_USER')
ポリシーEMPLOYEE_NAME
は、データベース・ユーザー名と一致しています。Oracle Virtual Private DatabaseではSQL述語の形で表され、述語はポリシーとみなされます。述語が変更された場合、正しい結果を生成するために文を再度解析する必要があります。
パラレル問合せに埋め込まれているSQL関数内でSYS_CONTEXT
を使用すると、この関数にアプリケーション・コンテキストが挿入されます。
ユーザーIDを5に設定する、SQL文内のユーザー定義関数を考えてみます。
CREATE FUNCTION set_id RETURN NUMBER IS BEGIN IF SYS_CONTEXT ('hr', 'id') = 5 THEN RETURN 1; ELSE RETURN 2; END IF; END;
次の文を考えてみます。
SELECT * FROM emp WHERE set_id( ) = 1;
この文をパラレル問合せとして実行すると、アプリケーション・コンテキスト情報を含むユーザー・セッションはパラレル実行サーバー(問合せ子プロセス)に伝播されます。
ユーザー・セッション内のSQL文にデータベース・リンクが含まれている場合は、そのデータベース・リンクのホスト・コンピュータでSYS_CONTEXT
SQL関数が実行され、そのホスト・コンピュータにあるコンテキスト情報が取得されます。
リモートのPL/SQLプロシージャ・コールがデータベース・リンクで実行されている場合は、そのプロシージャ内部のすべてのSYS_CONTEXT
関数が、そのリンクの宛先データベースで実行されます。この場合、データベース・リンクの宛先サイトで使用できるのは、外部で初期化されたアプリケーション・コンテキストのみです。セキュリティ上の理由から、データベース・リンクの開始サイトから宛先サイトに伝播されるのは、外部で初期化されたアプリケーション・コンテキストのみです。
SYS_CONTEXT
関数を使用してユーザーのセッション・データを取得後、アプリケーション・コンテキスト値をこのユーザーのセッションから設定できます。そのためには、DBMS_SESSION.SET_CONTEXT
プロシージャを使用します。(DBMS_SESSION
PL/SQLパッケージに対するEXECUTE
権限を所有していることを確認してください。)
構文は、次のとおりです。
DBMS_SESSION.SET_CONTEXT ( namespace VARCHAR2, attribute VARCHAR2, value VARCHAR2, username VARCHAR2, client_id VARCHAR2);
次のように値を指定します。
namespace
: 設定するアプリケーション・コンテキストのネームスペース(30バイトに制限)。たとえば、custno_ctx
という名前のネームスペースを使用していた場合は、次のように指定します。
namespace => 'custno_ctx',
attribute
: 設定するアプリケーション・コンテキストの属性(30バイトに制限)。たとえばcustno_ctx
ネームスペースのctx_attrib
属性を作成する場合は、次のようになります。
attribute => 'ctx_attrib',
value
: 設定するアプリケーション・コンテキストの値(4000バイトに制限)。通常、これはSYS_CONTEXT
関数で取得されて変数に格納された値です。次に例を示します。
value => ctx_value,
username
: オプション。アプリケーション・コンテキストのデータベース・ユーザー名属性。デフォルトはNULL
で、すべてのユーザーにセッションへのアクセスを許可します。データベース・セッション・ベースのアプリケーション・コンテキストでは、この設定は省略され、デフォルトのNULL
が使用されます。
username
およびclient_id
パラメータは、グローバルにアクセスされるアプリケーション・コンテキストに対して使用されます。詳細は、「DBMS_SESSION.SET_CONTEXTのusernameおよびclient_idパラメータの設定」を参照してください。
client_id
: オプション。アプリケーション・コンテキストのアプリケーション固有のclient_id
属性(最大64バイト)です。デフォルトはNULL
で、クライアントIDが指定されていないことを意味します。データベース・セッション・ベースのアプリケーション・コンテキストでは、この設定は省略され、デフォルトのNULL
が使用されます。
DBMS_SESSIONパッケージの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。
例6-1で作成したアプリケーション・コンテキストを例にします。
CREATE CONTEXT empno_ctx USING set_empno_ctx_proc;
例6-3に、empno_ctx
アプリケーション・コンテキストの属性を作成する単純なプロシージャの作成方法を示します。
例6-3 アプリケーション・コンテキストの値を作成する単純なプロシージャ
CREATE OR REPLACE PROCEDURE set_empno_ctx_proc( emp_value IN VARCHAR2) IS BEGIN DBMS_SESSION.SET_CONTEXT('empno_ctx', 'empno_attrib', emp_value); END; / |
この例の説明は、次のとおりです。
emp_value IN VARCHAR2
はemp_value
を入力パラメータとして使用します。このパラメータは、アプリケーション・コンテキスト属性empno_attrib
に関連付けられている値を指定します。制限は4000バイトです。
DBMS_SESSION.SET_CONTEXT('empno_ctx', 'empno_attrib', emp_value)
は、DBMS_SESSION.SET_CONTEXT
プロシージャを次のように使用して、アプリケーション・コンテキストの値を設定します。
'empno_ctx'
: アプリケーション・コンテキストのネームスペースを示します。ネームスペース名は一重引用符で囲みます。
'empno_attrib'
: アプリケーション・コンテキストのネームスペースに関連付ける属性を作成します。
emp_value
: empno_attrib
属性の値を指定します。ここでは2行目
に定義されているemp_valueパラメータを参照しています。
これで、set_empno_ctx_proc
プロシージャを実行して、アプリケーション・コンテキストを設定できます。
EXECUTE set_empno_ctx_proc ('42783');
(実際には、アプリケーション・コンテキストの値はプロシージャ自体に設定することになるため、そのプロシージャがトラステッド・プロシージャとなります。この例は、データが設定される様子を示すことのみを目的に記載しています。)
アプリケーション・コンテキストの設定をチェックするには、次のSELECT
文を実行します。
SELECT SYS_CONTEXT ('empno_ctx', 'empno_attrib') empno_attrib FROM DUAL; EMPNO_ATTRIB -------------- 42783
SESSION_CONTEXT
データ・ディクショナリ・ビューを問い合せると、データベース・インスタンスのカレント・セッションにあるすべてのアプリケーション・コンテキスト設定を検索することもできます。次に例を示します。
SELECT * FROM SESSION_CONTEXT; NAMESPACE ATTRIBUTE VALUE -------------------------------------------------- EMPNO_CTX EMP_ID 42783
関連項目:
|
アプリケーション・コンテキストと関連のパッケージを作成した後は、ユーザーはログイン時にそのパッケージ・プロシージャを実行する必要があります。これを自動的に処理するようにログイン・トリガーを作成できます。パッケージを実行するためのEXECUTE
権限をユーザーに付与する必要はありません。
例6-4に、PL/SQLプロシージャを実行する単純なログイン・トリガーを示します。
例6-4 単純なログイン・トリガーの作成
CREATE OR REPLACE TRIGGER set_empno_ctx_trig AFTER LOGON ON DATABASE BEGIN sec_mgr.set_empno_ctx_proc; END;
例6-5は、WHEN OTHERS例外を使用するログイン・トリガーの作成方法を示しています。一方、PL/SQLロジックにエラーが発生して未処理例外を引き起こす場合は、データベースへのすべての接続がブロックされます。この例は、セキュリティ管理者のスキーマの表にエラーを書き込む
WHEN OTHERS
例外を示しています。本番環境では、こちらのほうが、出力をユーザー・セッションへ送信することでセキュリティ攻撃を受けやすくなるよりも安全です。
例6-5 本番環境用のログイン・トリガーの作成
CREATE OR REPLACE TRIGGER set_empno_ctx_trig AFTER LOGON ON DATABASE BEGIN sec_mgr.set_empno_ctx_proc; EXCEPTION WHEN OTHERS THEN v_code := SQLCODE; v_errm := SUBSTR(SQLERRM, 1 , 64); -- Invoke another procedure, -- declared with PRAGMA AUTONOMOUS_TRANSACTION, -- to insert information about errors. INSERT INTO sec_mgr.errors VALUES (v_code, v_errm, SYSTIMESTAMP); END; /
例6-6に、同じログイン・トリガーを開発環境用に作成する方法を示します。この場合、エラーをデバッグのためにユーザー・セッションに出力できます。
例6-6 開発環境用のログイン・トリガーの作成
CREATE TRIGGER set_empno_ctx_trig AFTER LOGON ON DATABASE BEGIN sysadmin_ctx.set_empno_ctx_pkg.set_empno; EXCEPTION WHEN OTHERS THEN RAISE_APPLICATION_ERROR( -20000, 'Trigger sysadmin_ctx.set_empno_ctx_trig violation. Login denied.'); END; /
次のことに注意してください。
ログイン・トリガーによって呼び出されたPL/SQLパッケージ・プロシージャに未処理例外があるか(たとえばセキュリティ・チェックに失敗したために)なんらかの例外を発生すると、ログイン・トリガーは失敗します。ログイン・トリガーに失敗すると、ログインは失敗し、つまりユーザーはデータベースにログインする権限が拒否されます。
ログイン・トリガーがパフォーマンスに影響を与える可能性があります。また、ログイン・トリガーは、最初にサンプル・スキーマ・ユーザーでテストしてから、データベース用に作成してください。これによって、エラーがあった場合は簡単に修正できます。
会計帳簿の変更や職階の変更が頻繁にある場合は注意が必要です。この場合、新しい属性値はすぐに選択できない可能性があるため、カーソルの再解析を強制実行して、新しい属性値を選択する必要があります。
この項の内容は、次のとおりです。
ユーザーSYS
でログインし、AS SYSDBA
権限を使用して接続します。
sqlplus sys as sysdba
Enter password: password
sysadmin_ctx
アカウントを作成します。このアカウントは、データベース・セッション・ベースのアプリケーション・コンテキストを管理します。
GRANT CREATE SESSION, CREATE ANY CONTEXT, CREATE PROCEDURE, CREATE TRIGGER, ADMINISTER DATABASE TRIGGER TO sysadmin_ctx IDENTIFIED BY password;
GRANT SELECT ON HR.EMPLOYEES TO sysadmin_ctx;
GRANT EXECUTE ON DBMS_SESSION TO sysadmin_ctx;
password
を安全なパスワードに置き換えます。詳細は、「パスワードの最低要件」を参照してください。
Lisa Ozerに対して、次のユーザー・アカウントを作成します。HR.EMPLOYEES
表には、lozer
というLisa Ozerの電子メール・アカウントがあります。
GRANT CREATE SESSION TO LOZER IDENTIFIED BY password;
password
を安全なパスワードに置き換えます。詳細は、「パスワードの最低要件」を参照してください。
この例ではサンプル・ユーザーSCOTT
も使用するため、DBA_USERS
データ・ディクショナリ・ビューを問い合せて、SCOTT
がロックされていたり、期限切れになっていないことを確認します。
SELECT USERNAME, ACCOUNT_STATUS FROM DBA_USERS WHERE USERNAME = 'SCOTT';
DBA_USERS
ビューに、ユーザーSCOTT
がロックされて期限切れになっていると表示された場合は、次の文を入力して、SCOTT
アカウントのロックを解除し、新しいパスワードを作成します。
ALTER USER SCOTT ACCOUNT UNLOCK IDENTIFIED BY password;
安全なパスワードを入力します。セキュリティを向上させるため、以前のリリースのOracle Databaseと同じパスワードをSCOTTアカウントに指定しないでください
。パスワードを作成するための最低要件は、「パスワードの最低要件」を参照してください。
sysadmin_ctx
でSQL*Plusにログインします。
CONNECT sysadmin_ctx
Enter password: password
次の文を使用してアプリケーション・コンテキストを作成します。
CREATE CONTEXT empno_ctx USING set_empno_ctx_pkg;
ユーザーsysadmin_ctx
がこのアプリケーション・コンテキストを作成した場合でも、SYS
スキーマがこのコンテキストを所有することに注意してください。
例6-7に、セッション・データを取得してアプリケーション・コンテキストを設定するために必要なパッケージの作成方法を示します。パッケージを作成する前に、ユーザーsysadmin_ctx
でログインしていることを確認してください。(最初の行のCREATE OR REPLACE
の前にカーソルを置くことで、このテキストをコピーして貼り付けることができます。)
例6-7 セッション・データを取得してデータベース・セッション・コンテキストを設定するためのパッケージ
CREATE OR REPLACE PACKAGE set_empno_ctx_pkg IS PROCEDURE set_empno; END; / CREATE OR REPLACE PACKAGE BODY set_empno_ctx_pkg IS PROCEDURE set_empno IS emp_id HR.EMPLOYEES.EMPLOYEE_ID%TYPE; BEGIN SELECT EMPLOYEE_ID INTO emp_id FROM HR.EMPLOYEES WHERE email = SYS_CONTEXT('USERENV', 'SESSION_USER'); DBMS_SESSION.SET_CONTEXT('empno_ctx', 'employee_id', emp_id); EXCEPTION WHEN NO_DATA_FOUND THEN NULL; END; END; / |
このパッケージでは、次の処理を実行するset_empno
というプロシージャが作成されます。
emp_id HR.EMPLOYEES.EMPLOYEE_ID%TYPE
は、ログインするユーザーの従業員IDを格納する変数emp_id
を宣言します。HR.EMPLOYEES
のEMPLOYEE_ID
列と同じデータ型を使用します。
SELECT EMPLOYEE_ID INTO emp_id FROM HR.EMPLOYEES
は、SELECT
文を実行し、HR.EMPLOYEES
表のemployee_id
列データに格納されている従業員IDをemp_id
変数にコピーします。
WHERE email = SYS_CONTEXT('USERENV', 'SESSION_USER')
は、WHERE
句を使用して、セッション・ユーザーの電子メール・アカウントと一致するすべての従業員IDを検索します。SYS_CONTEXT
関数は、事前定義のUSERENV
コンテキストを使用してユーザー・セッションID (これはemail
列データと同じです)を取得します。たとえば、Lisa OzerのユーザーIDと電子メール・アドレスはどちらも同じでlozer
です。
DBMS_SESSION.SET_CONTEXT('empno_ctx', 'employee_id', emp_id)
は、DBMS_SESSION.SET_CONTEXT
プロシージャを使用して、アプリケーション・コンテキストを設定します。
'empno_ctx'
: アプリケーション・コンテキストempno_ctx
をコールします。empno_ctx
は一重引用符で囲みます。
'employee_id'
: 属性にemployee_id
という名前を指定して、empno_ctx
アプリケーション・コンテキストの名前と値のペアの属性値を作成します。employee_id
は一重引用符で囲みます。
emp_id
: employee_id
属性の値をemp_id
変数に格納された値に設定します。emp_id
変数は8行目で作成され、従業員IDは10から11行目で取得されます。
要約すると、set_empno_ctx_pkg.set_empno
プロシージャは、「ユーザーのセッションIDを取得して、このユーザーIDをHR.EMPLOYEES
表にリストされたユーザーの従業員IDおよび電子メール・アドレスと照合する」プロシージャです。
EXCEPTION ... WHEN_NO_DATA_FOUND
は、WHEN NO_DATA_FOUND
システム例外を追加して、SELECT
文によって発生した可能性のあるno data foundエラーを捕捉します。この例外がないと、パッケージとログイン・トリガーは正常に機能し、必要に応じてアプリケーション・コンテキストが設定されますが、HR.EMPLOYEES
表にリストされたユーザーを除き、システム管理者以外のユーザーはデータベースにログインできなくなります。他のユーザーは、有効なデータベース・ユーザーであればデータベースにログインできます。アプリケーション・コンテキスト情報が設定された後は、特定のアプリケーションへのユーザー・アクセスを制御する手段として、このセッション情報を使用できます。
ユーザーsysadmin_ctx
で、次のトリガーを作成します。
CREATE TRIGGER set_empno_ctx_trig AFTER LOGON ON DATABASE BEGIN sysadmin_ctx.set_empno_ctx_pkg.set_empno; END; /
ユーザーlozer
でログインします。
CONNECT lozer
Enter password: password
ユーザーlozer
がログインすると、このユーザーの従業員IDがempno_ctx
アプリケーション・コンテキストによって収集されます。これは次のようにして確認できます。
SELECT SYS_CONTEXT('empno_ctx', 'employee_id') emp_id FROM DUAL;
次の出力が表示されます。
EMP_ID -------------------------------------------------------- 168
ユーザーSCOTT
でログインします。
CONNECT SCOTT
Enter password: password
ユーザーSCOTT
はHR.EMPLOYEES
表に従業員としてリストされていないため、empno_ctx
アプリケーション・コンテキストではこのユーザーの従業員IDを収集できません。
SELECT SYS_CONTEXT('empno_ctx', 'employee_id') emp_id FROM DUAL;
次の出力が表示されます。
EMP_ID --------------------------------------------------------
これ以降、アプリケーションではユーザー・セッション情報を使用してユーザーがデータベース内で許可されるアクセス数を判別できます。そのためには、Oracle Virtual Private Databaseを使用できます。詳細は、第7章「Oracle Virtual Private Databaseを使用したデータ・アクセスの制御」を参照してください。
SYS
でログインし、AS SYSDBA
を使用して接続します。
CONNECT SYS/AS SYSDBA
Enter password: password
ユーザーsysadmin_ctx
とlozer
を削除します。
DROP USER sysadmin_ctx CASCADE; DROP USER lozer;
アプリケーション・コンテキストを削除します。
DROP CONTEXT empno_ctx;
このアプリケーション・コンテキストはsysadmin_ctx
が作成しましたが、SYS
スキーマの所有となっていることに注意してください。
他のユーザーがSCOTT
を使用しない場合、このアカウントはロックして期限切れにできます。
ALTER USER SCOTT PASSWORD EXPIRE ACCOUNT LOCK;
データベース・セッション・ベースのアプリケーション・コンテキストを外部で初期化するときは、外部リソースからの属性値の初期化を受け入れてからローカル・ユーザー・セッションに保管する特殊なタイプのネームスペースを指定します。アプリケーション・コンテキストは外部で初期化することによりUGAに格納されて、属性をセッションから別のセッションへ自動伝播できるようになるため、パフォーマンスが向上します。接続ユーザー・データベース・リンクをサポートするのは、OCIベースの外部ソースから初期化されたアプリケーション・コンテキストのみです。
この項の内容は、次のとおりです。
ユーザーからデフォルトを取得することが必要な場合があります。最初、これらのデフォルト値はヒントまたはプリファレンスとして機能し、検証後にトラステッド・コンテキストになります。同様に、クライアントでは、一部のデフォルト値を初期化してから、ログイン・イベント・トリガーまたはアプリケーションを使用して値の検証を行うと便利です。
ジョブ・キューに関しては、ジョブ発行ルーチンで、ジョブの発行時に設定されたコンテキストを記録し、バッチ・ジョブの実行時にそのコンテキストをリストアします。コンテキストの整合性を保持するために、ジョブ・キューは、コンテキストを設定する特定のPL/SQLパッケージを回避できません。一方、外部で初期化されたアプリケーション・コンテキストは、コンテキスト値の初期化をジョブ・キュー・プロセスから受け入れます。
リモート・セッションへのコンテキストの自動伝播によって、セキュリティ上の問題が発生する場合があります。開発者または管理者は、ユーザーのログイン時にログイン・トリガーを使用してコンテキストを再設定することで、特定のPL/SQLプロシージャ以外のリソースからデフォルト値を取得するコンテキストを効果的に処理できます。
外部リソースを介して属性と値の初期化を受け入れるアプリケーション・コンテキストを作成できます。このような外部リソースには、OCIインタフェース、ジョブ・キュー・プロセスまたはデータベース・リンクなどが含まれます。
外部で初期化されたアプリケーション・コンテキストでは、次の機能が提供されます。
リモート・セッションの場合は、外部で初期化されたアプリケーション・コンテキスト・ネームスペースにあるコンテキスト値を自動的に伝播します。
ジョブ・キューの場合は、外部で初期化されたアプリケーション・コンテキスト・ネームスペースにあるコンテキスト値をリストアします。
OCIインタフェースの場合は、外部で初期化されたアプリケーション・コンテキスト・ネームスペースにあるコンテキスト値を初期化するメカニズムを提供します。
Oracle Call Interfaceを使用しているクライアント・プログラムであればこのタイプのネームスペースの初期化は可能ですが、ログイン・イベント・トリガーを使用して値を検証できます。属性の値を解釈して信頼するかどうかはアプリケーションによって異なります。
例6-8に、外部ソースから値を取得するデータベース・セッション・ベースのアプリケーション・コンテキストを作成する方法を示します。
中間層サーバーは、データベース・ユーザーのかわりにアプリケーション・コンテキスト値を初期化できます。コンテキスト属性は、初期化時にリモート・セッションに対して伝播され、ネームスペースが外部で初期化されている場合、リモート・データベースはこれらの値を受け入れます。
たとえば、OCIまたはJDBC/OCI経由の軽量ユーザー・セッションを作成する3層アプリケーションの場合は、USERENVの
PROXY_USER
属性にアクセスできます。この属性を使用すると、ユーザー・セッションが中間層アプリケーションによって作成されたかどうかを判断できます。ユーザーがデータへのアクセスを許可されるのは、そのユーザーがプロキシ化されている接続に対してのみです。ユーザーがデータベースに直接接続している場合、そのユーザーはどのデータにもアクセスできません。
Oracle Virtual Private Database内のUSERENV
ネームスペースからPROXY_USER
属性を使用すると、ユーザーによるデータへのアクセスを特定の中間層アプリケーションを経由した場合のみに制限できます。他の方法では、セキュア・アプリケーション・ロールを作成し、ユーザーは特定のプロキシ経由でのみデータベースにアクセスするというポリシーを規定できます。
関連項目:
|
この項の内容は、次のとおりです。
ユーザーのデータベース・セッション・ベースのアプリケーション・コンテキストは、集中格納場所を使用して格納できます。これによって、アプリケーションでは、初期化中にユーザーの識別情報に基づいてユーザー・コンテキストを設定できます。特に、この機能では、Oracle Label Securityのラベルと権限がサポートされます。アプリケーション・コンテキストをグローバルに初期化すると、多数のユーザーとデータベースのコンテキストを簡単に管理できます。
たとえば、多くの組織では、LDAPベースのディレクトリでユーザー情報を集中管理する必要があります。Oracle Advanced Securityの機能の1つであるエンタープライズ・ユーザー・セキュリティは、Oracle Internet Directoryでのユーザーと認可の集中管理をサポートします。ただし、Oracle Virtual Private Databaseの規定に使用するために、アプリケーションではLightweight Directory Access Protocol(LDAP)から追加の属性(ユーザーの職位、組織、物理的な位置など)を取得することが必要な場合があります。これらのタイプの属性は、アプリケーション・コンテキストをグローバルに初期化することで取得できます。
グローバルに初期化されたアプリケーション・コンテキストは、拡張可能で効率的な標準ディレクトリ・アクセス・プロトコルであるLDAPを使用します。LDAPディレクトリには、このアプリケーションが割り当てられているユーザーのリストが格納されます。Oracle Databaseでは、ディレクトリ・サービス(通常はOracle Internet Directory)を使用して、エンタープライズ・ユーザーを認証および認可します。
注意:
|
orclDBApplicationContext
LDAPオブジェクト(groupOfUniqueNames
のサブクラス)は、アプリケーション・コンテキスト値をディレクトリに格納します。アプリケーション・コンテキスト・オブジェクトの場所は、Human Resourcesの例に基づく図6-1で説明しています。
LDAPオブジェクトinetOrgPerson
により、一部の属性では複数のエントリが存在可能です。ただし、これらのエントリがデータベースにロードされ、SYS_LDAP_USER_DEFAULT
コンテキスト・ネームスペースでアクセスされると、これらのエントリのうち最初のエントリだけが返されます。たとえば、ユーザーに対するinetOrgPerson
オブジェクトでは、telephoneNumber
に複数のエントリが可能です(そのため、ユーザーは複数の電話番号を保存できます)。SYS_LDAP_USER_DEFAULT
コンテキスト・ネームスペースを使用すると、最初の電話番号だけが取得されます。
LDAP側では、アプリケーション・コンテキスト値のリストをデータベースに返すorclDBApplicationContext
値を取得するための内部C関数が必要になります。この例では、HR
はネームスペース、「Title」と「Project」は属性、「Manager」と「Promotion」が値です。
グローバルに初期化されたセキュア・アプリケーションを使用するには、Oracle Advanced Securityの機能の1つであるエンタープライズ・ユーザー・セキュリティを最初に構成する必要があります。次に、ユーザーのアプリケーション・コンテキスト値をデータベースとディレクトリに設定します。
グローバル・ユーザー(エンタープライズ・ユーザー)がデータベースに接続すると、エンタープライズ・ユーザー・セキュリティ機能によって、データベースに接続しているユーザーの識別情報が検証されます。認証後、グローバル・ユーザー・ロールとアプリケーション・コンテキストがディレクトリから取得されます。ユーザーがデータベースにログインするときは、グローバル・ロールと初期アプリケーション・コンテキストがすでに設定されています。
関連項目: エンタープライズ・ユーザー・セキュリティの構成の詳細は、『Oracle Databaseエンタープライズ・ユーザー・セキュリティ管理者ガイド』を参照してください。 |
ユーザーの初期アプリケーション・コンテキスト(部門名や職位など)は、LDAPディレクトリに設定および格納できます。これらの値はユーザーのログイン中に取得されるため、コンテキストは適切に設定されます。さらに、ユーザーに関するすべての情報が取得され、アプリケーション・コンテキスト・ネームスペースSYS_USER_DEFAULTS
に格納されます。次に例を示します。
データベースにアプリケーション・コンテキストを作成します。
CREATE CONTEXT hr USING hrapps.hr_manage_pkg INITIALIZED GLOBALLY;
新規のエントリを作成し、LDAPディレクトリに追加します。
LDAPディレクトリに追加されたエントリの例を次に示します。これらのエントリは、アプリケーション(ネームスペース)HR
に属性値Manager
を持つ属性名Title
を作成し、ユーザー名user1
およびuser2
を割り当てます。次の例では、cn=example
はドメイン名を示します。
dn: cn=OracleDBAppContext,cn=example,cn=OracleDBSecurity,cn=Products,cn=OracleContext,ou=Americas,o=oracle,c=US changetype: add cn: OracleDBAppContext objectclass: top objectclass: orclContainer dn: cn=hr,cn=OracleDBAppContext,cn=example,cn=OracleDBSecurity,cn=Products,cn=OracleContext,ou=Americas,o=oracle,c=US changetype: add cn: hr objectclass: top objectclass: orclContainer dn: cn=Title,cn=hr, cn=OracleDBAppContext,cn=example,cn=OracleDBSecurity,cn=Products,cn=OracleContext,ou=Americas,o=oracle,c=US changetype: add cn: Title objectclass: top objectclass: orclContainer dn: cn=Manager,cn=Title,cn=hr, cn=OracleDBAppContext,cn=example,cn=OracleDBSecurity,cn=Products,cn=OracleContext,ou=Americas,o=oracle,c=US cn: Manager objectclass: top objectclass: groupofuniquenames objectclass: orclDBApplicationContext uniquemember: CN=user1,OU=Americas,O=Oracle,L=Redwoodshores,ST=CA,C=US uniquemember: CN=user2,OU=Americas,O=Oracle,L=Redwoodshores,ST=CA,C=US
このユーザーに関するLDAP inetOrgPerson
オブジェクト・エントリが存在する場合、接続では、複数の属性がinetOrgPerson
から取得され、これらがネームスペースSYS_LDAP_USER_DEFAULT
に割り当てられます。次に、inetOrgPerson
エントリの例を示します。
dn: cn=user1,ou=Americas,O=oracle,L=redwoodshores,ST=CA,C=US changetype: add objectClass: top objectClass: person objectClass: organizationalPerson objectClass: inetOrgPerson cn: user1 sn: One givenName: User initials: UO title: manager, product development uid: uone mail: uone@us.example.com telephoneNumber: +1 650 555 0105 employeeNumber: 00001 employeeType: full time
データベースに接続します。
user1
がドメインexample
に属するデータベースに接続する場合、user1
のTitle
はManager
に設定されます。user1
に関するすべての情報が、LDAPディレクトリから取得されます。値は、次の構文を使用して取得できます。
SYS_CONTEXT('namespace','attribute name')
例:
DECLARE tmpstr1 VARCHAR2(30); tmpstr2 VARCHAR2(30); BEGIN tmpstr1 = SYS_CONTEXT('HR','TITLE); tmpstr2 = SYS_CONTEXT('SYS_LDAP_USER_DEFAULT','telephoneNumber'); DBMS_OUTPUT.PUT_LINE('Title is ' || tmpstr1); DBMS_OUTPUT.PUT_LINE('Telephone Number is ' || tmpstr2); END;
次に、この例の出力を示します。
Title is Manager Telephone Number is +1 650 555 0105
多くのアプリケーションでは、ファイングレイン・アクセス・コントロールに使用される属性をデータベース・メタデータ表に格納します。たとえば、employees
表に、コスト・センター、職責、署名認証などのファイングレイン・アクセス・コントロールに有効な情報を含めることができます。ただし、多くの組織ではユーザー情報をOracle Internet DirectoryなどのLDAPベースのディレクトリに集中化して、ユーザーを管理し、アクセス制御しています。アプリケーション・コンテキスト属性は、Oracle Internet Directoryに格納して1人以上のエンタープライズ・ユーザーに割り当てることができます。また、これらの属性は、エンタープライズ・ユーザーがログインすると自動的に取得され、アプリケーション・コンテキストの初期化にも使用されます。
注意: エンタープライズ・ユーザー・セキュリティはOracle Advanced Securityの機能です。 |
関連項目:
|
この項の内容は、次のとおりです。
グローバル・アプリケーション・コンテキストにより、Oracle RACインスタンスを含むデータベース・セッションでアプリケーション・コンテキスト値にアクセス可能になります。グローバル・アプリケーション・コンテキスト情報はシステム・グローバル領域(SGA: 共有グローバル領域でSGAと称する場合もあります)に格納されるため、3層アーキテクチャの中間層アプリケーションなど、セッションを使用しないアプリケーションに対して使用できます。このようなアプリケーションでは、複数のユーザーがアプリケーションに対して認証され、通常は単一の識別情報としてデータベースに接続するため、セッション・ベースのアプリケーション・コンテキストを使用できません。グローバル・アプリケーション・コンテキストは、ユーザー・セッション単位ではなく一度に初期化されます。したがって、接続は接続プールから再利用されるため、パフォーマンスが向上します。
グローバル・アプリケーション・コンテキストには、3種類の一般的な使用方法があります。
全データベース・ユーザーを対象にしてアプリケーションの値をグローバルに共有する必要がある場合。たとえば、特定の状況に基づいてアプリケーションへのアクセスを禁止することがあります。この場合、アプリケーション・コンテキストが設定する値はユーザーに固有の値ではなく、ユーザーのプライベート・データに基づく値でもありません。アプリケーション・コンテキストは、ある状況を定義して、実行中のアプリケーション・モジュールのバージョンなどを示します。
複数のアプリケーション間を移動する必要があるデータベース・ユーザーがいる場合。この場合、ユーザーの移動先となる第2のアプリケーションには、第1のアプリケーションとは異なるアクセス要件があります。
非データベース・ユーザー(つまり、データベースに認識されていないユーザー)を認証する必要がある場合。データベース・アカウントを持たないこのタイプのユーザーは、通常、Webアプリケーション経由で接続プールを使用して接続します。このようなアプリケーションでは、One Big Application User認証モデルを使用して、複数のユーザーを単一のユーザーとしてデータベースに接続します。このタイプのユーザーを認証するには、そのユーザーのクライアント・セッションIDを使用します。
グローバル・アプリケーション・コンテキストには次のコンポーネントがあります。
グローバル・アプリケーション・コンテキスト。CREATE CONTEXT
SQL文にACCESSED GLOBALLY
句を指定して、グローバル・アプリケーション・コンテキストを作成します。この文は、アプリケーション・コンテキスト名を設定し、その名前に、アプリケーション・コンテキスト・データを設定するように設計されたPL/SQLプロシージャを関連付けます。グローバル・アプリケーション・コンテキストは、そのコンテキストを作成したセキュリティ管理者のデータベース・スキーマに作成および格納されます。
属性を設定するPL/SQLパッケージ。このパッケージには、DBMS_SESSION.SET_CONTEXT
プロシージャを使用してグローバル・アプリケーション・コンテキストを設定するプロシージャが含まれている必要があります。SET_CONTEXT
プロシージャには、この項に記載されている3種類すべての状況に適応するグローバル・アプリケーション・コンテキストを生成できるパラメータが用意されています。このPL/SQLパッケージは、データベース・サーバーで作成、格納および実行します。通常、このパッケージは、それを作成したセキュリティ管理者のスキーマに属します。
クライアント・セッションIDを取得および設定する中間層アプリケーション。非データベース・ユーザー(認証にはクライアント・セッションIDが必要)の場合は、中間層アプリケーションでOracle Call Interface(OCI)コールを使用して、それぞれのセッション・データを取得および設定できます。DBMS_SESSION.SET_IDENTIFIER
プロシージャを使用してクライアント・セッションIDを設定することもできます。クライアント・セッションIDを作成して非データベース・ユーザー名を保存する利点は、DBA_AUDIT_TRAIL
、DBA_FGA_AUDIT_TRAIL
、DBA_COMMON_AUDIT_TRAIL
データ・ディクショナリ・ビューのCLIENT_ID
列を問い合せてこのユーザーのアクティビティを監査できることです。
注意: DBMS_APPLICATION_INFO.SET_CLIENT_INFO 設定で値を上書きできることに注意してください。詳細は、「DBMS_SESSION PL/SQLパッケージを使用したクライアント識別子の設定と消去」を参照してください。 |
Oracle RAC環境では、グローバル・アプリケーション・コンテキストがロードまたは変更された場合は、常に、既存のアクティブ・インスタンスによってのみ、そのことが認識されます。Oracle RAC環境でグローバル・アプリケーション・コンテキスト値を設定すると、コンテキスト値をすべてのOracle RACインスタンスに一貫して伝播することによるパフォーマンスのオーバーヘッドが生じることに注意してください。
1つのOracle RACインスタンスでグローバル・アプリケーション・コンテキストをフラッシュすると(ALTER SYSTEM FLUSH GLOBAL_CONTEXT
SQL文を使用して)、他のすべてのOracle RACインスタンスでも、すべてのグローバル・アプリケーション・コンテキストがフラッシュされます。
グローバル・アプリケーション・コンテキストを作成するには、CREATE CONTEXT
SQL文を使用してグローバル・アプリケーション・コンテキストを作成し、ACCESSED GLOBALLY
句をこのSQL文に含めます。CREATE CONTEXT
文を使用するにはCREATE ANY CONTEXT
システム権限が必要であり、DROP CONTEXT
文でコンテキストを削除するにはDROP ANY CONTEXT
権限が必要になります。ローカル・アプリケーション・コンテキストと同様、グローバル・アプリケーション・コンテキストもセキュリティ管理者のデータベース・スキーマで作成および格納されます。
グローバル・アプリケーション・コンテキストの所有権については、CREATE ANY CONTEXT
権限とDROP ANY CONTEXT
権限を付与されたユーザーがそのグローバル・アプリケーション・コンテキストを作成および削除できた場合でも、SYS
スキーマが所有しています。Oracle Databaseは、作成したスキーマ・アカウントにコンテキストを関連付けますが、このユーザーを削除した場合、コンテキストはそれでもSYS
スキーマの中に存在します。ユーザーSYS
であれば、アプリケーション・コンテキストを削除できます。
例6-9に、グローバル・アプリケーション・コンテキストglobal_hr_ctx
の作成方法を示します。このコンテキストは、hr_ctx_pkg
パッケージを使用して設定されます。
DBMS_SESSION
パッケージの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。
グローバル・アプリケーション・コンテキストに関連付けるPL/SQLパッケージのタスクは、DBMS_SESSION
パッケージを使用したグローバル・アプリケーション・コンテキスト値の設定と消去です。このプロシージャを使用するには、DBMS_SESSION
パッケージに対するEXECUTE
権限が必要です。通常、このパッケージはセキュリティ管理者のデータベース・スキーマに作成および格納されます。DBMS_SESSION
パッケージはSYS
スキーマの所有です。
ローカル・アプリケーション・コンテキストの設定に使用するPL/SQLパッケージとは異なり、ユーザー・セッション・データを取得するSYS_CONTEXT
関数は挿入しません。グローバル・アプリケーション・コンテキストでは、接続しているすべてのユーザーにとって、セッションの所有者(USERENV
コンテキストに記録される)は同じ所有者となるため、この関数を挿入する必要はありません。
プロシージャは、グローバル・アプリケーション・コンテキストのPL/SQLパッケージ内でいつでも実行できます。グローバル・アプリケーション・コンテキストに関連付けられているパッケージ・プロシージャを実行するために、ログイン・トリガーとログオフ・トリガーを作成する必要はありません。一般的に、パッケージ・プロシージャはデータベース・アプリケーション内から実行します。また、非データベース・ユーザーには、中間層アプリケーションを使用してクライアント・セッションIDを取得および設定します。
グローバル・アプリケーション・コンテキストのパッケージ—およびOracle Virtual Private Databaseとファイングレイン監査ポリシーに使用されるパッケージ—の動作を、複数のエディションで次のように制御できます。
PL/SQLパッケージの結果が、すべてのエディションで同じになるようにします。そのためには、エディションが使用可能になっていないユーザーのスキーマで、パッケージを作成します。エディションが使用可能になっていないユーザーを検索するには、DBA_USERS
およびUSER_USERS
データ・ディクショナリ・ビューを問い合せます。SYS
、SYSTEM
、およびDBA_REGISTRY
データ・ディクショナリ・ビューにリストされている他のデフォルトのOracle Database管理者アカウントは、エディションが使用不可であり、使用可能にすることもできません。
PL/SQLパッケージの結果が、パッケージが実行されているエディションの現在の状態に依存するようにします。その結果は、パッケージが適用されるすべてのエディションで異なることがあります。この場合、エディションが使用可能になっているユーザーのスキーマで、パッケージを作成します。スキーマでエディションが使用可能な場合、各エディションに存在するパッケージの実コピーが異なり、各コピーの動作が異なる可能性があります。これは、次のようなシナリオにおいて役立ちます。
パッケージで新しいアプリケーション・コンテキストを使用する必要がある場合。
パッケージで、別のスキームを使用して入力値をエンコードする必要がある場合。
パッケージで、データベースにログインするユーザーに別の検証ルールを適用する必要がある場合。
グローバル・アプリケーション・コンテキストを設定するPL/SQLパッケージでは、1つのgetter関数を使用して、アプリケーション・コンテキストのキー値のペアを読み取る、プリミティブなSYS_CONTEXT
コールをラップします。このgetter関数は、アプリケーション・コンテキストのsetterプロシージャと同じパッケージに配置できます。この方法により、関連する概念を反映するように、アプリケーション・コンテキストのキー値をタグ付けできます。たとえば、setter関数が実際に存在するエディションをタグに使用できます。または、コンテキストを設定するセッションの現行エディションを使用できます、これは、SYS_CONTEXT('USERENV', 'CURRENT_EDITION_NAME')
を使用して検索できます。このタグには、setter関数を適用する任意の概念を使用できます。
関連項目: エディションの詳細は、『Oracle Databaseアドバンスト・アプリケーション開発者ガイド』を参照してください。 |
DBMS_SESSION.SYS_CONTEXT
プロシージャには、namespace
、attribute
およびvalue
パラメータの他に、client_id
パラメータとusername
パラメータも用意されています。これらの設定はグローバル・アプリケーション・コンテキストに使用します。これらの設定の組合せによって、作成可能なグローバル・アプリケーション・コンテキストのタイプがどのように制御されるかについて、表6-2で説明します。
表6-2 DBMS_SESSION.SET_CONTEXTのusernameおよびclient_idパラメータの設定
設定の組合せ | 結果 |
---|---|
|
この組合せでは、すべてのユーザーがアプリケーション・コンテキストにアクセスできます。詳細は、「全データベース・ユーザーを対象としたグローバル・アプリケーション・コンテキスト値の共有」を参照してください。 これらの設定は、データベース・セッション・ベースのアプリケーション・コンテキストにも使用されます。詳細は、「データベース・セッション・ベースのアプリケーション・コンテキストの使用」を参照してください。 |
|
この組合せでは、 |
|
この組合せでは、 |
|
この組合せでは、次の2つの場合が考えられます。
詳細は、「非データベース・ユーザーに対するグローバル・アプリケーション・コンテキストの設定」を参照してください。 |
全データベース・ユーザーを対象としてグローバル・アプリケーションの値を共有するには、SET_CONTEXT
プロシージャのnamespace
、attribute
およびvalue
パラメータを設定します。このシナリオでは、データベース・アカウントを持つすべてのユーザーが、そのデータベース内のデータにアクセスできる可能性があります。
例6-10に、このタイプのグローバル・アプリケーション・コンテキストを設定および消去するパッケージの作成方法を示します。
例6-10 全データベース・ユーザーを対象としてグローバル・アプリケーション値を管理するためのパッケージ
CREATE OR REPLACE PACKAGE hr_ctx_pkg AS PROCEDURE set_hr_ctx(sec_level IN VARCHAR2); PROCEDURE clear_hr_context; END; / CREATE OR REPLACE PACKAGE BODY hr_ctx_pkg AS PROCEDURE set_hr_ctx(sec_level IN VARCHAR2) AS BEGIN DBMS_SESSION.SET_CONTEXT( namespace => 'global_hr_ctx', attribute => 'job_role', value => sec_level); END set_hr_ctx; PROCEDURE clear_hr_context AS BEGIN DBMS_SESSION.CLEAR_CONTEXT('global_hr_ctx', 'job_role'); END clear_context; END; / |
この例の説明は、次のとおりです。
DBMS_SESSION.SET_CONTEXT ... END set_hr_ctx
は、DBMS_SESSION.SET_CONTEXT
プロシージャを使用して、namespace、attributeおよびvalueパラメータの値を設定します。sec_level
値は、データベース・アプリケーションがhr_ctx_pkg.set_hr_ctx
プロシージャを実行する際に指定されます。
username
値とclient_id
値は設定されていません。そのためこれらはNULL
です。これによりすべてのユーザー(データベース・ユーザー)が値にアクセスできることになり、サーバー全体として適切な設定になります。
namespace => 'global_hr_ctx
'は、namespace
をglobal_hr_ctx
に設定します。
attribute => 'job_role'
は、job_role
属性を作成します。
value => sec_level
は、job_role
属性の値をsec_level
に設定します。
PROCEDURE clear_hr_context
は、コンテキスト値を消去するclear_hr_context
プロシージャを作成します。詳細は、「セッションをクローズする際のセッション・データの消去」を参照してください。
通常、このプロシージャは1つのデータベース・アプリケーション内で実行します。たとえば、ログインしているすべてのユーザーが社員であり、「社員」というセキュリティ・レベルを使用する場合は、次の例のようにデータベース・アプリケーション内にコールを埋め込みます。
BEGIN hr_ctx_pkg.set_hr_ctx('clerk'); END; /
プロシージャが正常に完了した場合は、次のようにしてアプリケーション・コンテキストの設定をチェックできます。
SELECT SYS_CONTEXT('global_hr_ctx', 'job_role') job_role FROM DUAL; JOB_ROLE ----------- clerk
このアプリケーション・コンテキストを消去するには、次のプロシージャを入力します。
BEGIN hr_ctx_pkg.clear_hr_context; END; /
実際に消去されていることをチェックするには、次のSELECT
文で値が戻らないことを確認してください。
SELECT SYS_CONTEXT('global_hr_ctx', 'job_role') job_role FROM DUAL; JOB_ROLE -----------
注意: 権限が不十分であることを示すエラー・メッセージが表示された場合は、グローバル・アプリケーション・コンテキストが正しく作成されていることを確認してください。また、DBA_CONTEXT データベース・ビューを問い合せて、設定が正しいこと(作成したスキーマからプロシージャがコールされていることなど)を確認してください。
EXEC DBMS_SESSION.CLEAR_IDENTIFIER; |
複数のアプリケーション間を移動するデータベース・ユーザーに対してグローバル・アプリケーション・コンテキストを設定する場合、特に、移動する複数のアプリケーション間でアクセス要件が異なる場合は、SET_CONTEXT
プロシージャにusername
パラメータを指定します。このパラメータは、すべてのセッションを対象として同じスキーマを使用することを指定します。
次のSET_CONTEXT
パラメータを使用します。
namespace
attribute
value
username
Oracle Databaseは、username
値を一致させることで、他のアプリケーションがアプリケーション・コンテキストを認識できるようにします。これによって、ユーザーは複数のアプリケーション間を移動できます。
client_id
設定を省略すると、その値はデフォルトのNULL
になります。これは、異なるアプリケーションで同じコンテキストを保持するデータベース・ユーザーに対して同じusername
が設定されている場合は、複数のセッションで値を参照できることを意味します。たとえば、各ユーザーを1つのジョブ・ロールに制限し、Oracle Virtual Private Databaseポリシーを使用してユーザー・アクセスを制御するアプリケーション一式を保持できます。
例6-11に、特定のユーザーが複数のアプリケーション間を移動できるように、username
パラメータを設定する方法を示します。この例は、例6-10で作成したパッケージに類似しています。username
パラメータを使用している部分は、太字で記載しています。
例6-11 複数のアプリケーション間を移動するユーザーのグローバル・アプリケーション・コンテキスト値を管理するためのパッケージ
CREATE OR REPLACE PACKAGE hr_ctx_pkg AS PROCEDURE set_hr_ctx(sec_level IN VARCHAR2, user_name IN VARCHAR2); PROCEDURE clear_hr_context; END; / CREATE OR REPLACE PACKAGE BODY hr_ctx_pkg AS PROCEDURE set_hr_ctx(sec_level IN VARCHAR2, user_name IN VARCHAR2) AS BEGIN DBMS_SESSION.SET_CONTEXT( namespace => 'global_hr_ctx', attribute => 'job_role', value => sec_level, username => user_name); END set_hr_ctx; PROCEDURE clear_hr_context AS BEGIN DBMS_SESSION.CLEAR_CONTEXT('global_hr_ctx'); END clear_context; END; /
通常は、次の例のようにコールを埋め込むことで、このプロシージャをデータベース・アプリケーション内で実行します。user_name
パラメータの値(この場合はscott
)には、必ず有効なデータベース・ユーザー名を指定してください。
BEGIN hr_ctx_pkg.set_hr_ctx('clerk', 'scott'); END;
このタイプのグローバル・アプリケーション・コンテキストを安全に管理する方法は、自分のアプリケーション範囲内にコードを埋め込み、セキュア・アプリケーション・ロールをユーザーに付与することです。このコードでは、アプリケーション・コンテキストを設定するトラステッドPL/SQLパッケージに対してEXECUTE
権限を指定する必要があります。つまり、アプリケーション(ユーザーではなく)がユーザーのコンテキストを設定します。
非データベース・ユーザー、つまり、データベースに認識されていないユーザー(Webアプリケーション・ユーザーなど)がクライアント・セッションを開始すると、アプリケーション・サーバーによってクライアント・セッションIDが生成されます。このIDは、アプリケーション・サーバーで設定後にデータベース・サーバー側へ渡す必要があります。そのためには、DBMS_SESSION.SET_IDENTIFIER
プロシージャを使用してクライアント・セッションIDを設定します。コンテキストを設定するには、サーバー側のPL/SQLプロシージャのDBMS_SESSION.SET_CONTEXT
プロシージャにclient_id
パラメータを設定します。これでアプリケーション・コンテキストをグローバルに管理できますが、各クライアントには、各自が割り当てられているアプリケーション・コンテキストのみが表示されます。
ここで、client_id
値は、グローバル・アプリケーション・コンテキストの正しい属性を取得および設定するためのキーです。クライアント識別子は中間層アプリケーションによって制御され、一度設定されると消去されるまでオープン状態のままです。
このタイプのアプリケーション・コンテキストを管理する一般的な方法は、session_id
(client_identifier
)の値をCookieに格納し、次のリクエストで戻されるように、エンド・ユーザーのHTMLページに送信する方法です。また、アプリケーションの参照表にクライアント識別子を保持し、他のユーザーのために使用されたり、エンド・ユーザーのセッション・タイムアウトを実装するために利用されるのを防止する必要があります。
非データベース・ユーザーの場合は、次のSET_CONTEXT
パラメータを構成します。
namespace
attribute
value
username
client_id
例6-12に、このタイプのグローバル・アプリケーション・コンテキストを管理するパッケージの作成方法を示します。
例6-12 非データベース・ユーザーのグローバル・アプリケーション・コンテキスト値を管理するためのパッケージ
CREATE OR REPLACE PACKAGE hr_ctx_pkg AS PROCEDURE set_session_id(session_id_p IN NUMBER); PROCEDURE set_hr_ctx(sec_level_attr IN VARCHAR2, sec_level_val IN VARCHAR2); PROCEDURE clear_hr_session(session_id_p IN NUMBER); PROCEDURE clear_hr_context; END; / CREATE OR REPLACE PACKAGE BODY hr_ctx_pkg AS session_id_global NUMBER; PROCEDURE set_session_id(session_id_p IN NUMBER) AS BEGIN session_id_global := session_id_p; DBMS_SESSION.SET_IDENTIFIER(session_id_p); END set_session_id; PROCEDURE set_hr_ctx(sec_level_attr IN VARCHAR2, sec_level_val IN VARCHAR2) AS BEGIN DBMS_SESSION.SET_CONTEXT( namespace => 'global_hr_ctx', attribute => sec_level_attr, value => sec_level_val, username => USER, client_id => session_id_global); END set_hr_ctx; PROCEDURE clear_hr_session(session_id_p IN NUMBER) AS BEGIN DBMS_SESSION.SET_IDENTIFIER(session_id_p); DBMS_SESSION.CLEAR_IDENTIFIER; END clear_hr_session; PROCEDURE clear_hr_context AS BEGIN DBMS_SESSION.CLEAR_CONTEXT('global_hr_ctx', session_id_global); END clear_hr_context; END; / |
この例の説明は、次のとおりです。
session_id_global NUMBER
は、クライアント・セッションIDを格納するsession_id_global
変数を作成します。このsession_id_global
変数は、グローバル・アプリケーション・コンテキストの属性を作成して値を割り当てるプロシージャも含めて、パッケージ定義全体から参照されます。これは、グローバル・アプリケーション・コンテキストの値が、この特定のセッションIDと常に関連付けられることを意味します。
PROCEDURE set_session_id ... END set_session_id
は、set_session_id
プロシージャを作成します。これは、クライアント・セッションIDをsession_id_global
変数に書き込むプロシージャです。
PROCEDURE set_hr_ctx ... END set_hr_ctx
は、set_hr_ctx
プロシージャを作成します。このプロシージャによりグローバル・アプリケーション・コンテキスト属性が作成されて、これらの属性に値を割り当てることができるようになります。このプロシージャ内では、次のように設定されます。
username = USER
は、username
値を指定します。この例では、Oracle Databaseによって指定される、コンテキスト取得プロセスからセッション所有者を追加するためのUSER
関数を呼び出すことによって設定します。USER
関数によって、アプリケーション・コンテキストを設定するユーザーのみがコンテキストにアクセスできるようになります。USER関数の詳細は、『Oracle Database SQL言語リファレンス』
を参照してください。
NULL
(username
パラメータのデフォルト)を指定すると、すべてのユーザーがコンテキストにアクセスできるようになります。
username
値とclient_id
値の両方を設定した場合は、2つの異なる使用目的が考えられます。軽量ユーザーの場合は、username
パラメータに対して接続プール所有者(APPS_USER
など)を設定し、client_id
に対してクライアント・セッションIDを設定します。ステートレスWebセッションを使用する場合は、ログインしたユーザーと同じデータベース・ユーザーをuser_name
パラメータに設定し、このユーザーが同じクライアント・セッションIDを保持していることを確認します。異なるusernameとclient_id
を設定した場合の動作の例は、「DBMS_SESSION.SET_CONTEXTのusernameおよびclient_idパラメータの設定」
を参照してください。
client_id => session_id_global
は、client_id
値を指定します。この例では、この値をsession_id_global
変数に設定しています。これによって、ここで定義したコンテキスト設定が特定のクライアント・セッションID(つまり、set_session_id
プロシージャを実行する際に設定されるID)に関連付けられます。client_id
パラメータにデフォルトのNULL
を指定すると、すべてのセッションでグローバル・アプリケーション・コンテキストの設定を使用できるようになります。
PROCEDURE clear_hr_session ... END clear_hr_session
は、クライアント・セッション識別子を消去するclear_hr_session
プロシージャを作成します。33行目: 正しいセッションID、つまり10行目で定義されている変数session_id_pに格納されているIDを消去するように設定します。
PROCEDURE clear_hr_context ... END clear_hr_context
は、clear_hr_context
プロシージャを作成します。このプロシージャは、global_hr_ctx
変数によって定義された現行のユーザー・セッションのコンテキスト設定を消去します。詳細は、「セッションをクローズする際のセッション・データの消去」を参照してください。
関連項目:
|
アプリケーション・コンテキストは、すべてがメモリー内に存在します。ユーザーがセッションを終了したときは、client_identifier
値のコンテキストを消去する必要があります。この消去によってメモリーが解放され、残存している値を他のユーザーが誤って使用することがなくなります。
ユーザーのセッション終了時にセッション・データを消去するには、サーバー側のPL/SQLパッケージで、次のいずれかの方法を使用します。
ユーザーがセッションを終了したときにクライアント識別子を消去する方法。DBMS_SESSION.CLEAR_IDENTIFIER
プロシージャを使用します。次に例を示します。
DBMS_SESSION.CLEAR_IDENTIFIER;
コンテキストを消去してもセッションを続行する方法。セッションを続行しながらコンテキストを消去する必要がある場合は、DBMS_SESSION.CLEAR_CONTEXT
またはDBMS_SESSION.CLEAR_ALL_CONTEXT
プロシージャを使用します。次に例を示します。
DBMS_SESSION.CLEAR_CONTEXT('my_ctx', 'my_attribute');
CLEAR_CONTEXT
プロシージャは現行ユーザーのコンテキストを消去します。たとえば、アプリケーション・サーバーを停止する必要がある場合など、すべてのユーザーのコンテキスト値を消去するには、CLEAR_ALL_CONTEXT
プロシージャを使用します。
グローバル・アプリケーション・コンテキスト値は消去されるまで使用可能です。したがって、他のセッションがこれらの値にアクセスしないように、CLEAR_CONTEXT
またはCLEAR_ALL_CONTEXT
を使用してください。コンテキストの値が変更された場合、その内容はただちに反映され、SYS_CONTEXT
ファンクションによって値を取得する後続のコールでは、最新の値が戻されます。
この項の内容は、次のとおりです。
アプリケーション・サーバーはクライアント・セッションIDを生成します。中間層アプリケーションから、クライアント・セッションIDを取得、設定、および消去できます。そのためには、Oracle Call Interface (OCI)コールとDBMS_SESSION
PL/SQLパッケージ・プロシージャのどちらかを中間層アプリケーション・コードに埋め込みます。
アプリケーションによってユーザーが認証され、クライアント識別子が設定されてカレント・セッションに設定されます。PL/SQLパッケージSET_CONTEXT
によって、アプリケーション・コンテキストにclient_identifier
値が設定されます。詳細は、「非データベース・ユーザーに対するグローバル・アプリケーション・コンテキストの設定」を参照してください。
ユーザーがクライアント・セッションを開始すると、アプリケーション・サーバーでクライアント・セッションIDが生成されます。このクライアントIDを取得するには、次のいずれかの文でOCIStmtExecute
コールを使用します。
SELECT SYS_CONTEXT('userenv', 'client_identifier') FROM dual; SELECT CLIENT_IDENTIFIER from V$SESSION; SELECT value FROM session_context WHERE attribute='CLIENT_IDENTIFIER';
例6-13に、OCIStmtExecute
コールを使用してクライアント・セッションIDを取得する方法を示します。
例6-13 OCIStmtExecuteを使用したクライアント・セッションID値の取得
oratext clientid[31]; OCIDefine *defnp1 = (OCIDefine *) 0; OCIStmt *statementhndle; oratext *selcid = (oratext *)"SELECT SYS_CONTEXT('userenv', 'client_identifier') FROM DUAL"; OCIStmtPrepare(statementhndle, errhp, selcid, (ub4) strlen((char *) selcid), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT); OCIDefineByPos(statementhndle, &defnp1, errhp, 1, (dvoid *)clientid, 31, SQLT_STR, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, OCI_DEFAULT); OCIStmtExecute(servhndle, statementhndle, errhp, (ub4) 1, (ub4) 0, (CONST OCISnapshot *) NULL, (OCISnapshot *) NULL, OCI_DEFAULT); printf("CLIENT_IDENTIFIER = %s \n", clientid); |
この例の説明は、次のとおりです。
oratext
、OCIDefine
、OCIStmt
およびoratext
は、クライアント・セッションID、OCIDefine
の参照コール、文ハンドルおよび使用するSELECT
文を格納するための変数を作成します。
OCIStmtPrepare
は、文selcid
を実行する準備を整えます。
OCIDefineByPos
は、クライアント・セッションIDの出力変数clientid
を定義します。
OCIStmtExecute
は、selcid
変数に格納されている文を実行します。
printf
は、取得したクライアント・セッションIDに書式を設定した出力を表示します。
OCIStmtExecute
コールを使用してクライアント・セッションIDを取得した後は、このIDを設定できます。サーバー側のPL/SQLパッケージのDBMS_SESSION.SET_CONTEXT
プロシージャによってこのセッションIDを設定した後、必要に応じてアプリケーション・コンテキスト値を上書きします。
中間層アプリケーション・コードにより、クライアント・セッションID値(前の例でuser_id
に書き込まれた値など)がサーバー側のDBMS_SESSION.SET_CONTEXT
プロシージャで定義されているclient_id
設定と一致することが確認されるようにします。アプリケーション・サーバー側では、次の順序でコールする必要があります。
現行のクライアント・セッションIDを取得します。セッションにはこのIDがすでに設定されていますが、本当に正しい値かどうかを確認するほうが安全です。
現行のクライアント・セッションIDを消去します。消去することで、異なるエンド・ユーザーからのリクエストにサービスを提供するようにアプリケーションを準備します。
新規クライアント・セッションIDまたはエンド・ユーザーに割当て済のクライアント・セッションIDを設定します。この設定によって、セッションは異なるグローバル・アプリケーション・コンテキストの値セットを使用するようになります。
次の方法を使用して、アプリケーション・サーバー側にクライアント・セッションIDを設定できます。
Oracle Call Interface。OCIAttrSet
OCIコールにOCI_ATTR_CLIENT_IDENTIFIER
属性を設定します。この属性は、エンド・ユーザーの識別情報を追跡するためのクライアント識別子をセッション・ハンドルに設定します。
次の例は、OCIAttrSet
でATTR_CLIENT_IDENTIFIER
パラメータを使用する方法を示しています。user_id
設定は、ログインしているユーザーのIDが格納されている変数を参照します。
OCIAttrSet((void *)session_handle, (ub4) OCI_HTYPE_SESSION, (void *) user_id, (ub4)strlen(user_id), OCI_ATTR_CLIENT_IDENTIFIER, error_handle);
DBMS_SESSIONパッケージ。DBMS_SESSION.SET_IDENTIFIER
プロシージャを使用して、グローバル・アプリケーション・コンテキストのクライアント識別子を設定します。たとえば、ログインしているユーザーのIDをuser_id
という変数に格納している場合は、中間層アプリケーションのコードに次の行を入力することになります。
DBMS_SESSION.SET_IDENTIFIER(user_id);
OCIAttrSet
およびDBMS_SESSION.SET_IDENTIFIER
では、次のようにして、この識別子の値をチェックできます。
SELECT SYS_CONTEXT('userenv', 'client_identifier') FROM dual;
この値をチェックする他の方法には、V$SESSION
ビューを問い合せる方法があります。
SELECT CLIENT_IDENTIFIER from V$SESSION;
アプリケーション・コンテキストは、すべてがメモリー内に存在します。ユーザーがセッションを終了したときは、client_identifier
値のコンテキストを消去する必要があります。この消去によってメモリーが解放され、残存している値を他のユーザーが誤って使用することがなくなります。
ユーザーのセッション終了時にセッション・データを消去するには、中間層アプリケーションのコードで、次のいずれかの方法を使用します。
ユーザーがセッションを終了したときにクライアント識別子を消去する方法。DBMS_SESSION.CLEAR_IDENTIFIER
プロシージャを使用します。次に例を示します。
DBMS_SESSION.CLEAR_IDENTIFIER;
コンテキストを消去してもセッションを続行する方法。セッションを続行しながらコンテキストを消去する必要がある場合は、DBMS_SESSION.CLEAR_CONTEXT
またはDBMS_SESSION.CLEAR_ALL_CONTEXT
プロシージャを使用します。次に例を示します。
DBMS_SESSION.CLEAR_CONTEXT(namespace, client_identifier, attribute);
CLEAR_CONTEXT
プロシージャは現行ユーザーのコンテキストを消去します。たとえば、アプリケーション・サーバーを停止する必要がある場合など、すべてのユーザーのコンテキスト値を消去するには、CLEAR_ALL_CONTEXT
プロシージャを使用します。
グローバル・アプリケーション・コンテキスト値は消去されるまで使用可能です。したがって、他のセッションがこれらの値にアクセスしないように、CLEAR_CONTEXT
またはCLEAR_ALL_CONTEXT
を使用してください。
この項の内容は、次のとおりです。
この例は、軽量ユーザーのアプリケーション用にクライアント・セッションIDを使用するグローバル・アプリケーション・コンテキストを作成する方法を示しています。非データベース・ユーザーの接続プールを使用したアクセスを制御する方法を示しています。
この例では、2人のユーザー(アプリケーション・コンテキストとそのパッケージを管理するセキュリティ管理者と、接続プールを所有するユーザー・アカウント)を作成する必要があります。
手順は、次のとおりです。
SYS
でSQL*Plusにログインし、AS SYSDBA
を使用して接続します。
sqlplus sys as sysdba
Enter password: password
sysadmin_ctx
アカウントを作成します。このアカウントは、グローバル・アプリケーション・コンテキストを管理します。
GRANT CREATE SESSION, CREATE ANY CONTEXT, CREATE PROCEDURE TO sysadmin_ctx IDENTIFIED BY password;
GRANT EXECUTE ON DBMS_SESSION TO sysadmin_ctx;
password
を安全なパスワードに置き換えます。詳細は、「パスワードの最低要件」を参照してください。
接続プールの所有者にするデータベース・アカウントapps_user
を作成します。
GRANT CREATE SESSION TO apps_user IDENTIFIED BY password;
password
を安全なパスワードに置き換えます。詳細は、「パスワードの最低要件」を参照してください。
セキュリティ管理者sysadmin_ctx
でログインします。
CONNECT sysadmin_ctx
Enter password: password
cust_ctx
グローバル・アプリケーション・コンテキストを作成します。
CREATE CONTEXT global_cust_ctx USING cust_ctx_pkg ACCESSED GLOBALLY;
cust_ctx
コンテキストが作成され、セキュリティ管理者sysadmin_ctx
のスキーマに関連付けられます。ただし、アプリケーション・コンテキストはSYS
スキーマが所有します。
sysadmin_ctx
として、次のPL/SQLパッケージを作成します。
CREATE OR REPLACE PACKAGE cust_ctx_pkg
AS
PROCEDURE set_session_id(session_id_p IN NUMBER);
PROCEDURE set_cust_ctx(sec_level_attr IN VARCHAR2,
sec_level_val IN VARCHAR2);
PROCEDURE clear_hr_session(session_id_p IN NUMBER);
PROCEDURE clear_hr_context;
END;
/
CREATE OR REPLACE PACKAGE BODY cust_ctx_pkg
AS
session_id_global NUMBER;
PROCEDURE set_session_id(session_id_p IN NUMBER)
AS
BEGIN
session_id_global := session_id_p;
DBMS_SESSION.SET_IDENTIFIER(session_id_p);
END set_session_id;
PROCEDURE set_cust_ctx(sec_level_attr IN VARCHAR2, sec_level_val IN VARCHAR2)
AS
BEGIN
DBMS_SESSION.SET_CONTEXT(
namespace => 'global_cust_ctx',
attribute => sec_level_attr,
value => sec_level_val,
username => USER, -- Retrieves the session user, in this case, apps_user
client_id => session_id_global);
END set_cust_ctx;
PROCEDURE clear_hr_session(session_id_p IN NUMBER)
AS
BEGIN
DBMS_SESSION.SET_IDENTIFIER(session_id_p);
DBMS_SESSION.CLEAR_IDENTIFIER;
END clear_hr_session;
PROCEDURE clear_hr_context
AS
BEGIN
DBMS_SESSION.CLEAR_CONTEXT('global_cust_ctx', session_id_global);
END clear_hr_context;
END;
/
このタイプのパッケージの動作に関する詳細説明は、例6-12を参照してください。
cust_ctx_pkg
パッケージに対するEXECUTE
権限を接続プール所有者apps_user
に付与します。
GRANT EXECUTE ON cust_ctx_pkg TO apps_user;
この時点で、このグローバル・アプリケーション・コンテキストとセッションIDの設定について動作を確認します。
接続プール所有者(ユーザーapps_user
)でSQL*Plusにログインします。
CONNECT apps_user
Enter password: password
接続プール・ユーザーのログイン時に、アプリケーションでは、次のようにクライアント・セッション識別子が設定されます。
BEGIN sysadmin_ctx.cust_ctx_pkg.set_session_id(34256); END; /
クライアント・セッション識別子の値は、次のようにテストしてチェックできます。
接続プール・ユーザーapps_user
でSQL*Plusに接続します。
セッションIDを設定します。
EXEC sysadmin_ctx.cust_ctx_pkg.set_session_id(34256);
セッションIDをチェックします。
SELECT SYS_CONTEXT('userenv', 'client_identifier') FROM dual;
次の出力が表示されます。
SYS_CONTEXT('USERENV','CLIENT_IDENTIFIER') -------------------------------------------------- 34256
ユーザーapps_user
で、グローバル・アプリケーション・コンテキストを次のように設定します。
EXEC sysadmin_ctx.cust_ctx_pkg.set_cust_ctx('Category', 'Gold Partner'); EXEC sysadmin_ctx.cust_ctx_pkg.set_cust_ctx('Benefit Level', 'Highest');
(実際には、手順2でクライアント・セッション識別子を設定した方法と同様に、中間層アプリケーションでグローバル・アプリケーション・コンテキスト値を設定することになります。)
次のSELECT SYS_CONTEXT
文を入力し、設定が正しいことをチェックします。
col category format a13 col benefit_level format a14 SELECT SYS_CONTEXT('global_cust_ctx', 'Category') category, SYS_CONTEXT('global_cust_ctx', 'Benefit Level') benefit_level FROM dual;
次の出力が表示されます。
CATEGORY BENEFIT_LEVEL ------------- -------------- Gold Partner Highest
apps_user
がここで(クライアント・セッション34256内で)実行したのは、非データベース・ユーザーにかわってグローバル・アプリケーション・コンテキストを設定したことです。このコンテキストは、DBMS_SESSION.SET_CONTEXT
のCategory
およびBenefit Level
属性をそれぞれGold Partner
およびHighest
に設定します。このコンテキストは、クライアントID 34256のユーザーapps_user
に対してのみ存在します。非データベース・ユーザーがバックグラウンドでログインした場合、そのユーザーは、実際には接続プール・ユーザーapps_user
でログインしたことになります。このようにして、非データベース・ユーザーは、Gold Partner
およびHighest
のコンテキスト値を使用できます。
データベース・ユーザーであるユーザーが、相応のアプリケーションを使用せずにログインすると仮定します。(たとえば、SQL*Plusを使用してログインします。)このユーザーは接続プール・ユーザー(apps_user
)でログインしていないため、グローバル・アプリケーション・コンテキストは、該当しないユーザーに対して空で表示されます。これは、このコンテキストがapps_user
セッションで作成および設定されていたためです。ユーザーがSELECT SYS_CONTEXT
文を実行すると、次の出力が表示されます。
CATEGORY BENEFIT_LEVEL ------------- --------------
次に、次のテストを試してください。
ユーザーapps_user
として、セッションIDを消去します。
EXEC sysadmin_ctx.cust_ctx_pkg.clear_hr_session(34256);
グローバル・アプリケーション・コンテキストを再度チェックしてください。
SELECT SYS_CONTEXT('global_cust_ctx', 'Category') category, SYS_CONTEXT('global_cust_ctx', 'Benefit Level') benefit_level FROM dual; CATEGORY BENEFIT_LEVEL ------------- --------------
apps_user
によってセッションIDが消去されたため、グローバル・アプリケーション・コンテキストの設定は使用できません。
セッションIDに34256をリストアしてから、コンテキスト値をチェックします。
EXEC sysadmin_ctx.cust_ctx_pkg.set_session_id(34256); SELECT SYS_CONTEXT('global_cust_ctx', 'Category') category, SYS_CONTEXT('global_cust_ctx', 'Benefit Level') benefit_level FROM dual;
次の出力が表示されます。
CATEGORY BENEFIT_LEVEL ------------- -------------- Gold Partner Highest
このように、セッションIDを34256に再設定すると、アプリケーション・コンテキスト値が元に戻ります。要約すると、グローバル・アプリケーション・コンテキストはこのユーザーに対して1度のみ設定しますが、クライアント・セッションIDはユーザーがログインするたびに設定する必要があります。
ここで、グローバル・アプリケーション・コンテキストの値を消去した後、その値をチェックしてください。
EXEC sysadmin_ctx.cust_ctx_pkg.clear_hr_context; SELECT SYS_CONTEXT('global_cust_ctx', 'Category') category, SYS_CONTEXT('global_cust_ctx', 'Benefit Level') benefit_level FROM dual;
次の出力が表示されます。
CATEGORY BENEFIT_LEVEL ------------- --------------
この時点では、クライアント・セッションIDの34256は適切に設定されていますが、アプリケーション・コンテキストの設定はすでに存在していません。これで、以前に設定したアプリケーション・コンテキストの値を使用せずに、このユーザーのセッションを続行できます。
SYS
でログインし、AS SYSDBA
を使用して接続します。
CONNECT sys/as sysdba
Enter password: password
グローバル・アプリケーション・コンテキストを削除します。
DROP CONTEXT global_cust_ctx;
このグローバル・アプリケーション・コンテキストはsysadmin_ctx
が作成しましたが、SYS
スキーマの所有となっていることに注意してください。
2人のサンプル・ユーザーを削除します。
DROP USER sysadmin_ctx CASCADE; DROP USER apps_user;
この項の内容は、次のとおりです。
クライアント識別子12345をクライアントSCOTT
に割り当てたアプリケーション・サーバー
AppSvr
を想定します。AppSvr
アプリケーションは、セッションを作成するためにSCOTT
ユーザーを使用します(つまり、接続プールではありません)。コンテキスト属性に割り当てる値には、ユーザーの職責コードが入っている表でSELECT
文を実行して取得された値など、あらゆる値を使用できます。アプリケーション・コンテキストは移入されると、メモリーに保存されます。そのため、職責コードを必要とするアクションはSYS_CONTEXT
コールによってすぐに職責コードにアクセスできるようになり、表にアクセスするオーバーヘッドもありません。このケースのローカル・コンテキストに対するグローバル・コンテキストの唯一の利点は、SCOTT
がアプリケーションを頻繁に変更して、各アプリケーションで同じコンテキストを使用したような場合です。
次の手順は、グローバル・アプリケーション・コンテキスト・プロセスでSCOTT
のクライアント識別子を設定する方法を示しています。
管理者は次の文を使用して、グローバル・コンテキスト・ネームスペースを作成します。
CREATE OR REPLACE CONTEXT hr_ctx USING hr.init ACCESSED GLOBALLY;
管理者は、hr_ctx
アプリケーション・コンテキスト用にPL/SQLパッケージを作成し、このクライアント識別子には、HR
ネームスペースに値13
があるresponsibility
と呼ばれるアプリケーション・コンテキストがあることを示します。
CREATE OR REPLACE PROCEDURE hr.init AS BEGIN DBMS_SESSION.SET_CONTEXT( namespace => 'hr_ctx', attribute => 'responsibility', value => '13', username => 'SCOTT', client_id => '12345' ); END; /
このPL/SQLプロシージャはHR
データベース・スキーマに格納されていますが、通常は、セキュリティ管理者のスキーマに格納されます。
scott
がAppSvr
を使用してデータベースに接続するたびに、AppSvrアプリケーションによって、次のコマンドが発行され、接続クライアントの識別情報が指定されます。
EXEC DBMS_SESSION.SET_IDENTIFIER('12345');
データベース・セッション内にSYS_CONTEXT('hr_ctx','responsibility')
コールがある場合、データベースによって、クライアント識別子12345
がグローバル・コンテキストと照合され、値13
が戻されます。
このデータベース・セッションの終了時には、AppSvr
によって、次のプロシージャが発行され、クライアント識別子が消去されます。
EXEC DBMS_SESSION.CLEAR_IDENTIFIER( );
アプリケーション・コンテキストによって使用されたメモリーを解放するために、AppSvr
は次のプロシージャを発行します。
DBMS_SESSION.CLEAR_CONTEXT('hr_ctx', '12345');
CLEAR_CONTEXT
が必要なのは、ユーザー・セッションが、明示的なログアウト、タイムアウトまたはAppSvr
アプリケーションで判断される他の状況でアクティブでない場合です。
注意: セッションのクライアント識別子は、消去されるとNULL 値になります。したがって、後続のSYS_CONTEXT コールでは、SET_IDENTIFIER インタフェースを使用してクライアント識別子を再設定しないかぎり、クライアント識別子がNULL のアプリケーション・コンテキストのみが取得されます。 |
次の手順は、軽量ユーザー・アプリケーション用のグローバル・アプリケーション・コンテキスト・プロセスを示しています。軽量ユーザーrobert
は、アプリケーションを介してデータベースに認識されていません。
管理者は次の文を使用して、グローバル・コンテキスト・ネームスペースを作成します。
CREATE CONTEXT hr_ctx USING hr.init ACCESSED GLOBALLY;
HR
アプリケーション・サーバーAppSvr
が起動し、ユーザーappsmgr
としてHR
データベースへの複数の接続を確立します。
ユーザーrobert
がHR
アプリケーション・サーバーにログインします。
AppSvr
がアプリケーションに対してrobert
を認証します。
AppSvr
がこの接続に対して一時的なセッションID12345
を割り当てます(またはアプリケーション・ユーザーIDを使用します)。
セッションIDが、robert
が使用するWebブラウザにCookieの一部として戻されるか、またはAppSvr
によって保持されます。
AppSvr
がhr.init
パッケージをコールして、このクライアントのアプリケーション・コンテキストを初期化すると、次の文が発行されます。
DBMS_SESSION.SET_CONTEXT( 'hr_ctx', 'id', 'robert', 'APPSMGR', 12345 ); DBMS_SESSION.SET_CONTEXT( 'hr_ctx', 'dept', 'sales', 'APPSMGR', 12345 );
AppSvr
がこのセッションにデータベース接続を割り当て、次の文を発行してセッションを初期化します。
DBMS_SESSION.SET_IDENTIFIER( 12345 );
このデータベース・セッション内のすべてのSYS_CONTEXT
コールが、そのクライアントのセッションのみに属するアプリケーション・コンテキストの値を戻します。
たとえば、SYS_CONTEXT('hr','id')
は、robert
という値を戻します。
セッションが終了すると、AppSvr
は次の文を発行してクライアントの識別情報を消去します。
DBMS_SESSION.CLEAR_IDENTIFIER ( );
他のユーザーがデータベースにログインした場合でも、このユーザーはAppSvr
によって設定されたグローバル・コンテキストにはアクセスできません。これは、AppSvr
が、ユーザーAPPSMGR
がログインしたアプリケーションのみがこのグローバル・コンテキストを認識できるように指定したためです。AppSvr
が次の文を使用した場合、クライアントIDが12345
に設定されたあらゆるユーザー・セッションがグローバル・コンテキストを認識できるようになります。
DBMS_SESSION.SET_CONTEXT( 'hr_ctx', 'id', 'robert', NULL , 12345 ); DBMS_SESSION.SET_CONTEXT( 'hr_ctx', 'dept', 'sales', NULL , 12345 );
USERNAME
をNULL
に設定すると、異なるユーザーが同一のコンテキストを共有できます。
注意: グローバル・コンテキストの設定が異なると、セキュリティ上の意味が変わることを認識する必要があります。ユーザー名にNULL が指定されている場合は、すべてのユーザーがそのグローバル・コンテキストにアクセスできます。グローバル・コンテキストのクライアントIDにNULL が指定されている場合、そのグローバル・コンテキストにアクセスできるのは、初期化されていないクライアントIDを持つセッションです。セッションへのアクセスをログインしたユーザーのみに制限するには、NULL のかわりにUSER を指定します。 |
セッションに設定されたクライアント識別子は、次のように問い合せることができます。
SELECT SYS_CONTEXT('USERENV','CLIENT_IDENTIFIER') FROM dual;
次の出力が表示されます。
SYS_CONTEXT('USERENV','CLIENT_IDENTIFIER') ------------------------------------------------- 12345
セキュリティ管理者は、V$SESSION
ビューのCLIENT_IDENTIFIER
およびUSERNAME
を問い合せることで、どのセッションにクライアント識別子が設定されているかを確認できます。次に例を示します。
COL client_identifier format a18 SELECT CLIENT_IDENTIFIER, USERNAME from V$SESSION;
次の出力が表示されます。
CLIENT_IDENTIFIER USERNAME ------------------ -------- 12345 APPSMGR
グローバル・コンテキストの使用領域(バイト単位)をチェックするには、次の問合せを使用します。
SELECT SYS_CONTEXT('USERENV','GLOBAL_CONTEXT_MEMORY') FROM dual;
次の出力が表示されます。
SYS_CONTEXT('USERENV','GLOBAL_CONTEXT_MEMORY') ---------------------------------------------- 584
関連項目: USERENV アプリケーション・コンテキストの事前定義属性であるCLIENT_IDENTIFIER の使用の詳細は、次を参照してください。
|
この項の内容は、次のとおりです。
クライアント・セッション・ベースのアプリケーション・コンテキストでは、Oracle Call Interface(OCI)関数を使用してユーザー・セッション情報を設定および消去します。このユーザー・セッション情報はユーザー・グローバル領域(UGA)に格納されます。
このタイプのアプリケーション・コンテキストの利点は、個々のアプリケーションが特定の非データベース・ユーザー・セッション・データを確認でき、このタスクをデータベースで実行しないことです。もう1つの利点は、アプリケーション・コンテキスト値を設定するコールはサーバーに対する次のコールに含まれるため、パフォーマンスが向上するという点です。
ただし、アプリケーション・コンテキストは、クライアント・セッション・ベースのアプリケーション・コンテキストではセキュリティを維持できなくなる点に注意が必要です。具体的には、アプリケーション・ユーザーがクライアント・アプリケーション・コンテキストを設定できるようになり、データベースでのチェックが一切実行されません。
クライアント・セッション・ベースのアプリケーション・コンテキストは、クライアント・アプリケーションに対してのみ構成します。クライアントの接続先データベース・サーバーには、設定を構成しません。データベース・サーバーのアプリケーション・コンテキスト設定は、クライアント・セッション・ベースのアプリケーション・コンテキストに影響を与えません。
クライアント・セッション・ベースのアプリケーション・コンテキストを構成するには、OCI関数OCIAppCtxSet
を使用します。CLIENTCONTEXT
ネームスペースを使用するクライアント・セッション・ベースのアプリケーション・コンテキストは、OCIクライアントまたはアプリケーション・コンテキストの既存のDBMS_SESSION
パッケージで更新できます。このタイプのコンテキストでは、権限またはパッケージ・セキュリティのチェックは実行されません。
CLIENTCONTEXT
ネームスペースを使用すると、1つのアプリケーション・トランザクションで、ユーザー・コンテキスト情報を変更することと、同じユーザー・セッション・ハンドルを使用して新規ユーザー・リクエストに対応することの両方が可能になります。CLIENTCONTEXT
ネームスペースで属性の個々の値を設定または消去することも、すべての値を消去することもできます。
OCIクライアントではOCIAppCtx
関数を使用して、ネームスペースOCISessionHandle
の可変長データを設定します。OCIネットワークの単一ラウンドトリップ転送は、1回のラウンドトリップで全情報をサーバーに送信します。サーバー側では、ネームスペースに対してSYS_CONTEXT
SQL関数を使用することで、アプリケーション・コンテキスト情報を問い合せることができます。次に例を示します。
JDBCクライアントでは、oracle.jdbc.internal.OracleConnection
関数を使用してこれと同じことを実行します。
CLIENTCONTEXT
ネームスペースはパッケージ・ベースのセキュリティで保護されていないため、すべてのユーザーがこのネームスペース内の情報を設定、消去または収集できます。
関連項目: クライアント・アプリケーション・コンテキストの詳細は、『Oracle Call Interfaceプログラマーズ・ガイド』を参照してください。 |
Oracle Call Interfaceの場合、CLIENTCONTEXT
ネームスペースに値を設定するには、次の構文に従ってコマンドを使用します。
err = OCIAppCtxSet((void *) session_handle,(dvoid *)"CLIENTCONTEXT",(ub4) 13, (dvoid *)attribute_name, length_of_attribute_name (dvoid *)attribute_value, length_of_attribute_value, errhp, OCI_DEFAULT);
次のように値を指定します。
session_handle
: OCISessionHandle
ネームスペースを表します。
attribute_name
: 属性の名前を示します。たとえば、長さ14
のresponsibility
を指定します。
attribute_value
: 属性の値を示します。たとえば、長さ7
のmanager
を指定します。
関連項目: OCIAppCtx関数の詳細は、『Oracle Call Interfaceプログラマーズ・ガイド』 のスケーラブル・プラットフォームの管理に関する項を参照してください。 |
CLIENTCONTEXT
ネームスペースを取得するには、次のいずれかの文でOracle Call Interface OCIStmtExecute
コールを使用します。
SELECT SYS_CONTEXT('CLIENTCONTEXT', 'Attribute-1') FROM dual; SELECT VALUE FROM SESSION_CONTEXT WHERE NAMESPACE='CLIENTCONTEXT' AND ATTRIBUTE='attribute-1';
Attribute-1
の値は、CLIENTCONTEXT
ネームスペースですでに設定されているどんな属性値でも構いません。Oracle Databaseは設定された属性のみを取得します。設定済属性がない場合は、NULL
を返します。通常、属性を設定するにはOCIAppCtxSet
コールを使用します。さらに、DBMS_SESSION.SET_CONTEXT
コールをOCIコードに埋め込んで属性値を設定できます。
例6-13に、OCIStmtExecute
コールを使用してクライアント・セッションIDを取得する方法を示します。
例6-14 クライアント・セッション・ベース・コンテキストのクライアント・セッションID値の取得
oratext clientid[31]; OCIDefine *defnp1 = (OCIDefine *) 0; OCIStmt *statementhndle; oratext *selcid = (oratext *)"SELECT SYS_CONTEXT('CLIENTCONTEXT', attribute) FROM DUAL"; OCIStmtPrepare(statementhndle, errhp, selcid, (ub4) strlen((char *) selcid), (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT); OCIDefineByPos(statementhndle, &defnp1, errhp, 1, (dvoid *)clientid, 31, SQLT_STR, (dvoid *) 0, (ub2 *) 0, (ub2 *) 0, OCI_DEFAULT); OCIStmtExecute(servhndle, statementhndle, errhp, (ub4) 1, (ub4) 0, (CONST OCISnapshot *) NULL, (OCISnapshot *) NULL, OCI_DEFAULT); printf("CLIENT_IDENTIFIER = %s \n", clientid); |
この例の説明は、次のとおりです。
oratext
、OCIDefine
、OCIStmt
およびoratext
は、クライアント・セッションID、OCIDefine
の参照コール、文ハンドルおよび使用するSELECT
文を格納するための変数を作成します。
OCIStmtPrepare
は、文selcid
を実行する準備を整えます。
OCIDefineByPos
は、クライアント・セッションIDの出力変数clientid
を定義します。
OCIStmtExecute
は、selcid
変数に格納されている文を実行します。
printf
は、取得したクライアント・セッションIDに書式を設定した出力を表示します。
Oracle Call Interfaceの場合、CLIENTCONTEXT
の設定を消去するには、次のいずれかのコマンドを使用して、値をNULL
または空の文字列に設定します。
(void) OCIAppCtxSet((void *) session_handle, (dvoid *)"CLIENTCONTEXT", 13, (dvoid *)attribute_name, length_of_attribute_name, (dvoid *)0, 0,errhp OCI_DEFAULT);
または
(void) OCIAppCtxSet((void *) session_handle, (dvoid *)"CLIENTCONTEXT", 13 (dvoid *)attribute_name, length_of_attribute_name, (dvoid *)"", 0,errhp, OCI_DEFAULT);
表6-3に、アプリケーション・コンテキストに関する情報の検索で問合せ可能なデータ・ディクショナリ・ビューをリストします。これらのビューの詳細は、『Oracle Databaseリファレンス』を参照してください。
表6-3 アプリケーション・コンテキストに関する情報を表示するデータ・ディクショナリ・ビュー