アプリケーション・コンテキストはユーザーIDを格納します。このIDを使用して、ユーザーによるデータベースのデータへのアクセスを可能または不可にすることができます。
内容は次のとおりです。
関連項目:
アプリケーション・コンテキストには、ユーザーがデータに対して保持するアクセスを制御する場合に多くのメリットがあります。
内容は次のとおりです。
アプリケーション・コンテキストにより、Oracle Databaseは認証中にデータベース・ユーザーと非データベース・ユーザーに関する情報を入手できます。
アプリケーション・コンテキストとは、Oracle Databaseがメモリーに格納する名前と値のペアです。アプリケーション・コンテキストには、ネームスペースと呼ばれるラベル(たとえば、従業員IDを取得するアプリケーション・コンテキストはempno_ctx
)があります。
コンテキスト内は名前と値のペア(結合配列)です。名前は、値を保持するメモリー内の場所を指定します。アプリケーションはアプリケーション・コンテキストを使用して、ユーザーに関するセッション情報(ユーザーIDまたは他のユーザー固有の情報など)またはクライアントIDにアクセスして、その情報をデータベースに安全に引き渡すことができます。
この情報を使用して、ユーザーがアプリケーションを通じてデータにアクセスできるようにしたりアクセスできないようにできます。アプリケーション・コンテキストを使用して、データベース・ユーザーと非データベース・ユーザーの両方を認証できます。
関連項目:
アプリケーション・コンテキストには2つのコンポーネントがあり、名前と値のペアを構成します。
これらのコンポーネントは次のとおりです。
名前:値に関連付けられている属性セットの名前を示します。たとえば、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)コールを使用してアプリケーション・コンテキストを設定することもできます。
Oracle Databaseではアプリケーション・コンテキスト値が保護データ・キャッシュに格納されます。
このキャッシュはユーザー・グローバル領域(UGA)またはシステム("共有"と呼ばれる場合もある)グローバル領域(SGA)にあります。格納されたアプリケーション・コンテキストの値はセッション中に取得されます。アプリケーション・コンテキストには、このデータ・キャッシュ内の値が格納されるため、アプリケーションのパフォーマンスが向上します。アプリケーション・コンテキストは単独で使用でき、Oracle Virtual Private Databaseポリシーまたはその他のファイングレイン・アクセス制御ポリシーと併用することもできます。アプリケーション・コンテキストと仮想プライベート・データベース・ポリシーの併用については、Oracle Virtual Private Databaseでのアプリケーション・コンテキストの使用を参照してください。
ほとんどのアプリケーションには、アプリケーション・コンテキストに使用可能なある種の情報が含まれています。
たとえば、ORDER_NUMBER
列とCUSTOMER_NUMBER
列を備えた表を使用する受注管理アプリケーションでは、それらの列の値をセキュリティ属性として使用して、顧客によるアクセスをその顧客のIDに基づいて顧客自身の注文のみに制限できます。
アプリケーション・コンテキストは、次の目的で使用されます。
ファイングレイン・アクセス・コントロールの規定(Oracle Virtual Private Databaseポリシーなどで)
複数層環境でのユーザー識別情報の保持
アプリケーションに対する強力なセキュリティの規定(アプリケーション・コンテキストはユーザーではなくトラステッド・プロシージャによって制御されるため)
アプリケーションがファイングレイン監査やPL/SQL条件文またはループで使用する際に必要な属性に対して、保護データ・キャッシュとしての機能を果すことによるパフォーマンスの向上
このキャッシュによって、これらの属性が必要になるたびにデータベースに問い合せるというオーバーヘッドが軽減されます。アプリケーションはセッション・データを表から繰り返し取得する必要がなく、このデータがアプリケーション・コンテキストによってキャッシュに格納されるため、アプリケーションのパフォーマンスが大幅に向上します。
アプリケーションで定義、変更およびアクセスできる名前と値のペアの保持領域として機能
Oracle Databaseでは、アプリケーション・コンテキスト・パッケージの影響を受けるすべてのエディションでアプリケーション・コンテキストが設定されます。
アプリケーション・コンテキストで設定される値は、アプリケーション・コンテキストが影響するすべてのエディションで表示されます。データベース内のすべてのエディション、およびそれが使用可能であるかどうかを検索するには、ALL_EDITIONSデータ・ディクショナリ・ビューを問い合せます。
関連項目:
エディションの詳細は、『Oracle Database開発ガイド』を参照してください。
アプリケーション・コンテキストには、3種類の一般的なカテゴリがあります。
カテゴリは次のとおりです。
データベース・セッション・ベースのアプリケーション・コンテキスト。このタイプのアプリケーション・コンテキストは、データベース・ユーザー・セッション(つまりUGA)のキャッシュに格納されているデータを取得します。データベース・セッション・ベースのアプリケーション・コンテキストは、3つのカテゴリに分類されます。
ローカルで初期化。ユーザーのセッションに対してアプリケーション・コンテキストをローカルで初期化します。
外部で初期化。Oracle Call Interface(OCI)アプリケーション、ジョブ・キュー・プロセスまたは接続ユーザーのデータベース・リンクからアプリケーション・コンテキストを初期化します。
グローバルに初期化。LDAPディレクトリなどの集中格納場所から属性と値を使用します。
このタイプのアプリケーション・コンテキストについては、「データベース・セッション・ベースのアプリケーション・コンテキストの使用」を参照してください。
グローバル・アプリケーション・コンテキスト。このタイプは、システム・グローバル領域(SGA)に格納されるデータを取得するため、3層アーキテクチャの中間層アプリケーションなど、セッションを使用しないアプリケーションに対して使用できます。グローバル・アプリケーション・コンテキストは、セッション・コンテキストをセッション間で、たとえば接続プールの実装を通じて共有する場合に便利です。
このタイプについては、「グローバル・アプリケーション・コンテキスト」を参照してください。
クライアント・セッション・ベースのアプリケーション・コンテキスト。このタイプのアプリケーション・コンテキストは、クライアント側のOracle Call Interface関数を使用してユーザー・セッション・データを設定し、次に、必要なセキュリティ・チェックを実行してユーザー・アクセスを制限します。
このタイプについては、「クライアント・セッション・ベースのアプリケーション・コンテキストの使用」を参照してください。
表9-1に、異なる種類のアプリケーション・コンテキストの要約を示します。
表9-1 アプリケーション・コンテキストの種類
アプリケーション・コンテキストの種類 | UGAへの格納 | SGAへの格納 | 接続ユーザー・データベース・リンクのサポート | ユーザーのアプリケーション・コンテキストの集中保管のサポート | セッションを使用しない複数層アプリケーションのサポート |
---|---|---|---|---|---|
ローカルで初期化されるデータベース・セッション・ベースのアプリケーション・コンテキスト |
あり |
なし |
なし |
なし |
なし |
外部で初期化されるデータベース・セッション・ベースのアプリケーション・コンテキスト |
あり |
なし |
あり |
なし |
なし |
グローバルに初期化されるデータベース・セッション・ベースのアプリケーション・コンテキスト |
あり |
なし |
なし |
あり |
なし |
グローバル・アプリケーション・コンテキスト |
なし |
あり |
なし |
なし |
あり |
クライアント・セッション・ベースのアプリケーション・コンテキスト |
あり |
なし |
あり |
なし |
あり |
データベース・セッション・ベースのアプリケーション・コンテキストを使用すると、ユーザーのセッション・ベースの情報を取得できます。
内容は次のとおりです。
データベース・セッション・ベースのアプリケーション・コンテキストは、データベース・ユーザーのセッション情報を取得します。
このタイプのアプリケーション・コンテキストは、Oracle Database内でPL/SQLプロシージャを使用し、管理の対象となるデータを取得、設定および保護します。
注意:
ユーザーがアプリケーション・ユーザー(つまり、データベースに存在しないユーザー)の場合は、グローバル・アプリケーション・コンテキストの使用を考慮してください。詳細は、グローバル・アプリケーション・コンテキストを参照してください。
データベース・セッション・ベースのアプリケーション・コンテキストは、Oracle Databaseの中で完全管理されます。Oracle Databaseが値を設定し、ユーザーがセッションを終了すると、キャッシュに保管されたアプリケーション・コンテキスト値を自動的に消去します。ユーザー接続が異常終了すると(たとえば停電)、PMONバックグラウンド・プロセスはアプリケーション・コンテキスト・データをクリーン・アップします。アプリケーション・コンテキストをキャッシュから消去する必要はありません。
アプリケーション・コンテキストをOracle Databaseで管理する利点は、アプリケーション・コンテキストを集中管理できる点です。このデータベースにアクセスするアプリケーションは、このアプリケーション・コンテキストを使用して、そのアプリケーションに対するユーザーのアクセスを許可または防止する必要があります。これによって、パフォーマンス向上とセキュリティ強化の両方の利点が得られます。
データベース・セッション・ベースのアプリケーション・コンテキストは、コンテキストのデータを取得および設定して、ユーザーがログインするときにこのコンテキストを設定します。
データベース・セッション・ベースのアプリケーション・コンテキストを作成して使用するには、アプリケーション・コンテキスト、データの取得とコンテキストの設定を実行するプロシージャ、およびユーザーのログイン時にコンテキストを設定する手段の3つのコンポーネントを使用する必要があります。
アプリケーション・コンテキスト。アプリケーション・コンテキストを作成するには、CREATE CONTEXT
SQL文を使用します。この文は、アプリケーション・コンテキスト(ネームスペース)名を設定し、セッション・データを取得してアプリケーション・コンテキストを設定するように設計されたPL/SQLプロシージャに対して、その名前を関連付けます。
データの取得とコンテキストの設定を実行するPL/SQLプロシージャ。このプロシージャで実行する必要があるタスクについては、データベース・セッション・ベースのアプリケーション・コンテキストを管理するパッケージの概要を参照してください。理想的には、必要に応じて他のプロシージャ(タスクのエラー・チェックなど)を挿入できるように、このプロシージャは1つのパッケージ内に作成します。
ユーザーのログイン時にアプリケーション・コンテキストを設定する手段。アプリケーション・コンテキストを使用するアプリケーションにログインするユーザーは、そのアプリケーション・コンテキストを設定するPL/SQLパッケージを実行する必要があります。そのためには、ユーザーがログインするたびに起動するログイン・トリガーを使用するか、この機能をアプリケーションに埋め込むことができます。
ローカルで初期化されるデータベース・セッション・ベースのアプリケーション・コンテキストの作成方法と使用方法は、例: データベース・セッション・ベースのアプリケーション・コンテキストの作成と使用を参照してください。
さらに、セッション・ベースのアプリケーション・コンテキストは、外部で、またはグローバルに初期化できます。いずれの場合も、コンテキスト情報はユーザー・セッションに格納されます。
外部での初期化。この初期化は、OCIインタフェース、ジョブ・キュー・プロセスまたは接続ユーザーのデータベース・リンクから発生します。詳細は、データベース・セッション・ベースのアプリケーション・コンテキストの外部での初期化を参照してください。
グローバルな初期化。この初期化では、LDAPディレクトリなどの集中格納場所から属性と値を使用します。詳細は、データベース・セッション・ベースのアプリケーション・コンテキストのグローバルな初期化を参照してください。
データベース・セッション・ベースのアプリケーション・コンテキストは、ユーザーのセッション情報を格納する名前付きのオブジェクトです。
内容は次のとおりです。
データベース・ユーザー・セッション(UGA)は、ユーザーが作成したネームスペースを使用して、セッション・ベースのアプリケーション・コンテキストを格納します。
各アプリケーション・コンテキストには一意の属性が必要で、1つのネームスペースに属している必要があります。つまり、コンテキスト名は、スキーマ内のみでなくデータベース内でも一意である必要があります。
アプリケーション・コンテキストを作成するには、CREATE ANY CONTEXT
システム権限が必要です。アプリケーション・コンテキストを削除する場合は、DROP CONTEXT
文を使用するためにDROP ANY CONTEXT
権限が必要になります。
アプリケーション・コンテキストの所有権については、CREATE ANY CONTEXT
権限とDROP ANY CONTEXT
権限を付与されたユーザーがそのアプリケーション・コンテキストを作成および削除できた場合でも、SYS
スキーマが所有しています。Oracle Databaseは、作成したスキーマ・アカウントにコンテキストを関連付けますが、このユーザーを削除した場合、コンテキストはそれでもSYS
スキーマの中に存在します。ユーザーSYS
であれば、アプリケーション・コンテキストを削除できます。
既存のアプリケーション・コンテキストの名前は、次の問合せを実行して検索できます。
SELECT OBJECT_NAME FROM DBA_OBJECTS WHERE OBJECT_TYPE ='CONTEXT';
CREATE CONTEXT
SQL文で、データベース・セッション・ベースのアプリケーション・コンテキストを作成できます。
データベース・セッション・ベースのアプリケーション・コンテキストを作成する場合、そのアプリケーション・コンテキストのネームスペースを作成し、ユーザーのセッション情報を保持する名前と値のペアを管理するPL/SQLパッケージとそのネームスペースを関連付ける必要があります。PL/SQLパッケージは、コンテキストの作成時には不要ですが、実行時には存在している必要があります。
データベース・セッション・ベースのアプリケーション・コンテキストを作成するには、CREATE
CONTEXT
SQL文を使用します。
例:
CREATE CONTEXT empno_ctx USING set_empno_ctx_pkg;
この例の説明は、次のとおりです。
empno_ctx
はコンテキスト・ネームスペースです。
set_empno_ctx_pkg
は、そのempno_ctx
ネームスペースの属性を設定するパッケージです(コンテキストの作成時には不要です)。このアプリケーション・コンテキストで使用可能なパッケージの作成方法の例は、手順3: セッション・データを取得してアプリケーション・コンテキストを設定するパッケージの作成を参照してください。
コンテキストを作成するときは、そのコンテキストの名前/値の属性をCREATE CONTEXT
文に設定しないでください。かわりに、これらは、アプリケーション・コンテキストに関連付けるPL/SQLパッケージに設定してください。これは、不正なユーザーによって、適切な属性の検証なしにコンテキスト属性が変更されないようにするためです。このパッケージがアプリケーション・コンテキストと同じコンテナにあることを確認してください。たとえば、アプリケーション・コンテキストをPDBに作成した場合、PL/SQLパッケージはそのPDBに存在する必要があります。
注意:
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_SESSION_ROLES
ネームスペースを使用して、セッションに対して指定したロールが現在有効化されているかどうかを示すこともできます。(SYS_CONTEXT
関数の詳細は、『Oracle Database SQL言語リファレンス』を参照してください。)
CREATE CONTEXTで作成したアプリケーション・コンテキストの名前/値の属性の設定。アプリケーション・コンテキストの名前/値の属性の設定には、DBMS_SESSION.SET_CONTEXT
プロシージャを使用できます。この名前/値の属性には、ユーザーID、IPアドレス、認証モード、アプリケーション名などの情報を格納できます。設定した属性の値は、再設定するまで、またはユーザーがセッションを終了するまでそのまま残ります。次のことに注意してください。
ネームスペース内のパラメータの値がすでに設定されている場合は、SET_CONTEXT
によってこの値が上書きされます。
コンテキストの値が変更された場合、その内容はただちに反映され、SYS_CONTEXT
ファンクションによって値を取得する後続のコールでは、最新の値が戻されます。
ユーザーによる実行。パッケージを作成した後、ログインする場合ユーザーはそのパッケージを実行する必要があります。ユーザーがログインするときパッケージを自動的に実行するためのログイン・トリガーを作成するか、この機能をアプリケーションに埋め込むことができます。アプリケーション・コンテキスト・セッション値はユーザーがセッションを終了すると自動的に消去されるので、セッション・データを手動で削除する必要はありません。
プロシージャはトラステッド・プロシージャであることに注意してください。ユーザーが自分独自のアプリケーション・コンテキスト属性値を設定できないように設計されています。ユーザーはプロシージャを実行しますが、プロシージャがアプリケーション・コンテキスト値を設定します、ユーザーではありません。
データベース・セッション・ベースのアプリケーション・コンテキストの作成方法は、例: データベース・セッション・ベースのアプリケーション・コンテキストの作成と使用を参照してください。
SYS_CONTEXT
ファンクションを使用して、アプリケーション・コンテキストのセッション情報を取得できます。
SYS_CONTEXT
関数には、ログインしたユーザーのカレント・セッションを表すデフォルト・ネームスペースUSERENV
があります。SYS_CONTEXT
を使用すると、ユーザー・ホスト・コンピュータID、ホストIPアドレス、オペレーティング・システム・ユーザー名など、ユーザーに関する様々な種類のセッション・ベースの情報を取得できます。セッション・データを設定
ではなく、取得するにはUSERENVのみを使用することに注意してください。事前定義の属性は、『Oracle Database SQL言語リファレンス』のPL/SQLファンクションの説明でリストされています。
セッション情報を取得するには、ネームスペースとパラメータを設定し、オプションでSYS_CONTEXT
ファンクションの長さの値を設定します。
例:
SYS_CONTEXT ('USERENV','HOST')
PL/SQLファンクションのSYS_CONTEXT
の構文は、次のとおりです。
SYS_CONTEXT ('namespace','parameter'[,length])
次のように値を指定します。
namespace
はアプリケーション・コンテキストの名前です。文字列、または文字列として評価される式を指定できます。SYS_CONTEXT
ファンクションは、現時点でコンテキストのネームスペースに関連付けられているパラメータの値を戻します。ネームスペース内のパラメータの値がすでに設定されている場合は、SET_CONTEXT
によってこの値が上書きされます。
parameter
は、namespace
アプリケーション・コンテキスト内のパラメータです。この値には、文字列または式を指定できます。
length
は戻り型のデフォルト最大サイズ(256バイト)ですが、最大で4000バイトの値を指定して長さを変更できます。NUMBER
データ型の値を入力するか、NUMBER
に明示的に変換できる値を入力します。SYS_CONTEXT
戻り型のデータ型はVARCHAR2
です。この設定はオプションです。
注意:
USERENV
アプリケーション・コンテキスト・ネームスペースは、Oracle Databaseの以前のリリースで提供されていたUSERENV
関数にかわる機能です。
DUAL
表に格納されるSYS_CONTEXT
設定を確認できます。
DUAL
表はデータ・ディクショナリ内の小さい表で、既知の結果を保証するためにOracle Databaseおよびユーザーが記述したプログラムから参照できます。この表には、DUMMY
という列と、値X
が格納されている行があります。
SYS_CONTEXT
設定を確認するには、DUAL
表に対してSELECT
SQL文を発行します。
たとえば、ログインしたホスト・コンピュータを確認する場合、EMP_USERS
の下のSHOBEEN_PC
ホスト・コンピュータにログインしたと想定しています。
SELECT SYS_CONTEXT ('USERENV', 'HOST') FROM DUAL; SYS_CONTEXT(USERENV,HOST) ------------------------- EMP_USERS\SHOBEEEN_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;
この文をパラレル問合せとして実行すると、アプリケーション・コンテキスト情報を含むユーザー・セッションはパラレル実行サーバー(問合せ子プロセス)に伝播されます。
SYS_CONTEXT
ファンクションはデータベース・リンクと一緒に使用できます。
ユーザー・セッション内のSQL文にデータベース・リンクが含まれている場合は、そのデータベース・リンクのホスト・コンピュータでSYS_CONTEXT
関数が実行され、そのホスト・コンピュータにあるコンテキスト情報が取得されます。
リモートのPL/SQLプロシージャ・コールがデータベース・リンクで実行されている場合は、そのプロシージャ内部のすべてのSYS_CONTEXT
関数が、そのリンクの宛先データベースで実行されます。
この場合、データベース・リンクの宛先サイトで使用できるのは、外部で初期化されたアプリケーション・コンテキストのみです。セキュリティ上の理由から、データベース・リンクの開始サイトから宛先サイトに伝播されるのは、外部で初期化されたアプリケーション・コンテキストのみです。
SYS_CONTEXT
でユーザーのセッション・データを取得した後、ユーザー・セッションからアプリケーション・コンテキスト値を設定できます。
コンテキスト値を設定するには、DBMS_SESSION.SET_CONTEXT
プロシージャを使用します。DBMS_SESSION
PL/SQLパッケージに対するEXECUTE
権限を所有している必要があります。
DBMS_SESSION.SET_CONTEXT
の構文は、次のとおりです。
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.SET_CONTEXT
プロシージャの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。
DBMS_SESSION
パッケージの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』 を参照してください。
プロシージャでDBMS_SESSION.SET_CONTEXT文を使用して、アプリケーション・コンテキストの値を設定できます。
例9-1に、empno_ctx
アプリケーション・コンテキストの属性を作成する単純なプロシージャの作成方法を示します。
例9-1 アプリケーション・コンテキストの値を作成する単純なプロシージャ
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
属性の値を指定します。ここでは、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
権限をユーザーに付与する必要はありません。
次のことに注意してください。
ログイン・トリガーによって呼び出されたPL/SQLパッケージ・プロシージャに未処理例外があるか(たとえばセキュリティ・チェックに失敗したために)なんらかの例外を発生すると、ログイン・トリガーは失敗します。ログイン・トリガーに失敗すると、ログインは失敗し、つまりユーザーはデータベースにログインする権限が拒否されます。
ログイン・トリガーがパフォーマンスに影響を与える可能性があります。また、ログイン・トリガーは、最初にサンプル・スキーマ・ユーザーでテストしてから、データベース用に作成してください。これによって、エラーがあった場合は簡単に修正できます。
会計帳簿の変更や職階の変更が頻繁にある場合は注意が必要です。この場合、新しい属性値はすぐに選択できない可能性があるため、カーソルの再解析を強制実行して、新しい属性値を選択する必要があります。
注意:
ユーザー・コンテキスト(EMPNO
、GROUP
、MANAGER
などの情報)は、ユーザーがデータにアクセスする前に設定されるため、ログイン・トリガーを使用できます。
CREATE TRIGGER
文で簡単なログイン・トリガーを作成できます。
例9-2に、PL/SQLプロシージャを実行する単純なログイン・トリガーを示します。
例9-2 単純なログイン・トリガーの作成
CREATE OR REPLACE TRIGGER set_empno_ctx_trig AFTER LOGON ON DATABASE BEGIN sec_mgr.set_empno_ctx_proc; END;
CREATE TRIGGER
文で、本番環境のログイン・トリガーを作成できます。
例9-3は、WHEN OTHERS例外を使用するログイン・トリガーの作成方法を示しています。一方、PL/SQLロジックにエラーが発生して未処理例外を引き起こす場合は、データベースへのすべての接続がブロックされます。
この例は、セキュリティ管理者のスキーマの表にエラーを書き込むWHEN OTHERS
例外を示しています。本番環境では、こちらのほうが、出力をユーザー・セッションへ送信することでセキュリティ攻撃を受けやすくなるよりも安全です。
例9-3 本番環境用のログイン・トリガーの作成
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; /
CREATE TRIGGER
文で、開発環境のログイン・トリガーを作成できます。
例9-4に、同じログイン・トリガーを開発環境用に作成する方法を示します。この場合、エラーをデバッグのためにユーザー・セッションに出力できます。
例9-4 開発環境用のログイン・トリガーの作成
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; /
このチュートリアルでは、データベースにログインを試行するデータベース・ユーザーの従業員IDをチェックするアプリケーション・コンテキストの作成方法を示します。
内容は次のとおりです。
このチュートリアルを開始するには、必要なデータベース・アカウントを作成し、SCOTT
ユーザー・アカウントがアクティブであることを確認する必要があります。
sysadmin_ctx
ユーザーとして、データベース・セッション・ベースのアプリケーション・コンテキストを作成します。
次に、セッション・データを取得してアプリケーション・コンテキストを設定するPL/SQLパッケージを作成する必要があります。
パッケージを作成するには、CREATE OR REPLACE PACKAGE
文を使用します。
例9-5に、セッション・データを取得してアプリケーション・コンテキストを設定するために必要なパッケージの作成方法を示します。パッケージを作成する前に、ユーザーsysadmin_ctx
でログインしていることを確認してください。(最初の行のCREATE OR REPLACE
の前にカーソルを置くことで、このテキストをコピーして貼り付けることができます。)
例9-5 セッション・データを取得してデータベース・セッション・コンテキストを設定するためのパッケージ
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
変数に格納された値に設定します。
要約すると、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
ユーザーとして、set_empno_ctx_pkg.set_empno
パッケージ・プロシージャのログオン・トリガーを作成します。
CREATE TRIGGER set_empno_ctx_trig AFTER LOGON ON DATABASE BEGIN sysadmin_ctx.set_empno_ctx_pkg.set_empno; END; /
すべてのコンポーネントの準備ができると、アプリケーション・コンテキストをテストできます。
これ以降、アプリケーションではユーザー・セッション情報を使用してユーザーがデータベース内で許可されるアクセス数を判別できます。そのためには、Oracle Virtual Private Databaseを使用できます。詳細は、Oracle Virtual Private Databaseを使用したデータ・アクセスの制御を参照してください。
データベース・セッション・ベースのアプリケーション・コンテキストを外部で初期化すると、アプリケーション・コンテキストがユーザー・グローバル領域(UGA)に格納されるため、パフォーマンスが向上します。
内容は次のとおりです。
セッション・ベースのアプリケーション・コンテキストを外部で初期化するには、特別な種類のネームスペースを使用する必要があります。
このネームスペースは外部リソースからの属性値の初期化を受け入れ、ローカル・ユーザー・セッションに格納する必要があります。
アプリケーション・コンテキストは外部で初期化することによりUGAに格納されて、属性をセッションから別のセッションへ自動伝播できるようになるため、パフォーマンスが向上します。接続ユーザー・データベース・リンクをサポートするのは、OCIベースの外部ソースから初期化されたアプリケーション・コンテキストのみです。
Oracle Databaseでは、アプリケーションのユーザーからデフォルト値を取得して使用できます。
ユーザーからデフォルトを取得することが必要な場合があります。最初、これらのデフォルト値はヒントまたはプリファレンスとして機能し、検証後にトラステッド・コンテキストになります。同様に、クライアントでは、一部のデフォルト値を初期化してから、ログイン・イベント・トリガーまたはアプリケーションを使用して値の検証を行うと便利です。
ジョブ・キューに関しては、ジョブ発行ルーチンで、ジョブの発行時に設定されたコンテキストを記録し、バッチ・ジョブの実行時にそのコンテキストをリストアします。コンテキストの整合性を保持するために、ジョブ・キューは、コンテキストを設定する特定のPL/SQLパッケージを回避できません。一方、外部で初期化されたアプリケーション・コンテキストは、コンテキスト値の初期化をジョブ・キュー・プロセスから受け入れます。
リモート・セッションへのコンテキストの自動伝播によって、セキュリティ上の問題が発生する場合があります。開発者または管理者は、ユーザーのログイン時にログイン・トリガーを使用してコンテキストを再設定することで、特定のPL/SQLプロシージャ以外のリソースからデフォルト値を取得するコンテキストを効果的に処理できます。
アプリケーション・コンテキストは、外部リソースを介して属性と値の初期化を受け入れることができます。
このような外部リソースには、Oracle Call Interface(OCI)インタフェース、ジョブ・キュー・プロセスまたはデータベース・リンクなどが含まれます。
外部で初期化されたアプリケーション・コンテキストでは、次の機能が提供されます。
リモート・セッションの場合は、外部で初期化されたアプリケーション・コンテキスト・ネームスペースにあるコンテキスト値を自動的に伝播します。
ジョブ・キューの場合は、外部で初期化されたアプリケーション・コンテキスト・ネームスペースにあるコンテキスト値をリストアします。
OCIインタフェースの場合は、外部で初期化されたアプリケーション・コンテキスト・ネームスペースにあるコンテキスト値を初期化するメカニズムを提供します。
Oracle Call Interfaceを使用しているクライアント・プログラムであればこのタイプのネームスペースの初期化は可能ですが、ログイン・イベント・トリガーを使用して値を検証できます。属性の値を解釈して信頼するかどうかはアプリケーションによって異なります。
CREATE CONTEXT
SQL文で、外部化されたデータベース・セッション・ベースのアプリケーション・コンテキストを作成できます。
例9-6に、外部ソースから値を取得するデータベース・セッション・ベースのアプリケーション・コンテキストを作成する方法を示します。
例9-6 外部化されたデータベース・セッション・ベースのアプリケーション・コンテキストの作成
CREATE CONTEXT ext_ctx USING ext_ctx_pkg INITIALIZED EXTERNALLY;
中間層サーバーは、データベース・ユーザーのかわりにアプリケーション・コンテキスト値を初期化できます。
このプロセスでは、コンテキスト属性が初期化時にリモート・セッションに対して伝播され、ネームスペースが外部で初期化されている場合、リモート・データベースはこれらの値を受け入れます。
たとえば、OCIまたはJDBC/OCI経由の軽量ユーザー・セッションを作成する3層アプリケーションの場合は、USERENVの
PROXY_USER
属性にアクセスできます。この属性を使用すると、ユーザー・セッションが中間層アプリケーションによって作成されたかどうかを判断できます。ユーザーがデータへのアクセスを許可されるのは、そのユーザーがプロキシ化されている接続に対してのみです。ユーザーがデータベースに直接接続している場合、そのユーザーはどのデータにもアクセスできません。
Oracle Virtual Private Database内のUSERENV
ネームスペースからPROXY_USER
属性を使用すると、ユーザーによるデータへのアクセスを特定の中間層アプリケーションを経由した場合のみに制限できます。他の方法では、セキュア・アプリケーション・ロールを作成し、ユーザーは特定のプロキシ経由でのみデータベースにアクセスするというポリシーを規定できます。
関連項目:
プロキシ認証の詳細およびUSERENV
属性CLIENT_IDENTIFIER
を使用して複数層にわたってユーザー識別情報を保持する方法は、複数層環境でのユーザー識別情報の保持を参照してください
セキュア・アプリケーション・ロールを使用して特定のプロキシを経由するようにポリシーを実施する方法は、プロキシ認証に対する中間層サーバーの使用を参照してください
Oracle Call Interfaceプログラマーズ・ガイド
データベース・セッション・ベースのアプリケーション・コンテキストをグローバルに初期化するには、統合された場所にコンテキストを格納します。これによって、LDAPディレクトリ内のこれらのタイプのコンテキストを使用できます。
内容は次のとおりです。
ユーザーのデータベース・セッション・ベースのアプリケーション・コンテキストは、集中格納場所を使用して格納できます。
集中格納場所を使用することでアプリケーションでは、初期化中にユーザーの識別情報に基づいてユーザー・コンテキストを設定できます。
特に、この機能では、Oracle Label Securityのラベルと権限がサポートされます。アプリケーション・コンテキストをグローバルに初期化すると、多数のユーザーとデータベースのコンテキストを簡単に管理できます。
たとえば、多くの組織では、LDAPベースのディレクトリでユーザー情報を集中管理する必要があります。エンタープライズ・ユーザー・セキュリティは、Oracle Internet Directoryでのユーザーと認可の集中管理をサポートします。ただし、Oracle Virtual Private Databaseの規定に使用するために、アプリケーションではLightweight Directory Access Protocol(LDAP)から追加の属性(ユーザーの職位、組織、物理的な位置など)を取得することが必要な場合があります。これらのタイプの属性は、アプリケーション・コンテキストをグローバルに初期化することで取得できます。
グローバルに初期化されたアプリケーション・コンテキストは、拡張可能で効率的な標準ディレクトリ・アクセス・プロトコルであるLDAPを使用します。
LDAPディレクトリには、このアプリケーションが割り当てられているユーザーのリストが格納されます。Oracle Databaseでは、ディレクトリ・サービス(通常はOracle Internet Directory)を使用して、エンタープライズ・ユーザーを認証および認可します。
注意:
Microsoft Active DirectoryやSun MicrosystemsのSunONEなどのサード・パーティ製ディレクトリもディレクトリ・サービスとして使用できます。
orclDBApplicationContext
LDAPオブジェクト(groupOfUniqueNames
のサブクラス)は、アプリケーション・コンテキスト値をディレクトリに格納します。アプリケーション・コンテキスト・オブジェクトの場所は、Human Resourcesの例に基づく図9-1で説明しています。
LDAPオブジェクトinetOrgPersonにより、一部の属性では複数のエントリが存在可能です。ただし、これらのエントリがデータベースにロードされ、SYS_LDAP_USER_DEFAULTコンテキスト・ネームスペースでアクセスされると、これらのエントリのうち最初のエントリだけが返されます。たとえば、ユーザーに対するinetOrgPersonオブジェクトでは、telephoneNumberに複数のエントリが可能です(そのため、ユーザーは複数の電話番号を保存できます)。SYS_LDAP_USER_DEFAULTコンテキスト・ネームスペースを使用すると、最初の電話番号だけが取得されます。
LDAP側では、アプリケーション・コンテキスト値のリストをデータベースに返すorclDBApplicationContext
値を取得するための内部C関数が必要になります。この例では、HR
はネームスペース、「Title」と「Project」は属性、「Manager」と「Promotion」が値です。
グローバルに初期化されたセキュア・アプリケーションを使用するには、エンタープライズ・ユーザー・セキュリティを最初に構成する必要があります。
次に、データベースとディレクトリのユーザーに対してアプリケーション・コンテキスト値を構成します。
グローバル・ユーザー(エンタープライズ・ユーザー)がデータベースに接続すると、エンタープライズ・ユーザー・セキュリティ機能によって、データベースに接続しているユーザーの識別情報が検証されます。認証後、グローバル・ユーザー・ロールとアプリケーション・コンテキストがディレクトリから取得されます。ユーザーがデータベースにログインするときは、グローバル・ロールと初期アプリケーション・コンテキストがすでに設定されています。
関連項目:
エンタープライズ・ユーザー・セキュリティの構成の詳細は、『Oracle Databaseエンタープライズ・ユーザー・セキュリティ管理者ガイド』を参照してください。
多くのアプリケーションでは、ファイングレイン・アクセス・コントロールに使用される属性をデータベース・メタデータ表に格納します。
たとえば、employees
表に、コスト・センター、職責、署名認証などのファイングレイン・アクセス・コントロールに有効な情報を含めることができます。ただし、多くの組織ではユーザー情報をOracle Internet DirectoryなどのLDAPベースのディレクトリに集中化して、ユーザーを管理し、アクセス制御しています。アプリケーション・コンテキスト属性は、Oracle Internet Directoryに格納して1人以上のエンタープライズ・ユーザーに割り当てることができます。また、これらの属性は、エンタープライズ・ユーザーがログインすると自動的に取得され、アプリケーション・コンテキストの初期化にも使用されます。
関連項目:
OCIインタフェース、ジョブ・キュー・プロセスまたはデータベース・リンクなど、外部リソースを介したローカル・アプリケーション・コンテキストの初期化に関する詳細は、データベース・セッション・ベースのアプリケーション・コンテキストの外部での初期化を参照してください
Oracle Internet Directoryなどの集中化されたリソースを介したローカル・アプリケーション・コンテキストの初期化に関する詳細は、データベース・セッション・ベースのアプリケーション・コンテキストのグローバルな初期化を参照してください
エンタープライズ・ユーザーの詳細は、『Oracle Databaseエンタープライズ・ユーザー・セキュリティ管理者ガイド』を参照してください。
グローバル・アプリケーション・コンテキストを使用して、Oracle Real Application Clusters環境などのデータベース・セッション間でアプリケーション値にアクセスできます。
内容は次のとおりです。
グローバル・アプリケーション・コンテキストを使用すると、アプリケーション・コンテキスト値を複数のデータベース・セッション(Oracle RACインスタンスを含む)にわたってアクセス可能にできます。
グローバル・アプリケーション・コンテキスト情報はシステム・グローバル領域(SGA: 共有グローバル領域でSGAと称する場合もあります)に格納されるため、3層アーキテクチャの中間層アプリケーションなど、セッションを使用しないアプリケーションに対して使用できます。
このようなアプリケーションでは、複数のユーザーがアプリケーションに対して認証され、通常は単一の識別情報としてデータベースに接続するため、セッション・ベースのアプリケーション・コンテキストを使用できません。グローバル・アプリケーション・コンテキストは、ユーザー・セッション単位ではなく一度に初期化されます。したがって、接続は接続プールから再利用されるため、パフォーマンスが向上します。
グローバル・アプリケーション・コンテキスト値は、ALTER SYSTEM FLUSH GLOBAL_CONTEXT
SQL文を実行して消去できます。
グローバル・アプリケーション・コンテキストには、3種類の一般的な使用方法があります。
使用方法は次のとおりです。
全データベース・ユーザーを対象にしてアプリケーションの値をグローバルに共有する必要がある場合。たとえば、特定の状況に基づいてアプリケーションへのアクセスを禁止することがあります。この場合、アプリケーション・コンテキストが設定する値はユーザーに固有の値ではなく、ユーザーのプライベート・データに基づく値でもありません。アプリケーション・コンテキストは、ある状況を定義して、実行中のアプリケーション・モジュールのバージョンなどを示します。
複数のアプリケーション間を移動する必要があるデータベース・ユーザーがいる場合。この場合、ユーザーの移動先となる第2のアプリケーションには、第1のアプリケーションとは異なるアクセス要件があります。
非データベース・ユーザー(つまり、データベースに認識されていないユーザー)を認証する必要がある場合。データベース・アカウントを持たないこのタイプのユーザーは、通常、Webアプリケーション経由で接続プールを使用して接続します。このようなアプリケーションでは、One Big Application User認証モデルを使用して、複数のユーザーを単一のユーザーとしてデータベースに接続します。このタイプのユーザーを認証するには、そのユーザーのクライアント・セッションIDを使用します。
グローバル・アプリケーション・コンテキストはパッケージを使用して属性を管理し、中間層アプリケーションを使用してクライアント・セッション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文を使用できます。コンテキストの場所は、SYS
スキーマ内になります。
内容は次のとおりです。
グローバル・アプリケーション・コンテキストを所有できるのはSYS
スキーマのみです。
グローバル・アプリケーション・コンテキストの所有権については、CREATE ANY CONTEXT
権限とDROP ANY CONTEXT
権限を付与されたユーザーがそのグローバル・アプリケーション・コンテキストを作成および削除できた場合でも、SYS
スキーマが所有しています。
Oracle Databaseは、作成したスキーマ・アカウントにコンテキストを関連付けますが、このユーザーを削除した場合、コンテキストはそれでもSYS
スキーマの中に存在します。ユーザーSYS
であれば、アプリケーション・コンテキストを削除できます。
ローカル・アプリケーション・コンテキストと同様、グローバル・アプリケーション・コンテキストもセキュリティ管理者のデータベース・スキーマで作成および格納されます。
グローバル・アプリケーション・コンテキストを作成するには、CREATE ANY CONTEXT
システム権限が必要であり、DROP CONTEXT
文でコンテキストを削除するにはDROP ANY CONTEXT
権限が必要になります。
グローバル・アプリケーション・コンテキストを作成するには、CREATE CONTEXT
SQL文を使用してグローバル・アプリケーション・コンテキストを作成し、ACCESSED GLOBALLY
句をこのSQL文に含めます。
次に例を示します。
CREATE OR REPLACE CONTEXT global_hr_ctx USING hr_ctx_pkg ACCESSED GLOBALLY;
DBMS_SESSION
PL/SQLパッケージを使用して、グローバル・アプリケーション・コンテキストを管理できます。
内容は次のとおりです。
関連項目:
DBMS_SESSION
パッケージの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。
グローバル・アプリケーション・コンテキストに関連付けるパッケージは、DBMS_SESSION
パッケージを使用してグローバル・アプリケーション・コンテキスト値の設定と消去を行います。
このプロシージャを使用するには、DBMS_SESSION
パッケージに対するEXECUTE
権限が必要です。通常、このパッケージはセキュリティ管理者のデータベース・スキーマに作成および格納されます。DBMS_SESSION
パッケージはSYS
スキーマの所有です。
ローカル・アプリケーション・コンテキストの設定に使用するPL/SQLパッケージとは異なり、ユーザー・セッション・データを取得するSYS_CONTEXT
関数は挿入しません。グローバル・アプリケーション・コンテキストでは、接続しているすべてのユーザーにとって、セッションの所有者(USERENV
コンテキストに記録される)は同じ所有者となるため、この関数を挿入する必要はありません。
プロシージャは、グローバル・アプリケーション・コンテキストのPL/SQLパッケージ内でいつでも実行できます。グローバル・アプリケーション・コンテキストに関連付けられているパッケージ・プロシージャを実行するために、ログイン・トリガーとログオフ・トリガーを作成する必要はありません。一般的に、パッケージ・プロシージャはデータベース・アプリケーション内から実行します。また、非データベース・ユーザーには、中間層アプリケーションを使用してクライアント・セッションIDを取得および設定します。
関連項目:
DBMS_SESSION
パッケージの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。
グローバル・アプリケーション・コンテキストのパッケージ、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
プロシージャは、グローバル・アプリケーション・コンテキストに使用するclient_id
およびusername
パラメータを提供します。
これらの設定の組合せによって、作成可能なグローバル・アプリケーション・コンテキストのタイプがどのように制御されるかについて、表9-2で説明します。
表9-2 DBMS_SESSION.SET_CONTEXTのusernameおよびclient_idパラメータの設定
設定の組合せ | 結果 |
---|---|
|
この組合せでは、すべてのユーザーがアプリケーション・コンテキストにアクセスできます。詳細は、「全データベース・ユーザーを対象としたグローバル・アプリケーション・コンテキスト値の共有」を参照してください。 これらの設定は、データベース・セッション・ベースのアプリケーション・コンテキストにも使用されます。詳細は、「データベース・セッション・ベースのアプリケーション・コンテキストの使用」を参照してください。 |
|
この組合せでは、 |
|
この組合せでは、 |
|
この組合せでは、次の2つの場合が考えられます。
詳細は、「非データベース・ユーザーのグローバル・アプリケーション・コンテキスト」を参照してください。 |
全データベース・ユーザーを対象としてグローバル・アプリケーション値を共有し、データベース内のデータにアクセスできます。
全データベース・ユーザーを対象としてグローバル・アプリケーションの値を共有するには、SET_CONTEXT
プロシージャのnamespace
、attribute
およびvalue
パラメータを設定します。
CREATE PACKAGE
文で、全データベース・ユーザーを対象としてグローバル・アプリケーション値を管理できます。
例9-7に、全データベース・ユーザーを対象としてグローバル・アプリケーション・コンテキストを設定および消去するパッケージの作成方法を示します。
例9-7 全データベース・ユーザーを対象としてグローバル・アプリケーション値を管理するためのパッケージ
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'
は、SET_CONTEXT
プロシージャで、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 -----------
権限が不十分であることを示すエラー・メッセージがOracle Databaseで返された場合は、グローバル・アプリケーション・コンテキストが正しく作成されていることを確認してください。また、DBA_CONTEXT
データベース・ビューを問い合せて、設定が正しいこと(作成したスキーマからプロシージャがコールされていることなど)を確認してください。
NULL
が戻る場合は、誤ってクライアント識別子を設定した可能性があります。クライアント識別子を消去するには、次のプロシージャを実行します。
EXEC DBMS_SESSION.CLEAR_IDENTIFIER;
アプリケーションに異なるアクセス要件がある場合でも、アプリケーション間を移動するデータベース・ユーザーはグローバル・アプリケーション・コンテキストを使用できます。
これを行うには、DBMS_SESSION.SET_CONTEXT
プロシージャにusername
パラメータを含める必要があります。
このパラメータは、すべてのセッションを対象として同じスキーマを使用することを指定します。
次のDBMS_SESSION.SET_CONTEXT
パラメータを使用できます。
namespace
attribute
value
username
Oracle Databaseは、username
値を一致させることで、他のアプリケーションがアプリケーション・コンテキストを認識できるようにします。これによって、ユーザーは複数のアプリケーション間を移動できます。
client_id
設定を省略すると、その値はデフォルトのNULL
になります。これは、異なるアプリケーションで同じコンテキストを保持するデータベース・ユーザーに対して同じusername
が設定されている場合は、複数のセッションで値を参照できることを意味します。たとえば、各ユーザーを1つのジョブ・ロールに制限し、Oracle Virtual Private Databaseポリシーを使用してユーザー・アクセスを制御するアプリケーション一式を保持できます。
例9-8に、特定のユーザーが複数のアプリケーション間を移動できるように、username
パラメータを設定する方法を示します。username
パラメータを使用している部分は、太字で記載しています。
例9-8 複数のアプリケーション間を移動するグローバル・アプリケーション・コンテキスト値のパッケージ
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
権限を指定する必要があります。つまり、アプリケーション(ユーザーではなく)がユーザーのコンテキストを設定します。
非データベース・ユーザーがクライアント・セッションを開始すると、アプリケーション・サーバーでクライアント・セッションIDが生成されます。
非データベース・ユーザーとはデータベースにとって未知のユーザーのことで、Webアプリケーション・ユーザーなどがこれに当たります。
この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
関連項目:
クライアント・セッションIDを使用するグローバル・アプリケーション・コンテキストがどのように機能するかを示す例は、「例: クライアント・セッションIDを使用するグローバル・アプリケーション・コンテキストの作成」を参照してください。
中間層システムでのクライアント識別子の動作の詳細は、「データベースに認識されないアプリケーション・ユーザーの識別でのクライアント識別子の使用」を参照してください。
CREATE PACKAGE
文で、非データベース・ユーザーのグローバル・アプリケーション・コンテキスト値を管理できます。
例9-9に、このタイプのグローバル・アプリケーション・コンテキストを管理するパッケージの作成方法を示します。
例9-9 非データベース・ユーザーのグローバル・アプリケーション・コンテキスト値を管理するためのパッケージ
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
プロシージャを作成します。AS
句は、正しいセッションID、つまりCREATE OR REPLACE PACKAGE BODY
hr_ctx_pkg
プロシージャで定義されている変数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を取得してから設定する必要があります。クライアント・セッションIDは、不要になった場合、消去する必要があります。
内容は次のとおりです。
アプリケーション・サーバーはクライアント・セッションIDを生成します。
中間層アプリケーションから、クライアント・セッションIDを取得、設定、および消去できます。そのために、Oracle Call Interface (OCI)コールとDBMS_SESSION
PL/SQLパッケージ・プロシージャのどちらかを中間層アプリケーション・コードに埋め込むことができます。
アプリケーションによってユーザーが認証され、クライアント識別子が設定されてカレント・セッションに設定されます。PL/SQLパッケージSET_CONTEXT
によって、アプリケーション・コンテキストにclient_identifier
値が設定されます。詳細は、「非データベース・ユーザーのグローバル・アプリケーション・コンテキスト」を参照してください。
ユーザーがクライアント・セッションを開始すると、アプリケーション・サーバーでクライアント・セッションIDが生成されます。
この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';
次に、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に書式を設定した出力を表示します。
次に、中間層アプリケーションを使用してクライアント・セッション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を設定します。この設定によって、セッションは異なるグローバル・アプリケーション・コンテキストの値セットを使用するようになります。
Oracle Call InterfaceまたはDBMS_SESSION
PL/SQLパッケージで、中間層アプリケーションを使用してクライアント・セッション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);
注意:
アプリケーションでCLIENT_IDENTIFIER
として使用するセッションIDを生成する場合、そのセッションIDは適度にランダムで、ネットワーク上では暗号化によって保護されている必要があります。セッションIDがランダムでない場合は、不正なユーザーがセッションIDを推測し、他のユーザーのデータにアクセスする可能性があります。セッションIDがネットワーク上で暗号化されていない場合は、不正なユーザーがセッションIDを取得して、接続にアクセスする可能性があります。
ネットワーク・データの暗号化を使用して、セッションIDを暗号化できます。詳細は、「Oracle Databaseのネットワーク暗号化およびデータ整合性の構成」を参照してください。ネットワークを介したデータの暗号化については、『Oracle Database 2日でセキュリティ・ガイド』を参照してください。
アプリケーション・コンテキストは、すべてがメモリー内に存在します。
ユーザーがセッションを終了したときは、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を使用するグローバル・アプリケーション・コンテキストの作成を示しています。
内容は次のとおりです。
この例は、軽量ユーザーのアプリケーション用にクライアント・セッションIDを使用するグローバル・アプリケーション・コンテキストを作成する方法を示しています。
非データベース・ユーザーの接続プールを使用したアクセスを制御する方法を示しています。マルチテナント環境を使用している場合、このチュートリアルは現在のPDBのみに適用されます。
この時点で、このグローバル・アプリケーション・コンテキストとセッションIDの設定について動作を確認します。
接続プール所有者(ユーザーapps_user
)でSQL*Plusにログインします。
CONNECT apps_user -- Or, CONNECT apps_user@hrpdb Enter password: password
接続プール・ユーザーのログイン時に、アプリケーションでは、次のようにクライアント・セッション識別子が設定されます。
BEGIN sysadmin_ctx.cust_ctx_pkg.set_session_id(34256); END; /
クライアント・セッション識別子の値をテストします。
セッション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
次に示すように、グローバル・アプリケーション・コンテキストを設定します。
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 ------------- --------------
必要なアクセスの種類に応じて、データベース・ユーザー・アカウントを使用してユーザー・セッションを作成する簡単なグローバル・アプリケーション・コンテキストを構成できます。あるいは、軽量ユーザーに対してグローバル・アプリケーション・コンテキストを構成できます。
内容は次のとおりです。
簡単なグローバル・アプリケーション・コンテキストのプロセスでは、アプリケーションは、データベース・ユーザーを使用してユーザー・セッションを作成します。
単純なグローバル・アプリケーション・コンテキスト・プロセスのコンテキスト属性の値は、SELECT
文から取得できます。
クライアント識別子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 Database SQL言語リファレンス
Oracle Call Interfaceプログラマーズ・ガイド
クライアント・セッション・ベースのアプリケーション・コンテキストは、ユーザー・グローバル領域(UGA)に格納されます。
内容は次のとおりです。
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(OCI)を使用して、CLIENTCONTEXT
ネームスペースを設定できます。
CLIENTCONTEXT
ネームスペースに値を設定するには、次の構文でOCIAppCTXSet
コマンドを使用します。
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プログラマーズ・ガイドを参照してくださいOracle Call Interfaceを使用して、CLIEINTCONTEXT
ネームスペースを取得できます。
CLIENTCONTEXT
ネームスペースを取得するには、次のいずれかの文で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コードに埋め込んで属性値を設定できます。
OCI OCIStmtExecute
コールで、クライアント・セッション・ベース・コンテキストのクライアント・セッションID値を取得できます。
例9-10に、OCIStmtExecute
コールを使用してクライアント・セッションIDを取得する方法を示します。
例9-10 クライアント・セッション・ベース・コンテキストのクライアント・セッション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
ネームスペースを消去できます。
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);
Oracle Databaseには、アプリケーション・コンテキストに関する情報を提供するデータ・ディクショナリ・ビューが用意されています。
表9-3に、これらのデータ・ディクショナリ・ビューを示します。
表9-3 アプリケーション・コンテキストに関する情報を表示するデータ・ディクショナリ・ビュー
ビュー | 説明 |
---|---|
|
属性および値が |
|
現行ユーザーがアクセス可能なシノニム、表およびビューに定義されている駆動コンテキストが表示されます。(駆動コンテキストは、仮想プライベート・データベース・ポリシーで使用されるコンテキストです。) |
|
データベース内のすべてのコンテキスト・ネームスペース情報が表示されます。このビューの列は、 |
|
既存のアプリケーション・コンテキストの名前が表示されます。次のように、 SELECT OBJECT_NAME FROM DBA_OBJECTS WHERE OBJECT_TYPE ='CONTEXT'; |
|
|
|
カレント・セッションに設定されているコンテキスト属性とその値が表示されます。 |
|
現行ユーザーが所有するシノニム、表およびビューに定義されている駆動コンテキストが表示されます。このビューの列は、 |
|
カレントPDBセッションに設定されている属性がリストされます。このビューに対する |
|
各カレントPDBセッションに関する詳細情報がリストされます。このビューに対する |
ヒント:
アプリケーション・コンテキストを使用するアプリケーションの実行時にエラーが発生した場合は、これらのビューに加え、データベース・トレース・ファイルも確認してください。USER_DUMP_DEST
初期化パラメータは、トレース・ファイルのディレクトリの場所を示します。このパラメータの値は、SQL*PlusでSHOW PARAMETER USER_DUMP_DEST
を発行して確認できます。
関連項目:
トレース・ファイルの詳細は、Oracle Database SQLチューニング・ガイドを参照してください
これらのビューの詳細は、Oracle Databaseリファレンスを参照してください。