【PL/SQL】セキュリティコンテキスト(DBMS_SESSION.SET_CONTEXT)の利用例

【PL/SQL】セキュリティコンテキスト(DBMS_SESSION.SET_CONTEXT)の利用例 PL/SQL

アプリケーションとデータベースを連携させる際、ユーザーごとに異なる条件でアクセス制御をしたい場面があります。PL/SQLでは「セキュリティコンテキスト」を活用することで、セッション単位で任意の値を格納し、その値に基づいたアクセス制御や条件分岐を実現できます。代表的にはDBMS_SESSION.SET_CONTEXTを使った実装があり、行レベルセキュリティ(VPD)やアプリケーションロジックの切り替えなどに利用されます。

セキュリティコンテキストの基本

セキュリティコンテキストとは「アプリケーションごとの属性をセッションに保持する仕組み」です。まずコンテキストを格納する「コンテキスト名前空間」を作成し、その後PL/SQLから値をセット・参照します。名前空間はDBAがCREATE CONTEXTで定義します。

-- 名前空間の作成(アプリケーション単位)
CREATE CONTEXT app_ctx USING set_app_ctx_pkg;

ここでset_app_ctx_pkgは後述する「値をセットするためのパッケージ」です。

DBMS_SESSION.SET_CONTEXTの使い方

値の格納はDBMS_SESSION.SET_CONTEXTを使います。形式は以下のとおりです。

DBMS_SESSION.SET_CONTEXT(
  namespace  => 'APP_CTX',
  attribute  => 'USER_ROLE',
  value      => 'ADMIN'
);

namespaceはCREATE CONTEXTで定義した名前空間、attributeはキー名、valueは格納する値です。セッション内でのみ有効です。

実装例:ユーザー権限に応じた条件分岐

アプリケーションログイン時にユーザーの権限をコンテキストへ設定し、後続処理で利用する例を示します。

-- 値をセットする専用パッケージ
CREATE OR REPLACE PACKAGE set_app_ctx_pkg IS
  PROCEDURE set_role(p_user IN VARCHAR2);
END;
/

CREATE OR REPLACE PACKAGE BODY set_app_ctx_pkg IS
  PROCEDURE set_role(p_user IN VARCHAR2) IS
    v_role VARCHAR2(20);
  BEGIN
    -- ここでユーザーテーブルから権限を取得
    SELECT role INTO v_role FROM app_users WHERE username = p_user;
    DBMS_SESSION.SET_CONTEXT('APP_CTX', 'USER_ROLE', v_role);
  END;
END;
/

ログイン処理時にset_app_ctx_pkg.set_role(:username)を呼び出せば、そのセッションではUSER_ROLEの値が保持されます。

利用例:ファンクション内での参照

格納した値はSYS_CONTEXTで参照できます。SYS_CONTEXTはnamespaceとattributeを引数にして値を返します。

CREATE OR REPLACE FUNCTION can_access(p_data_owner VARCHAR2)
RETURN VARCHAR2
IS
  v_role VARCHAR2(20);
BEGIN
  v_role := SYS_CONTEXT('APP_CTX', 'USER_ROLE');
  IF v_role = 'ADMIN' OR v_role = p_data_owner THEN
    RETURN 'ALLOW';
  ELSE
    RETURN 'DENY';
  END IF;
END;
/

これによりSQL文中で柔軟なアクセス制御を行えます。

行レベルセキュリティ(VPD)との連携

セキュリティコンテキストはVPD(Virtual Private Database)の行レベルポリシーでも使われます。DBMS_RLS.ADD_POLICYでポリシーを定義する際、SYS_CONTEXTを参照することで「ユーザー属性に応じた行制御」を実現できます。

BEGIN
  DBMS_RLS.ADD_POLICY(
    object_schema   => 'HR',
    object_name     => 'EMPLOYEES',
    policy_name     => 'emp_rls',
    function_schema => 'HR',
    policy_function => 'emp_rls_func'
  );
END;
/

このemp_rls_func内でSYS_CONTEXT(‘APP_CTX’,’USER_ROLE’)を参照し、WHERE句を返すことで行単位の制御が可能です。

まとめ

DBMS_SESSION.SET_CONTEXTを使ったセキュリティコンテキストは、アプリケーションログイン時にユーザー情報や権限をセッションに保持し、それをSQLやPL/SQLで参照することで柔軟な制御を可能にします。SYS_CONTEXTで簡単に参照できるため、アクセス制御・機能制御・ログ出力など幅広い用途で活用できます。特にVPDと組み合わせると強力なセキュリティ基盤となるため、セキュリティ要件が高いシステムでは積極的に活用する価値があります。