10 アプリケーション・コンテキストを使用したユーザー情報の取得
アプリケーション・コンテキストにはユーザーIDが格納されており、これに基づいてデータベースのデータにユーザーがアクセスできるかを否かを決定できます。
- アプリケーション・コンテキストについて
アプリケーション・コンテキストには、ユーザーがデータに対して保持するアクセスを制御する場合に多くのメリットがあります。 - アプリケーション・コンテキストの種類
アプリケーション・コンテキストには、3種類の一般的なカテゴリがあります。 - データベース・セッション・ベースのアプリケーション・コンテキストの使用
データベース・セッション・ベースのアプリケーション・コンテキストを使用すると、ユーザーのセッション・ベースの情報を取得できます。 - グローバル・アプリケーション・コンテキスト
グローバル・アプリケーション・コンテキストを使用して、Oracle Real Application Clusters環境などのデータベース・セッション間でアプリケーション値にアクセスできます。 - クライアント・セッション・ベースのアプリケーション・コンテキストの使用
クライアント・セッション・ベースのアプリケーション・コンテキストは、ユーザー・グローバル領域(UGA)に格納されます。 - アプリケーション・コンテキストのデータ・ディクショナリ・ビュー
Oracle Databaseには、アプリケーション・コンテキストに関する情報を提供するデータ・ディクショナリ・ビューが用意されています。
親トピック: データへのアクセス制御
10.1 アプリケーション・コンテキストについて
アプリケーション・コンテキストには、ユーザーがデータに対して保持するアクセスを制御する場合に多くのメリットがあります。
- アプリケーション・コンテキストとは
アプリケーション・コンテキストは、Oracle Databaseがメモリーに格納する名前と値のペアです。 - アプリケーション・コンテキストの構成要素
アプリケーション・コンテキストには2つのコンポーネントがあり、名前と値のペアを構成します。 - アプリケーション・コンテキストの値の格納場所
Oracle Databaseではアプリケーション・コンテキスト値が保護データ・キャッシュに格納されます。 - アプリケーション・コンテキストを使用する利点
ほとんどのアプリケーションには、アプリケーション・コンテキストに使用可能なある種の情報が含まれています。 - エディションがアプリケーション・コンテキストの値に与える影響
Oracle Databaseでは、アプリケーション・コンテキスト・パッケージの影響を受けるすべてのエディションでアプリケーション・コンテキストが設定されます。 - マルチテナント環境でのアプリケーション・コンテキスト
マルチテナント環境のどこでアプリケーションを作成するかによって、アプリケーション・コンテキストを作成する場所が決まります。
10.1.1 アプリケーション・コンテキストとは
アプリケーション・コンテキストとは、Oracle Databaseがメモリーに格納する名前と値のペアです。
コンテキストには、ネームスペースと呼ばれるラベル(たとえば、従業員IDを取得するアプリケーション・コンテキストにはempno_ctx
)があります。このコンテキストにより、Oracle Databaseは認証中にデータベース・ユーザーと非データベース・ユーザーに関する情報を入手できます。
コンテキスト内は名前と値のペア(結合配列)です。名前は、値を保持するメモリー内の場所を指定します。アプリケーションはアプリケーション・コンテキストを使用して、ユーザーに関するセッション情報(ユーザーIDまたは他のユーザー固有の情報など)またはクライアントIDにアクセスして、その情報をデータベースに安全に引き渡すことができます。
この情報を使用して、ユーザーがアプリケーションを通じてデータにアクセスできるようにしたりアクセスできないようにできます。アプリケーション・コンテキストを使用して、データベース・ユーザーと非データベース・ユーザーの両方を認証できます。
関連トピック
親トピック: アプリケーション・コンテキストについて
10.1.2 アプリケーション・コンテキストの構成要素
アプリケーション・コンテキストには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)コールを使用してアプリケーション・コンテキストを設定することもできます。
親トピック: アプリケーション・コンテキストについて
10.1.3 アプリケーション・コンテキストの値の格納場所
Oracle Databaseではアプリケーション・コンテキスト値が保護データ・キャッシュに格納されます。
このキャッシュはユーザー・グローバル領域(UGA)またはシステム("共有"と呼ばれる場合もある)グローバル領域(SGA)にあります。格納されたアプリケーション・コンテキストの値はセッション中に取得されます。アプリケーション・コンテキストには、このデータ・キャッシュ内の値が格納されるため、アプリケーションのパフォーマンスが向上します。アプリケーション・コンテキストは単独で使用でき、Oracle Virtual Private Databaseポリシーまたはその他のファイングレイン・アクセス制御ポリシーと併用することもできます。
10.1.4 アプリケーション・コンテキストを使用する利点
ほとんどのアプリケーションには、アプリケーション・コンテキストに使用可能なある種の情報が含まれています。
たとえば、ORDER_NUMBER
列とCUSTOMER_NUMBER
列を備えた表を使用する受注管理アプリケーションでは、それらの列の値をセキュリティ属性として使用して、顧客によるアクセスをその顧客のIDに基づいて顧客自身の注文のみに制限できます。
アプリケーション・コンテキストは、次の目的で使用されます。
-
ファイングレイン・アクセス・コントロールの規定(Oracle Virtual Private Databaseポリシーなどで)
-
複数層環境でのユーザー識別情報の保持
-
アプリケーションに対する強力なセキュリティの規定(アプリケーション・コンテキストはユーザーではなくトラステッド・プロシージャによって制御されるため)
-
アプリケーションがファイングレイン監査やPL/SQL条件文またはループで使用する際に必要な属性に対して、保護データ・キャッシュとしての機能を果すことによるパフォーマンスの向上
このキャッシュによって、これらの属性が必要になるたびにデータベースに問い合せるというオーバーヘッドが軽減されます。アプリケーションはセッション・データを表から繰り返し取得する必要がなく、このデータがアプリケーション・コンテキストによってキャッシュに格納されるため、アプリケーションのパフォーマンスが大幅に向上します。
-
アプリケーションで定義、変更およびアクセスできる名前と値のペアの保持領域として機能
親トピック: アプリケーション・コンテキストについて
10.1.5 エディションがアプリケーション・コンテキストの値に与える影響
Oracle Databaseでは、アプリケーション・コンテキスト・パッケージの影響を受けるすべてのエディションでアプリケーション・コンテキストが設定されます。
アプリケーション・コンテキストで設定される値は、アプリケーション・コンテキストが影響するすべてのエディションで表示されます。データベース内のすべてのエディション、およびそれが使用可能であるかどうかを検索するには、ALL_EDITIONSデータ・ディクショナリ・ビューを問い合せます。
関連項目:
エディションの詳細は、『Oracle Database開発ガイド』を参照してください。
親トピック: アプリケーション・コンテキストについて
10.1.6 マルチテナント環境でのアプリケーション・コンテキスト
マルチテナント環境のどこでアプリケーションを作成するかによって、アプリケーション・コンテキストを作成する場所が決まります。
アプリケーション・ルートまたはCDBルートにアプリケーションがインストールされると、そのアプリケーションはアプリケーション・コンテナまたはシステム・コンテナおよび関連付けられたアプリケーションPDBからアクセスできるようになります。そのルートで共通アプリケーション・コンテキストを作成する必要があります。
アプリケーション・コンテナで使用する共通アプリケーション・コンテキストを作成する場合は、次の点に注意してください。
-
マルチテナント環境でアプリケーション・コンテキストを作成するには、
CREATE CONTEXT
SQL文でCONTAINER
句を設定します。たとえば、アプリケーション・ルートで共通アプリケーション・コンテキストを作成するには、CONTAINER
をALL
に設定してCREATE CONTEXT
を実行する必要があります。PDBでアプリケーション・コンテキストを作成するには、CONTAINER
をCURRENT
に設定します。 -
ローカル・アプリケーション・コンテキストと共通アプリケーション・コンテキストに同じ名前を使用することはできません。既存のアプリケーション・コンテキストの名前は、次の問合せを実行して検索できます。
SELECT OBJECT_NAME FROM DBA_OBJECTS WHERE OBJECT_TYPE ='CONTEXT';
-
共通アプリケーション・コンテキストを管理するために作成するPL/SQLパッケージは、共通PL/SQLパッケージであることが必要です。つまり、それがアプリケーション・ルートまたはCDBルートに存在する必要があります。特定のPDBのアプリケーション・コンテキストを作成する場合、関連付けられたPL/SQLパッケージをそのPDBに格納する必要があります。
-
共通アプリケーション・コンテキストのアプリケーション・コンテナまたはシステム・コンテナから共通セッション・アプリケーション・コンテキストの下に設定した名前と値のペアは、共通ユーザーが異なるコンテナにアクセスする場合、他のアプリケーション・コンテナまたはシステム・コンテナからアクセスできません。
-
アプリケーション・コンテナまたはシステム・コンテナから共通グローバル・アプリケーション・コンテキストの下に設定した名前と値のペアは、同じユーザー・セッションの同じコンテナ内の場合にかぎりアクセスできます。
-
アプリケーションは、アプリケーション・ルート、CDBルートまたはPDBのいずれに存在していても、アプリケーション・コンテキストの値を取得できます。
-
CDBまたはアプリケーション・コンテナへのPDBの接続操作中、共通アプリケーション・コンテキストの名前がPDBのローカル・アプリケーション・コンテキストの名前と競合する場合は、PDBを制限モードでオープンする必要があります。データベース管理者は、PDBを通常モードでオープンする前に、競合を修正する必要があります。
-
切断操作中、共通アプリケーション・コンテキストはその共通セマンティクスを維持することで、後にそのPDBが同じ名前の共通アプリケーション・コンテキストがある別のCDBに接続する場合、引き続き共通オブジェクトのように動作します。PDBが同じ共通アプリケーション・コンテキストが存在しないアプリケーション・コンテナまたはシステム・コンテナに接続する場合、そのPDBはローカル・オブジェクトのように動作します。
アプリケーション・コンテキストがローカル・アプリケーション・コンテキストであるかアプリケーションの共通アプリケーション・コンテキストであるかを確認するには、DBA_CONTEXT
またはALL_CONTEXT
データ・ディクショナリ・ビューのSCOPE
列を問い合せます。
親トピック: アプリケーション・コンテキストについて
10.2 アプリケーション・コンテキストの種類
アプリケーション・コンテキストには、3種類の一般的なカテゴリがあります。
カテゴリは次のとおりです。
-
データベース・セッション・ベースのアプリケーション・コンテキスト。このタイプのアプリケーション・コンテキストは、データベース・ユーザー・セッション(つまりUGA)のキャッシュに格納されているデータを取得します。データベース・セッション・ベースのアプリケーション・コンテキストは、3つのカテゴリに分類されます。
-
ローカルで初期化。ユーザーのセッションに対してアプリケーション・コンテキストをローカルで初期化します。
-
外部で初期化。Oracle Call Interface(OCI)アプリケーション、ジョブ・キュー・プロセスまたは接続ユーザーのデータベース・リンクからアプリケーション・コンテキストを初期化します。
-
グローバルに初期化。LDAPディレクトリなどの集中格納場所から属性と値を使用します。
このタイプのアプリケーション・コンテキストについては、「データベース・セッション・ベースのアプリケーション・コンテキストの使用」を参照してください。
-
-
グローバル・アプリケーション・コンテキスト。このタイプは、システム・グローバル領域(SGA)に格納されるデータを取得するため、3層アーキテクチャの中間層アプリケーションなど、セッションを使用しないアプリケーションに対して使用できます。グローバル・アプリケーション・コンテキストは、セッション・コンテキストをセッション間で、たとえば接続プールの実装を通じて共有する場合に便利です。
このタイプについては、「グローバル・アプリケーション・コンテキスト」を参照してください。
-
クライアント・セッション・ベースのアプリケーション・コンテキスト。このタイプのアプリケーション・コンテキストは、クライアント側のOracle Call Interface関数を使用してユーザー・セッション・データを設定し、次に、必要なセキュリティ・チェックを実行してユーザー・アクセスを制限します。
このタイプについては、「クライアント・セッション・ベースのアプリケーション・コンテキストの使用」を参照してください。
表10-1に、異なる種類のアプリケーション・コンテキストの要約を示します。
表10-1 アプリケーション・コンテキストの種類
アプリケーション・コンテキストの種類 | UGAへの格納 | SGAへの格納 | 接続ユーザー・データベース・リンクのサポート | ユーザーのアプリケーション・コンテキストの集中保管のサポート | セッションを使用しない複数層アプリケーションのサポート |
---|---|---|---|---|---|
ローカルで初期化されるデータベース・セッション・ベースのアプリケーション・コンテキスト |
はい |
いいえ |
いいえ |
いいえ |
いいえ |
外部で初期化されるデータベース・セッション・ベースのアプリケーション・コンテキスト |
はい |
いいえ |
はい |
いいえ |
いいえ |
グローバルに初期化されるデータベース・セッション・ベースのアプリケーション・コンテキスト |
はい |
いいえ |
いいえ |
はい |
いいえ |
グローバル・アプリケーション・コンテキスト |
いいえ |
はい |
いいえ |
いいえ |
はい |
クライアント・セッション・ベースのアプリケーション・コンテキスト |
はい |
いいえ |
はい |
いいえ |
はい |
10.3 データベース・セッション・ベースのアプリケーション・コンテキストの使用
データベース・セッション・ベースのアプリケーション・コンテキストを使用すると、ユーザーのセッション・ベースの情報を取得できます。
- データベース・セッション・ベースのアプリケーション・コンテキストについて
データベース・セッション・ベースのアプリケーション・コンテキストで、データベース・ユーザーのセッション情報を取得します。 - データベース・セッション・ベースのアプリケーション・コンテキストのコンポーネント
データベース・セッション・ベースのアプリケーション・コンテキストは、コンテキストのデータを取得および設定して、ユーザーがログインするときにこのコンテキストを設定します。 - データベース・セッション・ベースのアプリケーション・コンテキストの作成
データベース・セッション・ベースのアプリケーション・コンテキストは、ユーザーのセッション情報を格納する名前付きのオブジェクトです。 - データベース・セッション・ベースのアプリケーション・コンテキストを設定するためのパッケージの作成
PL/SQLパッケージを使用し、セッション情報を取得してアプリケーション・コンテキストの名前と値の属性を設定できます。 - データベース・セッションのアプリケーション・コンテキスト・パッケージを実行するログイン・トリガー
データベース・インスタンスにログインした後、ユーザーはデータベース・セッションのアプリケーション・コンテキスト・パッケージを実行する必要があります。 - 例: 単純なログイン・トリガーの作成
CREATE TRIGGER
文で簡単なログイン・トリガーを作成できます。 - 例: 本番環境用のログイン・トリガーの作成
CREATE TRIGGER
文で、本番環境のログイン・トリガーを作成できます。 - 例: 開発環境用のログイン・トリガーの作成
CREATE TRIGGER
文で、開発環境のログイン・トリガーを作成できます。 - 例: データベース・セッション・ベースのアプリケーション・コンテキストの作成と使用
このチュートリアルでは、データベースへのログインを試みるユーザーのIDをチェックするアプリケーション・コンテキストの作成方法を示します。 - データベース・セッション・ベースのアプリケーション・コンテキストの外部での初期化
データベース・セッション・ベースのアプリケーション・コンテキストを外部で初期化すると、アプリケーション・コンテキストがユーザー・グローバル領域(UGA)に格納されるため、パフォーマンスが向上します。 - データベース・セッション・ベースのアプリケーション・コンテキストのグローバルな初期化
データベース・セッション・ベースのアプリケーションが集中格納場所に格納されている場合、そのアプリケーションはLDAPディレクトリ全域から使用できます。 - 外部化されたデータベース・セッション・ベースのアプリケーション・コンテキスト
多くのアプリケーションでは、ファイングレイン・アクセス・コントロールに使用される属性をデータベース・メタデータ表に格納します。
10.3.1 データベース・セッション・ベースのアプリケーション・コンテキストについて
データベース・セッション・ベースのアプリケーション・コンテキストで、データベース・ユーザーのセッション情報を取得します。
このタイプのアプリケーション・コンテキストは、Oracle Database内でPL/SQLプロシージャを使用し、管理の対象となるデータを取得、設定および保護します。
データベース・セッション・ベースのアプリケーション・コンテキストは、Oracle Databaseの中で完全管理されます。Oracle Databaseが値を設定し、ユーザーがセッションを終了すると、キャッシュに保管されたアプリケーション・コンテキスト値を自動的にクリアします。ユーザー接続が異常終了すると(たとえば停電)、PMONバックグラウンド・プロセスはアプリケーション・コンテキスト・データをクリーン・アップします。アプリケーション・コンテキストをキャッシュから消去する必要はありません。
アプリケーション・コンテキストをOracle Databaseで管理する利点は、アプリケーション・コンテキストを集中管理できる点です。このデータベースにアクセスするアプリケーションは、このアプリケーション・コンテキストを使用して、そのアプリケーションに対するユーザーのアクセスを許可または防止する必要があります。これによって、パフォーマンス向上とセキュリティ強化の両方の利点が得られます。
ノート:
ユーザーがアプリケーション・ユーザー(つまり、データベースに存在しないユーザー)の場合は、グローバル・アプリケーション・コンテキストの使用を考慮してください。
関連トピック
10.3.2 データベース・セッション・ベースのアプリケーション・コンテキストのコンポーネント
データベース・セッション・ベースのアプリケーション・コンテキストは、コンテキストのデータを取得および設定して、ユーザーがログインするときにこのコンテキストを設定します。
データベース・セッション・ベースのアプリケーション・コンテキストを作成して使用するには、アプリケーション・コンテキスト、データの取得とコンテキストの設定を実行するプロシージャ、およびユーザーのログイン時にコンテキストを設定する手段の3つのコンポーネントを使用する必要があります。
-
アプリケーション・コンテキスト。アプリケーション・コンテキストを作成するには、
CREATE CONTEXT
SQL文を使用します。この文は、アプリケーション・コンテキスト(ネームスペース)名を設定し、セッション・データを取得してアプリケーション・コンテキストを設定するように設計されたPL/SQLプロシージャに対して、その名前を関連付けます。 -
データの取得とコンテキストの設定を実行するPL/SQLプロシージャ。このプロシージャで実行する必要があるタスクの概要については、データベース・セッション・ベースのアプリケーション・コンテキストを管理するパッケージについてを参照してください。理想的には、必要に応じて他のプロシージャ(タスクのエラー・チェックなど)を挿入できるように、このプロシージャは1つのパッケージ内に作成します。
-
ユーザーのログイン時にアプリケーション・コンテキストを設定する手段。アプリケーション・コンテキストを使用するアプリケーションにログインするユーザーは、そのアプリケーション・コンテキストを設定するPL/SQLパッケージを実行する必要があります。そのためには、ユーザーがログインするたびに起動するログイン・トリガーを使用するか、この機能をアプリケーションに埋め込むことができます。
ローカルで初期化されるデータベース・セッション・ベースのアプリケーション・コンテキストの作成方法と使用方法は、例: データベース・セッション・ベースのアプリケーション・コンテキストの作成と使用を参照してください。
さらに、セッション・ベースのアプリケーション・コンテキストは、外部で、またはグローバルに初期化できます。いずれの場合も、コンテキスト情報はユーザー・セッションに格納されます。
-
外部での初期化。この初期化は、OCIインタフェース、ジョブ・キュー・プロセスまたは接続ユーザーのデータベース・リンクから発生します。詳細は、データベース・セッション・ベースのアプリケーション・コンテキストの外部での初期化を参照してください。
-
グローバルな初期化。この初期化では、LDAPディレクトリなどの集中格納場所から属性と値を使用します。詳細は、データベース・セッション・ベースのアプリケーション・コンテキストのグローバルな初期化を参照してください。
10.3.3 データベース・セッション・ベースのアプリケーション・コンテキストの作成
データベース・セッション・ベースのアプリケーション・コンテキストは、ユーザーのセッション情報を格納する名前付きのオブジェクトです。
- データベース・セッション・ベースのアプリケーション・コンテキストの作成について
ユーザー作成のネームスペースを使用して、データベース・ユーザー・セッション(UGA)には、セッション・ベースのアプリケーション・コンテキストが格納されます。 - データベース・セッション・ベースのアプリケーション・コンテキストの作成
CREATE
CONTEXT
SQL文を使用して、データベース・セッション・ベースのアプリケーション・コンテキストを作成できます。 - 複数のアプリケーションのデータベース・セッション・ベースのアプリケーション・コンテキスト
各アプリケーションには、独自の属性を持つアプリケーション・コンテキストを作成できます。
10.3.3.1 データベース・セッション・ベースのアプリケーション・コンテキストの作成について
ユーザー作成のネームスペースを使用して、データベース・ユーザー・セッション(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';
10.3.3.2 データベース・セッション・ベースのアプリケーション・コンテキストの作成
CREATE
CONTEXT
SQL文を使用して、データベース・セッション・ベースのアプリケーション・コンテキストを作成できます。
データベース・セッション・ベースのアプリケーション・コンテキストを作成する場合、そのアプリケーション・コンテキストのネームスペースを作成し、ユーザーのセッション情報を保持する名前と値のペアを管理するPL/SQLパッケージとそのネームスペースを関連付ける必要があります。PL/SQLパッケージは、コンテキストの作成時には不要ですが、実行時には存在している必要があります。
-
データベース・セッション・ベースのアプリケーション・コンテキストを作成するには、
CREATE
CONTEXT
SQL文を使用します。たとえば:
CREATE CONTEXT empno_ctx USING set_empno_ctx_pkg CONTAINER = CURRENT;
この例では、次のようになります。
-
empno_ctx
はコンテキスト・ネームスペースです。 -
set_empno_ctx_pkg
は、そのempno_ctx
ネームスペースの属性を設定するパッケージです(コンテキストの作成時には不要です)。このアプリケーション・コンテキストで使用可能なパッケージの作成方法の例は、ステップ3: セッション・データを取得してアプリケーション・コンテキストを設定するパッケージの作成を参照してください。 -
CONTAINER
は、現在のPDBでアプリケーション・コンテキストを作成します。アプリケーション・ルートまたはCDBルートでアプリケーション・コンテキストを作成するには、CONTAINER
をALL
に設定する必要があります。
コンテキストを作成するときは、そのコンテキストの名前/値の属性をCREATE CONTEXT
文に設定しないでください。かわりに、これらは、アプリケーション・コンテキストに関連付けるPL/SQLパッケージに設定してください。これは、不正なユーザーによって、適切な属性の検証なしにコンテキスト属性が変更されないようにするためです。このパッケージがアプリケーション・コンテキストと同じコンテナにあることを確認してください。たとえば、アプリケーション・コンテキストをPDBに作成した場合、PL/SQLパッケージはそのPDBに存在する必要があります。
ノート:
CLIENTCONTEXT
というコンテキストは作成できません。これは、クライアント・セッション・ベースのアプリケーション・コンテキストで使用される予約語です。このタイプのアプリケーション・コンテキストの詳細は、クライアント・セッション・ベースのアプリケーション・コンテキストの使用を参照してください。
10.3.3.3 複数のアプリケーションのデータベース・セッション・ベースのアプリケーション・コンテキスト
各アプリケーションには、独自の属性を持つアプリケーション・コンテキストを作成できます。
たとえば、General Ledger(一般会計)、Order Entry(受注管理)およびHuman Resources(人事管理)という3つのアプリケーションがあるとします。
これらの各アプリケーションには、異なる属性を指定できます。
-
受注管理アプリケーション・コンテキストには、
CUSTOMER_NUMBER
属性を指定できます。 -
一般会計アプリケーション・コンテキストには、
SET_OF_BOOKS
属性とTITLE
属性を指定できます。 -
人事管理アプリケーション・コンテキストには、
ORGANIZATION_ID
、POSITION
、COUNTRY
の各属性を指定できます。
属性がアクセスするデータは、アプリケーション外の表に保管されます。たとえば、受注管理アプリケーションではOE.CUSTOMERS
という名前の表が使用されており、この中のCUSTOMER_NUMBER
列にはCUSTOMER_NUMBER
属性のデータが入ります。いずれの場合にも、アプリケーション・コンテキストを厳密なセキュリティ・ニーズに適用できます。
10.3.4 データベース・セッション・ベースのアプリケーション・コンテキストを設定するためのパッケージの作成
PL/SQLパッケージを使用し、セッション情報を取得してアプリケーション・コンテキストの名前と値の属性を設定できます。
- データベース・セッション・ベースのアプリケーション・コンテキストを管理するパッケージについて
これは、アプリケーション・コンテキストによって表されるセッション・データを管理するプロシージャを定義します。 - SYS_CONTEXTファンクションを使用したセッション情報の取得
SYS_CONTEXT
ファンクションを使用して、アプリケーション・コンテキストのセッション情報を取得できます。 - SYS_CONTEXT設定の確認
DUAL
表に格納されるSYS_CONTEXT
設定を確認できます。 - SYS_CONTEXTでの動的SQL
指定した問合せを実行する間にポリシーの変更が予想されるセッション中は、その問合せに動的SQLを使用する必要があります。 - パラレル問合せでのSYS_CONTEXT
パラレル問合せに埋め込まれているSQL関数内でSYS_CONTEXT
を使用すると、この関数にアプリケーション・コンテキストが挿入されます。 - データベース・リンクでのSYS_CONTEXT
SYS_CONTEXT
ファンクションはデータベース・リンクと一緒に使用できます。 - セッション情報を設定するためのDBMS_SESSION.SET_CONTEXT
SYS_CONTEXT
でユーザーのセッション・データを取得した後、ユーザー・セッションからアプリケーション・コンテキスト値を設定できます。 - 例: アプリケーション・コンテキストの値を作成する単純なプロシージャ
プロシージャでDBMS_SESSION.SET_CONTEXT文を使用して、アプリケーション・コンテキストの値を設定できます。
10.3.4.1 データベース・セッション・ベースのアプリケーション・コンテキストを管理するパッケージについて
これは、アプリケーション・コンテキストにより示されたセッション・データを管理するプロシージャを定義します。
このパッケージは、通常、セキュリティ管理者のスキーマに作成されます。パッケージでは、次のタスクを実行する必要があります。
-
セッション情報の取得。ユーザー・セッション情報の取得には、
SYS_CONTEXT
SQL関数を使用できます。このSYS_CONTEXT
関数は、コンテキストのネームスペースに関連付けられているパラメータの値を戻します。この関数は、SQL文とPL/SQL文の両方で使用できます。通常は、組み込まれているUSERENV
ネームスペースを使用してユーザーのセッション情報を取得します。SYS_SESSION_ROLES
ネームスペースを使用して、セッションに対して指定したロールが現在有効化されているかどうかを示すこともできます。 -
CREATE CONTEXTで作成したアプリケーション・コンテキストの名前/値の属性の設定。アプリケーション・コンテキストの名前/値の属性の設定には、
DBMS_SESSION.SET_CONTEXT
プロシージャを使用できます。この名前/値の属性には、ユーザーID、IPアドレス、認証モード、アプリケーション名などの情報を格納できます。設定した属性の値は、再設定するまで、またはユーザーがセッションを終了するまでそのまま残ります。次のことに注意してください。-
ネームスペース内のパラメータの値がすでに設定されている場合は、
SET_CONTEXT
によってこの値が上書きされます。 -
コンテキストの値が変更された場合、その内容はただちに反映され、
SYS_CONTEXT
ファンクションによって値を取得する後続のコールでは、最新の値が戻されます。
-
-
ユーザーによる実行。パッケージを作成した後、ログインする場合ユーザーはそのパッケージを実行する必要があります。ユーザーがログインするときパッケージを自動的に実行するためのログイン・トリガーを作成するか、この機能をアプリケーションに埋め込むことができます。アプリケーション・コンテキスト・セッション値はユーザーがセッションを終了すると自動的にクリアされるので、セッション・データを手動で削除する必要はありません。
プロシージャはトラステッド・プロシージャであることに注意してください。ユーザーが自分独自のアプリケーション・コンテキスト属性値を設定できないように設計されています。ユーザーはプロシージャを実行しますが、プロシージャがアプリケーション・コンテキスト値を設定します、ユーザーではありません。
関連項目:
-
SYS_CONTEXT
ファンクションの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。 -
データベース・セッション・ベースのアプリケーション・コンテキストの作成方法は、例: データベース・セッション・ベースのアプリケーション・コンテキストの作成と使用を参照してください
10.3.4.2 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
関数にかわる機能です。
10.3.4.3 SYS_CONTEXT設定の確認
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
10.3.4.4 SYS_CONTEXTでの動的SQL
指定した問合せを実行する間にポリシーの変更が予想されるセッション中は、その問合せに動的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述語の形で表され、述語はポリシーとみなされます。述語が変更された場合、正しい結果を生成するために文を再度解析する必要があります。
10.3.4.5 パラレル問合せでのSYS_CONTEXT
パラレル問合せに埋め込まれている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;
この文をパラレル問合せとして実行すると、アプリケーション・コンテキスト情報を含むユーザー・セッションはパラレル実行サーバー(問合せ子プロセス)に伝播されます。
10.3.4.6 データベース・リンクでのSYS_CONTEXT
SYS_CONTEXT
ファンクションはデータベース・リンクと一緒に使用できます。
ユーザー・セッション内のSQL文にデータベース・リンクが含まれている場合は、そのデータベース・リンクのホスト・コンピュータでSYS_CONTEXT
関数が実行され、そのホスト・コンピュータにあるコンテキスト情報が取得されます。
リモートのPL/SQLプロシージャ・コールがデータベース・リンクで実行されている場合は、そのプロシージャ内部のすべてのSYS_CONTEXT
関数が、そのリンクの宛先データベースで実行されます。
この場合、データベース・リンクの宛先サイトで使用できるのは、外部で初期化されたアプリケーション・コンテキストのみです。セキュリティ上の理由から、データベース・リンクの開始サイトから宛先サイトに伝播されるのは、外部で初期化されたアプリケーション・コンテキストのみです。
10.3.4.7 セッション情報を設定するためのDBMS_SESSION.SET_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パッケージおよびタイプ・リファレンス』 を参照してください。
10.3.4.8 例: アプリケーション・コンテキストの値を作成する単純なプロシージャ
プロシージャでDBMS_SESSION.SET_CONTEXT文を使用して、アプリケーション・コンテキストの値を設定できます。
例10-1に、empno_ctx
アプリケーション・コンテキストの属性を作成する単純なプロシージャの作成方法を示します。
例10-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
10.3.5 データベース・セッションのアプリケーション・コンテキスト・パッケージを実行するログオン・トリガー
データベース・インスタンスにログインした後、ユーザーはデータベース・セッションのアプリケーション・コンテキスト・パッケージを実行する必要があります。
これを自動的に処理するようにログイン・トリガーを作成できます。パッケージを実行するためのEXECUTE
権限をユーザーに付与する必要はありません。
次のことに注意してください。
-
ログイン・トリガーによって呼び出されたPL/SQLパッケージ・プロシージャに未処理例外があるか(たとえばセキュリティ・チェックに失敗したために)なんらかの例外を発生すると、ログイン・トリガーは失敗します。ログイン・トリガーに失敗すると、ログインは失敗し、つまりユーザーはデータベースにログインする権限が拒否されます。
-
ログイン・トリガーがパフォーマンスに影響を与える可能性があります。また、ログイン・トリガーは、最初にサンプル・スキーマ・ユーザーでテストしてから、データベース用に作成してください。これによって、エラーがあった場合は簡単に修正できます。
-
会計帳簿の変更や職階の変更が頻繁にある場合は注意が必要です。この場合、新しい属性値はすぐに選択できない可能性があるため、カーソルの再解析を強制実行して、新しい属性値を選択する必要があります。
ノート:
ユーザー・コンテキスト(EMPNO
、GROUP
、MANAGER
などの情報)は、ユーザーがデータにアクセスする前に設定されるため、ログイン・トリガーを使用できます。
10.3.6 例: 単純なログイン・トリガーの作成
CREATE TRIGGER
文で簡単なログイン・トリガーを作成できます。
例10-2に、PL/SQLプロシージャを実行する単純なログイン・トリガーを示します。
例10-2 単純なログイン・トリガーの作成
CREATE OR REPLACE TRIGGER set_empno_ctx_trig AFTER LOGON ON DATABASE BEGIN sec_mgr.set_empno_ctx_proc; END;
10.3.7 例: 本番環境用のログイン・トリガーの作成
CREATE TRIGGER
文で、本番環境のログイン・トリガーを作成できます。
例10-3は、WHEN OTHERS例外を使用するログイン・トリガーの作成方法を示しています。一方、PL/SQLロジックにエラーが発生して未処理例外を引き起こす場合は、データベースへのすべての接続がブロックされます。
この例は、セキュリティ管理者のスキーマの表にエラーを書き込むWHEN OTHERS
例外を示しています。本番環境では、こちらのほうが、出力をユーザー・セッションへ送信することでセキュリティ攻撃を受けやすくなるよりも安全です。
例10-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; /
10.3.8 例: 開発環境用のログイン・トリガーの作成
CREATE TRIGGER
文で、開発環境のログイン・トリガーを作成できます。
例10-4に、同じログイン・トリガーを開発環境用に作成する方法を示します。この場合、エラーをデバッグのためにユーザー・セッションに出力できます。
例10-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; /
10.3.9 例: データベース・セッション・ベースのアプリケーション・コンテキストの作成と使用
このチュートリアルでは、データベースへのログインを試みるユーザーのIDをチェックするアプリケーション・コンテキストの作成方法を示します。
- ステップ1: ユーザー・アカウントの作成とユーザーSCOTTがアクティブであることの確認
このチュートリアルを開始するには、必要なデータベース・アカウントを作成し、SCOTT
ユーザー・アカウントがアクティブであることを確認する必要があります。 - ステップ2: データベース・セッション・ベースのアプリケーション・コンテキストの作成
sysadmin_ctx
ユーザーとして、データベース・セッション・ベースのアプリケーション・コンテキストを作成します。 - ステップ3: セッション・データを取得してアプリケーション・コンテキストを設定するパッケージの作成
次に、セッション・データを取得してアプリケーション・コンテキストを設定するPL/SQLパッケージを作成する必要があります。 - ステップ4: パッケージに対するログイン・トリガーの作成
ログイン・トリガーは、ユーザーがログインすると実行されます。 - ステップ5: アプリケーション・コンテキストのテスト
すべてのコンポーネントの準備ができると、アプリケーション・コンテキストをテストできます。 - ステップ6: このチュートリアルのコンポーネントの削除
このチュートリアルのコンポーネントが不要になった場合、それらを削除できます。
10.3.9.1 ステップ1: ユーザー・アカウントの作成とユーザーSCOTTがアクティブであることの確認
このチュートリアルを開始するには、必要なデータベース・アカウントを作成し、SCOTT
ユーザー・アカウントがアクティブであることを確認する必要があります。
10.3.9.2 ステップ2: データベース・セッション・ベースのアプリケーション・コンテキストの作成
sysadmin_ctx
ユーザーとして、データベース・セッション・ベースのアプリケーション・コンテキストを作成します。
10.3.9.3 ステップ3: セッション・データを取得してアプリケーション・コンテキストを設定するパッケージの作成
次に、セッション・データを取得してアプリケーション・コンテキストを設定するPL/SQLパッケージを作成する必要があります。
-
パッケージを作成するには、
CREATE OR REPLACE PACKAGE
文を使用します。
例10-5に、セッション・データを取得してアプリケーション・コンテキストを設定するために必要なパッケージの作成方法を示します。パッケージを作成する前に、ユーザーsysadmin_ctx
でログインしていることを確認してください。(最初の行のCREATE OR REPLACE
の前にカーソルを置くことで、このテキストをコピーして貼り付けることができます。)
例10-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
表にリストされたユーザーを除き、システム管理者以外のユーザーはデータベースにログインできなくなります。他のユーザーは、有効なデータベース・ユーザーであればデータベースにログインできます。アプリケーション・コンテキスト情報が設定された後は、特定のアプリケーションへのユーザー・アクセスを制御する手段として、このセッション情報を使用できます。
10.3.9.4 ステップ4: パッケージに対するログイン・トリガーの作成
ログオン・トリガーは、ユーザーがログインすると実行されます。
-
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; /
10.3.9.5 ステップ5: アプリケーション・コンテキストのテスト
すべてのコンポーネントの準備ができると、アプリケーション・コンテキストをテストできます。
これ以降、アプリケーションではユーザー・セッション情報を使用してユーザーがデータベース内で許可されるアクセス数を判別できます。そのためには、Oracle Virtual Private Databaseを使用できます。
10.3.10 データベース・セッション・ベースのアプリケーション・コンテキストの外部での初期化
データベース・セッション・ベースのアプリケーション・コンテキストを外部で初期化すると、アプリケーション・コンテキストがユーザー・グローバル領域(UGA)に格納されるため、パフォーマンスが向上します。
- データベース・セッション・ベースのアプリケーション・コンテキストの外部による初期化について
セッション・ベースのアプリケーション・コンテキストを外部で初期化するには、特別な種類のネームスペースを使用する必要があります。 - ユーザーからのデフォルト値
Oracle Databaseでは、アプリケーションのユーザーからデフォルト値を取得して使用できます。 - 他の外部リソースからの値
アプリケーション・コンテキストによって、外部リソースを介して属性と値の初期化を受け入れることができます。 - 例: 外部化されたデータベース・セッション・ベースのアプリケーション・コンテキストの作成
CREATE CONTEXT
SQL文で、外部化されたデータベース・セッション・ベースのアプリケーション・コンテキストを作成できます。 - 中間層サーバーからのアプリケーション・コンテキスト値の初期化
中間層サーバーは、データベース・ユーザーのかわりにアプリケーション・コンテキスト値を初期化できます。
10.3.10.1 データベース・セッション・ベースのアプリケーション・コンテキストの外部による初期化について
セッション・ベースのアプリケーション・コンテキストを外部で初期化するには、特別な種類のネームスペースを使用する必要があります。
このネームスペースは外部リソースからの属性値の初期化を受け入れ、ローカル・ユーザー・セッションに格納する必要があります。
アプリケーション・コンテキストは外部で初期化することによりUGAに格納されて、属性をセッションから別のセッションへ自動伝播できるようになるため、パフォーマンスが向上します。接続ユーザー・データベース・リンクをサポートするのは、OCIベースの外部ソースから初期化されたアプリケーション・コンテキストのみです。
10.3.10.2 ユーザーからのデフォルト値
Oracle Databaseでは、アプリケーションのユーザーからデフォルト値を取得して使用できます。
ユーザーからデフォルトを取得することが必要な場合があります。最初、これらのデフォルト値はヒントまたはプリファレンスとして機能し、検証後にトラステッド・コンテキストになります。同様に、クライアントでは、一部のデフォルト値を初期化してから、ログイン・イベント・トリガーまたはアプリケーションを使用して値の検証を行うと便利です。
ジョブ・キューに関しては、ジョブ発行ルーチンで、ジョブの発行時に設定されたコンテキストを記録し、バッチ・ジョブの実行時にそのコンテキストをリストアします。コンテキストの整合性を保持するために、ジョブ・キューは、コンテキストを設定する特定のPL/SQLパッケージを回避できません。一方、外部で初期化されたアプリケーション・コンテキストは、コンテキスト値の初期化をジョブ・キュー・プロセスから受け入れます。
リモート・セッションへのコンテキストの自動伝播によって、セキュリティ上の問題が発生する場合があります。開発者または管理者は、ユーザーのログイン時にログイン・トリガーを使用してコンテキストを再設定することで、特定のPL/SQLプロシージャ以外のリソースからデフォルト値を取得するコンテキストを効果的に処理できます。
10.3.10.3 他の外部リソースからの値
アプリケーション・コンテキストによって、外部リソースを介して属性と値の初期化を受け入れることができます。
このような外部リソースには、Oracle Call Interface (OCI)インタフェース、ジョブ・キュー・プロセスまたはデータベース・リンクなどが含まれます。
外部で初期化されたアプリケーション・コンテキストでは、次の機能が提供されます。
-
リモート・セッションの場合は、外部で初期化されたアプリケーション・コンテキスト・ネームスペースにあるコンテキスト値を自動的に伝播します。
-
ジョブ・キューの場合は、外部で初期化されたアプリケーション・コンテキスト・ネームスペースにあるコンテキスト値をリストアします。
-
OCIインタフェースの場合は、外部で初期化されたアプリケーション・コンテキスト・ネームスペースにあるコンテキスト値を初期化するメカニズムを提供します。
Oracle Call Interfaceを使用しているクライアント・プログラムであればこのタイプのネームスペースの初期化は可能ですが、ログイン・イベント・トリガーを使用して値を検証できます。属性の値を解釈して信頼するかどうかはアプリケーションによって異なります。
10.3.10.4 例: 外部化されたデータベース・セッション・ベースのアプリケーション・コンテキストの作成
CREATE CONTEXT
SQL文で、外部化されたデータベース・セッション・ベースのアプリケーション・コンテキストを作成できます。
例10-6に、外部ソースから値を取得するデータベース・セッション・ベースのアプリケーション・コンテキストを作成する方法を示します。
例10-6 外部化されたデータベース・セッション・ベースのアプリケーション・コンテキストの作成
CREATE CONTEXT ext_ctx USING ext_ctx_pkg INITIALIZED EXTERNALLY;
10.3.10.5 中間層サーバーからのアプリケーション・コンテキスト値の初期化
中間層サーバーは、データベース・ユーザーのかわりにアプリケーション・コンテキスト値を初期化できます。
このプロセスでは、コンテキスト属性が初期化時にリモート・セッションに対して伝播され、ネームスペースが外部で初期化されている場合、リモート・データベースはこれらの値を受け入れます。
たとえば、OCIまたはJDBC/OCI経由の軽量ユーザー・セッションを作成する3層アプリケーションの場合は、USERENVの
PROXY_USER
属性にアクセスできます。この属性を使用すると、ユーザー・セッションが中間層アプリケーションによって作成されたかどうかを判断できます。ユーザーがデータへのアクセスを許可されるのは、そのユーザーがプロキシ化されている接続に対してのみです。ユーザーがデータベースに直接接続している場合、そのユーザーはどのデータにもアクセスできません。
Oracle Virtual Private Database内のUSERENV
ネームスペースからPROXY_USER
属性を使用すると、ユーザーによるデータへのアクセスを特定の中間層アプリケーションを経由した場合のみに制限できます。他の方法では、セキュア・アプリケーション・ロールを作成し、ユーザーは特定のプロキシ経由でのみデータベースにアクセスするというポリシーを規定できます。
関連項目:
-
プロキシ認証の詳細および
USERENV
属性CLIENT_IDENTIFIER
を使用して複数層にわたってユーザー識別情報を保持する方法は、複数層環境でのユーザー識別情報の保持を参照してください -
セキュア・アプリケーション・ロールを使用して特定のプロキシを経由するようにポリシーを実施する方法は、プロキシ認証に対する中間層サーバーの使用を参照してください
10.3.11 データベース・セッション・ベースのアプリケーション・コンテキストのグローバルな初期化
データベース・セッション・ベースのアプリケーションが集中格納場所に格納されている場合、そのアプリケーションはLDAPディレクトリ全域から使用できます。
- データベース・セッション・ベースのアプリケーション・コンテキストのグローバルな初期化について
ユーザーのデータベース・セッション・ベースのアプリケーション・コンテキストは、集中格納場所を使用して格納できます。 - LDAPでのデータベース・セッション・ベースのアプリケーション・コンテキストの使用
グローバルに初期化されたアプリケーション・コンテキストは、拡張可能で効率的な標準ディレクトリ・アクセス・プロトコルであるLDAPを使用します。 - グローバルに初期化されたデータベース・セッション・ベースのアプリケーション・コンテキストの動作
グローバルに初期化されたセキュア・アプリケーションを使用するには、エンタープライズ・ユーザー・セキュリティを最初に構成する必要があります。 - データベース・セッション・ベースのアプリケーション・コンテキストのグローバルな初期化
ユーザーの初期アプリケーション・コンテキスト(部門名や職位など)は、LDAPディレクトリに設定および格納できます。
10.3.11.1 データベース・セッション・ベースのアプリケーション・コンテキストのグローバルな初期化について
ユーザーのデータベース・セッション・ベースのアプリケーション・コンテキストは、集中格納場所を使用して格納できます。
集中格納場所を使用することでアプリケーションでは、初期化中にユーザーの識別情報に基づいてユーザー・コンテキストを設定できます。
特に、この機能では、Oracle Label Securityのラベルと権限がサポートされます。アプリケーション・コンテキストをグローバルに初期化すると、多数のユーザーとデータベースのコンテキストを簡単に管理できます。
たとえば、多くの組織では、LDAPベースのディレクトリでユーザー情報を集中管理する必要があります。エンタープライズ・ユーザー・セキュリティは、Oracle Internet Directoryでのユーザーと認可の集中管理をサポートします。ただし、Oracle Virtual Private Databaseの規定に使用するために、アプリケーションではLightweight Directory Access Protocol(LDAP)から追加の属性(ユーザーの職位、組織、物理的な位置など)を取得することが必要な場合があります。これらのタイプの属性は、アプリケーション・コンテキストをグローバルに初期化することで取得できます。
10.3.11.2 LDAPでのデータベース・セッション・ベースのアプリケーション・コンテキストの使用
グローバルに初期化されたアプリケーション・コンテキストは、拡張可能で効率的な標準ディレクトリ・アクセス・プロトコルであるLDAPを使用します。
LDAPディレクトリには、このアプリケーションが割り当てられているユーザーのリストが格納されます。Oracle Databaseでは、ディレクトリ・サービス(通常はOracle Internet Directory)を使用して、エンタープライズ・ユーザーを認証および認可します。
ノート:
Microsoft Active DirectoryやSun MicrosystemsのSunONEなどのサード・パーティ製ディレクトリもディレクトリ・サービスとして使用できます。
orclDBApplicationContext
LDAPオブジェクト(groupOfUniqueNames
のサブクラス)は、アプリケーション・コンテキスト値をディレクトリに格納します。アプリケーション・コンテキスト・オブジェクトの場所は、Human Resourcesの例に基づく図10-1で説明しています。
LDAPオブジェクトinetOrgPerson
により、一部の属性では複数のエントリが存在可能です。ただし、これらのエントリがデータベースにロードされ、SYS_LDAP_USER_DEFAULT
コンテキスト・ネームスペースでアクセスされると、これらのエントリのうちの最初のエントリのみが返されます。たとえば、ユーザーに対するinetOrgPerson
オブジェクトでは、telephoneNumber
に複数のエントリが可能です(そのため、ユーザーは複数の電話番号を保存できます)。SYS_LDAP_USER_DEFAULT
コンテキスト・ネームスペースを使用すると、最初の電話番号だけが取得されます。提供された属性と値のリストが要求に関して十分でない場合は、DBMS_LDAP
PL/SQLパッケージを使用してディレクトリから追加の値をフェッチできます。
LDAP側では、アプリケーション・コンテキスト値のリストをデータベースに返すorclDBApplicationContext
値を取得するための内部C関数が必要になります。この例では、HR
はネームスペース、Title
とProject
は属性、Manager
とPromotion
は値です。
10.3.11.3 グローバルに初期化されたデータベース・セッション・ベースのアプリケーション・コンテキストの動作
グローバルに初期化されたセキュア・アプリケーションを使用するには、エンタープライズ・ユーザー・セキュリティを最初に構成する必要があります。
次に、データベースとディレクトリのユーザーに対してアプリケーション・コンテキスト値を構成します。
グローバル・ユーザー(エンタープライズ・ユーザー)がデータベースに接続すると、エンタープライズ・ユーザー・セキュリティ機能によって、データベースに接続しているユーザーの識別情報が検証されます。認証後、グローバル・ユーザー・ロールとアプリケーション・コンテキストがディレクトリから取得されます。ユーザーがデータベースにログインするときは、グローバル・ロールと初期アプリケーション・コンテキストがすでに設定されています。
関連項目:
エンタープライズ・ユーザー・セキュリティの構成の詳細は、『Oracle Databaseエンタープライズ・ユーザー・セキュリティ管理者ガイド』を参照してください。
10.3.12 外部化されたデータベース・セッション・ベースのアプリケーション・コンテキスト
多くのアプリケーションでは、ファイングレイン・アクセス・コントロールに使用される属性をデータベース・メタデータ表に格納します。
たとえば、employees
表に、コスト・センター、職責、署名認証などのファイングレイン・アクセス・コントロールに有効な情報を含めることができます。ただし、多くの組織ではユーザー情報をOracle Internet DirectoryなどのLDAPベースのディレクトリに集中化して、ユーザーを管理し、アクセス制御しています。アプリケーション・コンテキスト属性は、Oracle Internet Directoryに格納して1人以上のエンタープライズ・ユーザーに割り当てることができます。また、これらの属性は、エンタープライズ・ユーザーがログインすると自動的に取得され、アプリケーション・コンテキストの初期化にも使用されます。
関連項目:
-
OCIインタフェース、ジョブ・キュー・プロセスまたはデータベース・リンクなど、外部リソースを介したローカル・アプリケーション・コンテキストの初期化に関する詳細は、データベース・セッション・ベースのアプリケーション・コンテキストの外部での初期化を参照してください
-
Oracle Internet Directoryなどの集中化されたリソースを介したローカル・アプリケーション・コンテキストの初期化に関する詳細は、データベース・セッション・ベースのアプリケーション・コンテキストのグローバルな初期化を参照してください
-
エンタープライズ・ユーザーの詳細は、『Oracle Databaseエンタープライズ・ユーザー・セキュリティ管理者ガイド』を参照してください。
10.4 グローバル・アプリケーション・コンテキスト
グローバル・アプリケーション・コンテキストを使用して、Oracle Real Application Clusters環境などのデータベース・セッション間でアプリケーション値にアクセスできます。
- グローバル・アプリケーション・コンテキストについて
グローバル・アプリケーション・コンテキストを使用すると、アプリケーション・コンテキスト値を複数のデータベース・セッション(Oracle RACインスタンスを含む)にわたってアクセス可能にできます。 - グローバル・アプリケーション・コンテキストの使用方法
グローバル・アプリケーション・コンテキストには、3種類の一般的な使用方法があります。 - グローバル・アプリケーション・コンテキストのコンポーネント
グローバル・アプリケーション・コンテキストはパッケージを使用して属性を管理し、中間層アプリケーションを使用してクライアント・セッションIDを管理します。 - Oracle Real Application Clusters環境でのグローバル・アプリケーション・コンテキスト
Oracle RAC環境では、グローバル・アプリケーション・コンテキストがロードまたは変更された場合は、常に、既存のアクティブ・インスタンスによってのみ、そのことが認識されます。 - グローバル・アプリケーション・コンテキストの作成
CREATE CONTEXT
SQL文によって作成されたグローバル・アプリケーション・コンテキストはSYS
スキーマに配置されます。 - グローバル・アプリケーション・コンテキストを管理するためのPL/SQLパッケージ
DBMS_SESSION
PL/SQLパッケージで、グローバル・アプリケーション・コンテキストを管理します。 - クライアント・セッションIDを管理するための中間層アプリケーションへのコールの埋込み
中間層アプリケーションにコールを埋め込み、クライアント・セッションIDを管理できます。 - 例: クライアント・セッションIDを使用するグローバル・アプリケーション・コンテキストの作成
このチュートリアルでは、クライアント・セッションIDを使用するグローバル・アプリケーション・コンテキストの作成を示しています。 - グローバル・アプリケーション・コンテキスト・プロセス
簡単なグローバル・アプリケーション・コンテキストはデータベース・ユーザー・アカウントを使用し、ユーザー・セッションを作成します。グローバル・アプリケーション・コンテキストは軽量ユーザー用です。
10.4.1 グローバル・アプリケーション・コンテキストについて
グローバル・アプリケーション・コンテキストを使用すると、アプリケーション・コンテキスト値を複数のデータベース・セッション(Oracle RACインスタンスを含む)にわたってアクセス可能にできます。
グローバル・アプリケーション・コンテキスト情報はシステム・グローバル領域(SGA: 共有グローバル領域でSGAと称する場合もあります)に格納されるため、3層アーキテクチャの中間層アプリケーションなど、セッションを使用しないアプリケーションに対して使用できます。
このようなアプリケーションでは、複数のユーザーがアプリケーションに対して認証され、通常は単一の識別情報としてデータベースに接続するため、セッション・ベースのアプリケーション・コンテキストを使用できません。グローバル・アプリケーション・コンテキストは、ユーザー・セッション単位ではなく一度に初期化されます。したがって、接続は接続プールから再利用されるため、パフォーマンスが向上します。
グローバル・アプリケーション・コンテキスト値は、ALTER SYSTEM FLUSH GLOBAL_CONTEXT
SQL文を実行してクリアできます。
親トピック: グローバル・アプリケーション・コンテキスト
10.4.2 グローバル・アプリケーション・コンテキストの使用方法
グローバル・アプリケーション・コンテキストには、3種類の一般的な使用方法があります。
使用方法は次のとおりです。
-
全データベース・ユーザーを対象にしてアプリケーションの値をグローバルに共有する必要がある場合。たとえば、特定の状況に基づいてアプリケーションへのアクセスを禁止することがあります。この場合、アプリケーション・コンテキストが設定する値はユーザーに固有の値ではなく、ユーザーのプライベート・データに基づく値でもありません。アプリケーション・コンテキストは、ある状況を定義して、実行中のアプリケーション・モジュールのバージョンなどを示します。
-
複数のアプリケーション間を移動する必要があるデータベース・ユーザーがいる場合。この場合、ユーザーの移動先となる第2のアプリケーションには、第1のアプリケーションとは異なるアクセス要件があります。
-
非データベース・ユーザー(つまり、データベースに認識されていないユーザー)を認証する必要がある場合。データベース・アカウントを持たないこのタイプのユーザーは、通常、Webアプリケーション経由で接続プールを使用して接続します。このようなアプリケーションでは、One Big Application User認証モデルを使用して、複数のユーザーを単一のユーザーとしてデータベースに接続します。このタイプのユーザーを認証するには、そのユーザーのクライアント・セッションIDを使用します。
親トピック: グローバル・アプリケーション・コンテキスト
10.4.3 グローバル・アプリケーション・コンテキストのコンポーネント
グローバル・アプリケーション・コンテキストはパッケージを使用して属性を管理し、中間層アプリケーションを使用してクライアント・セッション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
設定で値を上書きできることに注意してください。
10.4.4 Oracle Real Application Clusters環境でのグローバル・アプリケーション・コンテキスト
Oracle RAC環境では、グローバル・アプリケーション・コンテキストがロードまたは変更された場合は、常に、既存のアクティブ・インスタンスによってのみ、そのことが認識されます。
Oracle RAC環境でグローバル・アプリケーション・コンテキスト値を設定すると、コンテキスト値をすべてのOracle RACインスタンスに一貫して伝播することによるパフォーマンスのオーバーヘッドが生じることに注意してください。
1つのOracle RACインスタンスでグローバル・アプリケーション・コンテキストをフラッシュすると(ALTER SYSTEM FLUSH GLOBAL_CONTEXT
SQL文を使用して)、他のすべてのOracle RACインスタンスでも、すべてのグローバル・アプリケーション・コンテキストがフラッシュされます。
親トピック: グローバル・アプリケーション・コンテキスト
10.4.5 グローバル・アプリケーション・コンテキストの作成
CREATE CONTEXT
SQL文によって作成されたグローバル・アプリケーション・コンテキストはSYS
スキーマに配置されます。
- グローバル・アプリケーション・コンテキストの所有権
グローバル・アプリケーション・コンテキストを所有できるのはSYS
スキーマのみです。 - グローバル・アプリケーション・コンテキストの作成
ローカル・アプリケーション・コンテキストと同様、グローバル・アプリケーション・コンテキストもセキュリティ管理者のデータベース・スキーマで作成および格納されます。
親トピック: グローバル・アプリケーション・コンテキスト
10.4.5.1 グローバル・アプリケーション・コンテキストの所有権
グローバル・アプリケーション・コンテキストを所有できるのはSYS
スキーマのみです。
グローバル・アプリケーション・コンテキストの所有権については、CREATE ANY CONTEXT
権限とDROP ANY CONTEXT
権限を付与されたユーザーがそのグローバル・アプリケーション・コンテキストを作成および削除できた場合でも、SYS
スキーマが所有しています。
Oracle Databaseは、作成したスキーマ・アカウントにコンテキストを関連付けますが、このユーザーを削除した場合、コンテキストはそれでもSYS
スキーマの中に存在します。ユーザーSYS
であれば、アプリケーション・コンテキストを削除できます。
親トピック: グローバル・アプリケーション・コンテキストの作成
10.4.5.2 グローバル・アプリケーション・コンテキストの作成
ローカル・アプリケーション・コンテキストと同様、グローバル・アプリケーション・コンテキストもセキュリティ管理者のデータベース・スキーマで作成および格納されます。
グローバル・アプリケーション・コンテキストを作成するには、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 CONTAINER = ALL;
親トピック: グローバル・アプリケーション・コンテキストの作成
10.4.6 グローバル・アプリケーション・コンテキストを管理するためのPL/SQLパッケージ
DBMS_SESSION
PL/SQLパッケージで、グローバル・アプリケーション・コンテキストを管理します。
- グローバル・アプリケーション・コンテキストを管理するパッケージについて
グローバル・アプリケーション・コンテキストに関連付けるパッケージは、DBMS_SESSION
パッケージを使用してグローバル・アプリケーション・コンテキスト値の設定とクリアを行います。 - エディションがグローバル・アプリケーション・コンテキストのPL/SQLパッケージの結果に与える影響
グローバル・アプリケーション・コンテキストのパッケージ、Oracle Virtual Private Databaseのパッケージ、およびファイングレイン監査ポリシーは、複数のエディションで使用できます。 - DBMS_SESSION.SET_CONTEXTのusernameおよびclient_idパラメータ
DBMS_SESSION.SYS_CONTEXT
プロシージャには、グローバル・アプリケーション・コンテキストに使用するclient_id
およびusername
パラメータが用意されています。 - 全データベース・ユーザーを対象としたグローバル・アプリケーション・コンテキスト値の共有
全データベース・ユーザーを対象としてグローバル・アプリケーション値を共有して、データベース内のデータへのアクセス権を付与できます。 - 例: 全データベース・ユーザーを対象としてグローバル・アプリケーション値を管理するためのパッケージ
CREATE PACKAGE
文で、全データベース・ユーザーを対象としてグローバル・アプリケーション値を管理できます。 - アプリケーション間を移動するデータベース・ユーザーのグローバル・コンテキスト
アプリケーションによってアクセス要件が異なる場合でも、アプリケーション間を移動するデータベース・ユーザーにグローバル・アプリケーション・コンテキストを使用できます。 - 非データベース・ユーザーのグローバル・アプリケーション・コンテキスト
非データベース・ユーザーがクライアント・セッションを開始すると、アプリケーション・サーバーでクライアント・セッションIDが生成されます。 - 例: 非データベース・ユーザーのグローバル・アプリケーション・コンテキスト値を管理するためのパッケージ
CREATE PACKAGE
文で、非データベース・ユーザーのグローバル・アプリケーション・コンテキスト値を管理できます。 - セッションをクローズする際のセッション・データのクリア
アプリケーション・コンテキストはメモリー内に存在するので、ユーザーがセッションを終了したときは、client_identifier
コンテキスト値をクリアする必要があります。
親トピック: グローバル・アプリケーション・コンテキスト
10.4.6.1 グローバル・アプリケーション・コンテキストを管理するパッケージについて
グローバル・アプリケーション・コンテキストに関連付けるパッケージは、DBMS_SESSION
パッケージを使用してグローバル・アプリケーション・コンテキスト値の設定とクリアを行います。
このプロシージャを使用するには、DBMS_SESSION
パッケージに対するEXECUTE
権限が必要です。通常、このパッケージはセキュリティ管理者のデータベース・スキーマに作成および格納されます。DBMS_SESSION
パッケージはSYS
スキーマの所有です。
ローカル・アプリケーション・コンテキストの設定に使用するPL/SQLパッケージとは異なり、ユーザー・セッション・データを取得するSYS_CONTEXT
関数は挿入しません。グローバル・アプリケーション・コンテキストでは、接続しているすべてのユーザーにとって、セッションの所有者(USERENV
コンテキストに記録される)は同じ所有者となるため、この関数を挿入する必要はありません。
プロシージャは、グローバル・アプリケーション・コンテキストのPL/SQLパッケージ内でいつでも実行できます。グローバル・アプリケーション・コンテキストに関連付けられているパッケージ・プロシージャを実行するために、ログイン・トリガーとログオフ・トリガーを作成する必要はありません。一般的に、パッケージ・プロシージャはデータベース・アプリケーション内から実行します。また、非データベース・ユーザーには、中間層アプリケーションを使用してクライアント・セッションIDを取得および設定します。
関連項目:
DBMS_SESSION
パッケージの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。
10.4.6.2 エディションがグローバル・アプリケーション・コンテキストの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開発ガイド』を参照してください。
-
10.4.6.3 DBMS_SESSION.SET_CONTEXTのusernameおよびclient_idパラメータ
DBMS_SESSION.SYS_CONTEXT
プロシージャには、グローバル・アプリケーション・コンテキストに使用するclient_id
およびusername
パラメータが用意されています。
これらの設定の組合せによって、作成可能なグローバル・アプリケーション・コンテキストのタイプがどのように制御されるかについて、表10-2で説明します。
表10-2 DBMS_SESSION.SET_CONTEXTのusernameおよびclient_idパラメータの設定
設定の組合せ | 結果 |
---|---|
|
この組合せでは、すべてのユーザーがアプリケーション・コンテキストにアクセスできます。詳細は、「全データベース・ユーザーを対象としたグローバル・アプリケーション・コンテキスト値の共有」を参照してください。 これらの設定は、データベース・セッション・ベースのアプリケーション・コンテキストにも使用されます。詳細は、「データベース・セッション・ベースのアプリケーション・コンテキストの使用」を参照してください。 |
|
この組合せでは、 |
|
この組合せでは、 |
|
この組合せでは、次の2つの場合が考えられます。
詳細は、「非データベース・ユーザーのグローバル・アプリケーション・コンテキスト」を参照してください。 |
10.4.6.4 全データベース・ユーザーを対象としたグローバル・アプリケーション・コンテキスト値の共有
全データベース・ユーザーを対象としてグローバル・アプリケーション値を共有して、データベース内のデータへのアクセス権を付与できます。
-
全データベース・ユーザーを対象としてグローバル・アプリケーションの値を共有するには、
SET_CONTEXT
プロシージャのnamespace
、attribute
およびvalue
パラメータを設定します。
10.4.6.5 例: 全データベース・ユーザーを対象としてグローバル・アプリケーション値を管理するためのパッケージ
CREATE PACKAGE
文で、全データベース・ユーザーを対象としてグローバル・アプリケーション値を管理できます。
例10-7に、全データベース・ユーザーを対象としてグローバル・アプリケーション・コンテキストを設定およびクリアするパッケージの作成方法を示します。
例10-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;
10.4.6.6 アプリケーション間を移動するデータベース・ユーザーのグローバル・コンテキスト
アプリケーションによってアクセス要件が異なる場合でも、アプリケーション間を移動するデータベース・ユーザーにグローバル・アプリケーション・コンテキストを使用できます。
これを行うには、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ポリシーを使用してユーザー・アクセスを制御するアプリケーション一式を保持できます。
例10-8に、特定のユーザーが複数のアプリケーション間を移動できるように、username
パラメータを設定する方法を示します。username
パラメータを使用している部分は、boldで記載しています。
例10-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
権限を指定する必要があります。つまり、アプリケーション(ユーザーではなく)がユーザーのコンテキストを設定します。
10.4.6.7 非データベース・ユーザーのグローバル・アプリケーション・コンテキスト
非データベース・ユーザーがクライアント・セッションを開始すると、アプリケーション・サーバーでクライアント・セッション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
10.4.6.8 例: 非データベース・ユーザーのグローバル・アプリケーション・コンテキスト値を管理するためのパッケージ
CREATE PACKAGE
文で、非データベース・ユーザーのグローバル・アプリケーション・コンテキスト値を管理できます。
例10-9に、このタイプのグローバル・アプリケーション・コンテキストを管理するパッケージの作成方法を示します。
例10-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
変数によって定義された現行のユーザー・セッションのコンテキスト設定を消去します。詳細は、「セッションをクローズする際のセッション・データのクリア」を参照してください。
10.4.6.9 セッションをクローズする際のセッション・データのクリア
アプリケーション・コンテキストはメモリー内に存在するので、ユーザーがセッションを終了したときは、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
ファンクションによって値を取得する後続のコールでは、最新の値が戻されます。
-
10.4.7 クライアント・セッションIDを管理するための中間層アプリケーションへのコールの埋込み
中間層アプリケーションにコールを埋め込み、クライアント・セッションIDを管理できます。
- 中間層アプリケーションを使用したクライアント・セッションIDの管理について
アプリケーション・サーバーはクライアント・セッションIDを生成します。 - ステップ1: 中間層アプリケーションを使用したクライアント・セッションIDの取得
ユーザーがクライアント・セッションを開始すると、アプリケーション・サーバーでクライアント・セッションIDが生成されます。 - ステップ2: 中間層アプリケーションを使用したクライアント・セッションIDの設定
次に、中間層アプリケーションを使用してクライアント・セッションIDを設定します。 - ステップ3: 中間層アプリケーションを使用したセッション・データのクリア
アプリケーション・コンテキストは、すべてがメモリー内に存在します。
親トピック: グローバル・アプリケーション・コンテキスト
10.4.7.1 中間層アプリケーションを使用したクライアント・セッションIDの管理について
アプリケーション・サーバーはクライアント・セッションIDを生成します。
中間層アプリケーションから、クライアント・セッションIDを取得、設定、およびクリアできます。そのために、Oracle Call Interface (OCI)コールとDBMS_SESSION
PL/SQLパッケージ・プロシージャのどちらかを中間層アプリケーション・コードに埋め込むことができます。
アプリケーションによってユーザーが認証され、クライアント識別子が設定されてカレント・セッションに設定されます。PL/SQLパッケージSET_CONTEXT
によって、アプリケーション・コンテキストにclient_identifier
値が設定されます。
10.4.7.2 ステップ1: 中間層アプリケーションを使用したクライアント・セッションIDの取得
ユーザーがクライアント・セッションを開始すると、アプリケーション・サーバーでクライアント・セッション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に書式を設定した出力を表示します。
10.4.7.3 ステップ2: 中間層アプリケーションを使用したクライアント・セッションIDの設定
次に、中間層アプリケーションを使用してクライアント・セッションIDを設定します。
- 中間層アプリケーションを使用したクライアント・セッションIDの設定について
OCIStmtExecute
コールを使用してクライアント・セッションIDを取得した後は、このIDを設定できます。 - 中間層アプリケーションを使用したクライアント・セッションIDの設定
Oracle Call InterfaceまたはDBMS_SESSION
PL/SQLパッケージによって、中間層アプリケーションを使用してクライアント・セッションIDを設定できます。 - クライアント識別子の値のチェック
OCIAttrSet
およびDBMS_SESSION.SET_IDENTIFIER
では、クライアント識別子の値をチェックできます。
10.4.7.3.1 中間層アプリケーションを使用したクライアント・セッション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を設定します。この設定によって、セッションは異なるグローバル・アプリケーション・コンテキストの値セットを使用するようになります。
10.4.7.3.2 中間層アプリケーションを使用したクライアント・セッション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のネイティブ・ネットワーク暗号化とデータ整合性の構成を参照してください。
10.4.7.4 ステップ3: 中間層アプリケーションを使用したセッション・データのクリア
アプリケーション・コンテキストは、すべてがメモリー内に存在します。
ユーザーがセッションを終了したときは、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
を使用してください。
-
10.4.8 例: クライアント・セッションIDを使用するグローバル・アプリケーション・コンテキストの作成
このチュートリアルでは、クライアント・セッションIDを使用するグローバル・アプリケーション・コンテキストの作成を示しています。
- このチュートリアルについて
この例は、軽量ユーザーのアプリケーション用にクライアント・セッションIDを使用するグローバル・アプリケーション・コンテキストを作成する方法を示しています。 - ステップ1: ユーザー・アカウントの作成
セキュリティ管理者はアプリケーション・コンテキストおよびそのパッケージを管理し、ユーザー・アカウントは接続プールを所有します。 - ステップ2: グローバル・アプリケーション・コンテキストの作成
次に、グローバル・アプリケーション・コンテキストを作成します。 - ステップ3: グローバル・アプリケーション・コンテキストのパッケージの作成
PL/SQLパッケージは、作成したグローバル・アプリケーション・コンテキストを管理します。 - ステップ4: 新規作成したグローバル・アプリケーション・コンテキストのテスト
この時点で、このグローバル・アプリケーション・コンテキストとセッションIDの設定について動作を確認します。 - ステップ5: セッションIDの変更とグローバル・アプリケーション・コンテキストの再テスト
次に、セッションIDをクリアして変更し、グローバル・アプリケーション・コンテキストを再テストします。 - ステップ6: このチュートリアルのコンポーネントの削除
このチュートリアルのコンポーネントが不要になった場合、それらを削除できます。
親トピック: グローバル・アプリケーション・コンテキスト
10.4.8.1 このチュートリアルについて
この例は、軽量ユーザーのアプリケーション用にクライアント・セッションIDを使用するグローバル・アプリケーション・コンテキストを作成する方法を示しています。
非データベース・ユーザーの接続プールを使用したアクセスを制御する方法を示しています。マルチテナント環境を使用している場合、このチュートリアルは現在のPDBのみに適用されます。
10.4.8.5 ステップ4: 新規作成したグローバル・アプリケーション・コンテキストのテスト
この時点で、このグローバル・アプリケーション・コンテキストとセッション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 ------------- --------------
10.4.8.6 ステップ5: セッションIDの変更とグローバル・アプリケーション・コンテキストの再テスト
次に、セッションIDをクリアして変更し、グローバル・アプリケーション・コンテキストを再テストします。
10.4.9 グローバル・アプリケーション・コンテキスト・プロセス
簡単なグローバル・アプリケーション・コンテキストはデータベース・ユーザー・アカウントを使用し、ユーザー・セッションを作成します。グローバル・アプリケーション・コンテキストは軽量ユーザー用です。
- 単純なグローバル・アプリケーション・コンテキスト・プロセス
簡単なグローバル・アプリケーション・コンテキストのプロセスでは、アプリケーションは、データベース・ユーザーを使用してユーザー・セッションを作成します。 - 軽量ユーザー用のグローバル・アプリケーション・コンテキスト・プロセス
軽量ユーザーにグローバル・アプリケーション・コンテキストを設定できます。
親トピック: グローバル・アプリケーション・コンテキスト
10.4.9.1 単純なグローバル・アプリケーション・コンテキスト・プロセス
簡単なグローバル・アプリケーション・コンテキストのプロセスでは、アプリケーションは、データベース・ユーザーを使用してユーザー・セッションを作成します。
単純なグローバル・アプリケーション・コンテキスト・プロセスのコンテキスト属性の値は、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
のアプリケーション・コンテキストのみが取得されます。
親トピック: グローバル・アプリケーション・コンテキスト・プロセス
10.4.9.2 軽量ユーザー用のグローバル・アプリケーション・コンテキスト・プロセス
軽量ユーザーにグローバル・アプリケーション・コンテキストを設定できます。
このアクセスは、他のユーザーがログイン時にグローバル・アプリケーション・コンテキストにアクセスできないように構成できます。
次のステップは、軽量ユーザー・アプリケーション用のグローバル・アプリケーション・コンテキスト・プロセスを示しています。軽量ユーザー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
の使用の詳細は、次を参照してください。
親トピック: グローバル・アプリケーション・コンテキスト・プロセス
10.5 クライアント・セッション・ベースのアプリケーション・コンテキストの使用
クライアント・セッション・ベースのアプリケーション・コンテキストは、ユーザー・グローバル領域(UGA)に格納されます。
- クライアント・セッション・ベースのアプリケーション・コンテキストについて
Oracle Call Interface (OCI)関数で、ユーザー・グローバル領域(UGA)のユーザー・セッション情報を設定およびクリアできます。 - CLIENTCONTEXTネームスペースへの値の設定
Oracle Call Interface (OCI)で、CLIENTCONTEXT
ネームスペースを設定できます。 - CLIENTCONTEXTネームスペースの取得
Oracle Call Interfaceを使用して、CLIEINTCONTEXT
ネームスペースを取得できます。 - 例: クライアント・セッション・ベース・コンテキストのクライアント・セッションID値の取得
OCIOCIStmtExecute
コールで、クライアント・セッション・ベース・コンテキストのクライアント・セッションID値を取得できます。 - CLIENTCONTEXTネームスペースの設定のクリア
Oracle Call Interfaceを使用して、CLIENTCONTEXT
ネームスペースをクリアできます。 - CLIENTCONTEXTネームスペースのすべての設定のクリア
Oracle Call Interface (OCI)を使用して、CLIENTCONTEXT
ネームスペースをクリアできます。
10.5.1 クライアント・セッション・ベースのアプリケーション・コンテキストについて
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プログラマーズ・ガイド』を参照してください。
10.5.2 CLIENTCONTEXTネームスペースへの値の設定
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
を指定します。
10.5.3 CLIENTCONTEXTネームスペースの取得
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コードに埋め込んで属性値を設定できます。
10.5.4 例: クライアント・セッション・ベース・コンテキストのクライアント・セッションID値の取得
OCI OCIStmtExecute
コールで、クライアント・セッション・ベース・コンテキストのクライアント・セッションID値を取得できます。
例10-10に、OCIStmtExecute
コールを使用してクライアント・セッションIDを取得する方法を示します。
例10-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に書式を設定した出力を表示します。
10.5.5 CLIENTCONTEXTネームスペースの設定のクリア
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);
-
10.6 アプリケーション・コンテキストのデータ・ディクショナリ・ビュー
Oracle Databaseには、アプリケーション・コンテキストに関する情報を提供するデータ・ディクショナリ・ビューが用意されています。
表10-3に、これらのデータ・ディクショナリ・ビューを示します。
表10-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リファレンスを参照してください。