オラクル 行レベルのセキュリティ

問題の紹介



現在、どの組織でも、ユーザーに関する特定の知識に基づいて情報へのアクセスが区別されています。 このような知識は、組織内でのユーザーの役割、ユーザーの位置、またはユーザーが働く構造単位になります。 多くの人は、アクセスを制限する問題は、ユーザー名、テーブル、ビュー、トリガーに基づいた単純なメカニズムを使用して解決できることを知っています。



例を考えてみましょう:

組織の顧客に関する情報をマネージャーに提供します。 同時に、マネージャーは自分の構造単位の顧客のみを表示できますが、会社全体は表示できません。



create table clients ( clientid integer, clientname varchar2(30), clientphone varchar2(7), clientoffice integer );
      
      







「額の」解決策は、会社の各部門に個別のプレゼンテーションを作成することです。 例:



 create or replace view clients_10 as select clientid, clientname, clientphone from clients where clientoffice = 10;
      
      







したがって、ビューの数を等しく維持する必要があります

<number_ofiltrable_tables> * <number_of Structural_departments>

また、各ユーザーを必要なデータに「送信」します。 愚かな退屈な職業。

前の例を改善してみましょう。



 create or replace view v_clients as select clientid, clientname, clietnphone from office where clientoffice = (select useroffice from users where username = user);
      
      







このソリューションは間違いなくより興味深いものですが、1人のユーザーが複数の部門のクライアントを「見る」必要がある場合はどうすればよいでしょうか。 また、1人のユーザーが1つのテーブルからのデータのリクエストのみを許可され、別のユーザーはまだ編集はできるが削除はできず、3番目のビューと削除では許可される場合がよくあります。 無数のビュー、トリガー、および調整テーブルを作成するのは非常に不便になっています...



RLSテクノロジー



RLSテクノロジ( 行レベルセキュリティまたは行レベルセキュリティ )は、ユーザーがデータベース内の情報にアクセスすることを制限するセキュリティポリシーを作成する機能を提供します。 前述のように、セキュリティポリシーを使用すると、情報の全体または一部を「閉じる」ことも、特定の操作のみを許可することもできます。 このテクノロジーはOracle 8iで初めて導入されましたが、将来のバージョンではその機能が大幅に拡張されました。

データベースオブジェクトがセキュリティポリシーに関連付けられている場合、アクセス制御は特別なPL / SQL関数に入力されたロジックを介して実行されます。 N番目の回路間隔の数十個の表現よりも、いくつかのソフトウェア機能をサポートする方がはるかに簡単であることに同意します。

ユーザーがデータベースオブジェクト(テーブル、ビュー)に直接または間接的にアクセスすると、サーバーは、セキュリティ関数によって返されるWHERE述語を追加して、SQLステートメントを動的に変更します。



セキュリティ機能



そこで、簡単なセキュリティ機能の例を検討します。 既に述べたように、関数のタスクは、ユーザーの要求に自動的に追加される述語を生成することです。



 create or replace function policy_func (p_schema varchar2, p_object varchar2) return varchar2 is begin if (user = 'MGR_10_20_30 ') then return 'clientoffice in (10, 20, 30)'; elseif return 'clientoffice = (select useroffice from users where username = user)'; end if; end;
      
      







上記の関数は、述語WHERE clientoffice = office_noをユーザーのSQLクエリに追加します。office_noは、ユーザーが勤務している部門の番号です。 ログインMGR_10_20_30を持つユーザーの場合、(10、20、30)の述語WHERE clientofficeが追加されます。 したがって、このユーザーは3つの部門の顧客情報にアクセスできます。



DBMS_RLSパッケージのプロシージャ



Add_policy


さて、この時点で必要な準備作業はすべて完了しました。データベースにセキュリティポリシーを追加するだけです。 セキュリティポリシーは、DBMS_RLS add_policyパッケージプロシージャによって記録されます。



 DBMS_RLS.ADD_POLICY ( object_schema IN VARCHAR2 NULL, object_name IN VARCHAR2, policy_name IN VARCHAR2, function_schema IN VARCHAR2 NULL, policy_function IN VARCHAR2, statement_types IN VARCHAR2 NULL, update_check IN BOOLEAN FALSE, enable IN BOOLEAN TRUE, static_policy IN BOOLEAN FALSE, policy_type IN BINARY_INTEGER NULL, long_predicate IN BOOLEAN FALSE, sec_relevant_cols IN VARCHAR2 NULL, sec_relevant_cols_opt IN BINARY_INTEGER NULL );
      
      







クライアントテーブルのセキュリティポリシーを追加します。



 Begin DBMS_RLS.ADD_POLICY ( object_schema => 'myuser', object_name => 'clients', policy_name => 'clients_policy', function_schema => 'myuser', policy_function => 'policy_func', statement_types => 'select, insert, update, delete', update_check => true ); End;
      
      







次に、使用する手順のパラメーターについて簡単に説明します。

object_schemaとobject_nameは、ポリシーが追加されるテーブル、ビュー、またはシノニムと、オブジェクトが配置されているデータベーススキーマです。

policy_nameは、追加するセキュリティポリシーの名前です。 名前は、テーブルまたはビューごとに一意である必要があります。

function_schemaおよびpolicy_function-述語を生成するセキュリティ関数の名前、および関数が配置されているデータベーススキーマ。

statement_types-セキュリティポリシーが適用されるステートメント。

update_check -INSERTまたはUPDATEが述語で指定された検索条件に違反する場合、このオプションはINSERTまたはUPDATE操作を防ぎます。

これで、実行中のセキュリティポリシーを確認できます。



 select username, useroffice from users;
      
      





画像





ユーザーMGR_10の場合:



 select user from dual;
      
      





画像





 select * from clients;
      
      





画像





ユーザーMGR_20の場合:



 select user from dual;
      
      





画像





 select * from clients;
      
      





画像





ユーザーMGR_10_20_30の場合:



 select user from dual;
      
      





画像





 select * from clients;
      
      





画像





データベースのビューに関する情報は、ビューuser_policies、all_policies、dba_policiesに保存されます。 DBA権限を持つユーザーの下からクエリを実行してみましょう。



 select * from dba_policies;
      
      





画像





Drop_policy


したがって、セキュリティポリシーを作成する手順、つまり削除する手順があります。

 DBMS_RLS.DROP_POLICY ( object_schema IN VARCHAR2 NULL, object_name IN VARCHAR2, policy_name IN VARCHAR2 );
      
      







セキュリティポリシーを削除してみましょう。



 Begin DBMS_RLS.DROP_POLICY ( object_schema => 'myuser', object_name => 'clients', policy_name => 'clients_policy' ); End;
      
      







次に、DBA権限を持つユーザーでデータベース内のポリシーの可用性を確認します。



 select * from dba_policies;
      
      





画像





Enable_policy


セキュリティポリシーの追加/削除に加えて、既存のポリシーを一時的に一時停止することができます。 これを行うには、enable_policyプロシージャを使用します。このプロシージャは、ポリシーを非アクティブ状態にする(enable => false)か、ポリシーを再開します(enable => true)。



 DBMS_RLS.ENABLE_POLICY ( object_schema IN VARCHAR2 NULL, object_name IN VARCHAR2, policy_name IN VARCHAR2, enable IN BOOLEAN TRUE) );
      
      







 select * from dba_policies;
      
      





画像





 Begin DBMS_RLS.ENABLE_POLICY ( object_schema => 'myuser', object_name => 'clients', policy_name => 'clients_policy', enable => false ); End;
      
      







 select * from dba_policies;
      
      





画像





 Begin DBMS_RLS.ENABLE_POLICY ( object_schema => 'myuser', object_name => 'clients', policy_name => 'clients_policy' ); End;
      
      







 select * from dba_policies;
      
      





画像



最も注意深いのは、dbms_rlsパッケージのadd_policyプロシージャのenableパラメーターに気づいたことです。 このパラメーターは、作成直後にポリシーがアクティブか非アクティブかを示します。 デフォルト値はtrueです。



Refresh_policy


この手順では、RLSポリシーの述語を更新できます。 セキュリティポリシーがDYNAMIC以外のタイプで定義されている場合、ポリシーの述語はしばらく更新されないことがあります。 メモリにキャッシュされます。 したがって、ポリシーをすぐに更新する必要がある場合は、REFRESH_POLICYプロシージャを実行する必要があります。これにより、ポリシー関数が再実行され、キャッシュ内の述語が更新されます。



 DBMS_RLS.REFRESH_POLICY ( object_schema IN VARCHAR2 NULL, object_name IN VARCHAR2 NULL, policy_name IN VARCHAR2 NULL );
      
      







おわりに



この記事では、「指で」と言われる最も単純な例を検討します。 次の記事では、コンテキストとポリシーのグループを使用したセキュリティについて検討します。



安全に! コミット!



All Articles