行レベル・セキュリティ
一般的なセキュリティに加えて、InterSystems IRIS® データ・プラットフォームでは 1 行ごとのきめ細かい SQL セキュリティを提供します。これは、行レベル・セキュリティと呼ばれます。行レベル・セキュリティでは、各行に、表示操作を承認されたユーザまたはロールのリストが保持されます。詳細は、"ユーザ" と "ロール" を参照してください。
概要
通常、SQL セキュリティは、テーブルまたはビューに対してユーザまたはロールに SELECT 特権を許可することによって制御します。ロールを使用することにより、セキュリティ・ロールの数がユーザの数を大幅に下回る場合にアクセス制御が単純化します。ほとんどの場合、各ユーザがどの行を選択できるかを制御するのにはビューレベル・セキュリティで十分です。ただし、目的の制御を実現するのに必要なビューの数が非常に多くなる場合は、きめ細かいアクセス制御を行うために別の方法が必要となります。
例えば、病院では各患者が患者固有のデータをオンラインで入手できるようにする場合があります。各患者に個別のビューを作成する方法は、実用的ではありません。代わりに、きめ細かいアクセス制御と InterSystems IRIS のロールベースの認証モデルを組み合わせることにより、行レベル・セキュリティでこのタイプのアプリケーションを効率的に、より安全に作成できます。
以下は、行レベル・セキュリティの使用に関する制約です。
-
行レベル・セキュリティは、永続クラスでのみ利用可能です。
-
行レベル・セキュリティは、InterSystems IRIS サーバ上でインスタンス化されたテーブルでのみ利用可能です。リンク・テーブル (つまり、外部サーバ上でインスタンス化されたテーブル) では利用できません。
-
行レベル・セキュリティは、SQL から行にアクセスする際にのみ適用されます。グローバルに直接アクセスする場合、またはオブジェクト・インタフェースを介してグローバルにアクセスする場合には適用されません。
行レベル・セキュリティの設定
テーブルの行レベル・セキュリティを有効にするには、そのテーブルの投影元のクラスの定義を編集します。
-
クラス定義コードでは、ROWLEVELSECURITY の値を 1 に設定します。以下は、その例です。
ROWLEVELSECURITY = 1;
このパラメータの定義は、行レベル・セキュリティが有効であり、このクラスは生成された %READERLIST プロパティを使用して、行へのアクセスが認証されたユーザおよびロールについての情報を格納することを示しています。
または、パラメータを以下のように定義できます。
ROWLEVELSECURITY = rlsprop;
rlsprop は、同じクラス内のプロパティ名です。この代替手段では、行レベル・セキュリティが有効であり、クラスは指定されたプロパティを使用して、行へのアクセスが認証されたユーザおよびロールに関する情報を格納することを示しています。この場合、次のようにインデックスもクラスに追加します。
Index %RLI On rlsprop;
-
%SecurityPolicy() クラス・メソッドを定義します。このクラス・メソッドは、ビューおよびテーブルの SELECT 特権を前提とし、行の選択を許可されているロールおよびユーザ名を指定します。
%SecurityPolicy() メソッドの構造は以下のとおりです。
ClassMethod %SecurityPolicy() As %String [ SqlProc ] { QUIT "" }
その特性は以下のとおりです。
-
%SecurityPolicy という名前のクラス・メソッドです。
-
文字列 (タイプ %String) を返します。
-
ゼロ個以上の引数を指定できます。このメソッドに引数がある場合は、各引数がクラス内のプロパティ名と一致する必要があり、すべて互いに異なる必要があります。
-
SqlProc キーワードは、メソッドをストアド・プロシージャとして呼び出すことができることを示します。
-
メソッドの QUIT 文は、行を表示できるユーザまたはロールを返します。複数のユーザまたはロールがある場合、QUIT はそれらの名前をコンマ区切りリストにして返す必要があります。例に示すように、Null 文字列を返す場合は、テーブルで SELECT 特権を持つすべてのユーザが行を表示できることを示します。
Important:%All ロールに割り当てられたユーザには、行レベル・セキュリティによって保護されているテーブルの行に対するアクセス権が自動的には付与されません。%All ユーザがこれらの行にアクセスできるようにするには、%SecurityPolicy() メソッドで明示的にそのアクセス権の付与を指定する必要があります。
-
-
クラスおよび依存クラス (存在する場合) をコンパイルします。
既存のデータを含むテーブルへの行レベル・セキュリティの追加
行レベル・セキュリティを既存のデータを含むテーブルに追加するには、まず、"行レベル・セキュリティの設定" で説明する手順を実行します。次に、以下の手順を実行します。
インデックスの再構築
ユーザがテーブルのデータにアクセスしている間は、そのテーブルのインデックスを再構築しないでください。再構築すると、クエリ結果が不正確になる可能性があります。
テーブルのインデックスを再構築する手順は以下のとおりです。
-
WITH CHECK OPTION 節を持つ定義済みのビューがテーブルにある場合は、DROP VIEW コマンドを使用してこれらのビューを削除します (各行にどのユーザがアクセス権を持つかという設定を更新した後、これらのビューを再作成できます)。
-
管理ポータルのホーム・ページで、[SQL] ページ ([システムエクスプローラ]→[SQL]) に移動します。
-
テーブルを含むネームスペースを選択します。
-
[テーブル] でテーブルの名前を選択します。これにより、テーブルの [カタログの詳細] が表示されます。
-
[アクション] ドロップダウン・リストで、[テーブルのインデックスを再構築] をクリックします。
インデックスの再構築の詳細は、"インデックスの定義と作成" を参照してください。
各行を表示できるユーザおよびロールの更新
これを実行する手順は以下のとおりです。
-
管理ポータルのホーム・ページで、[SQL] ページ ([システムエクスプローラ]→[SQL]) に移動します。
-
テーブルを含むネームスペースを選択します。
-
[クエリ実行] をクリックします。
-
編集可能領域で、テーブルを更新する文を発行します。その形式は以下のようになります。
UPDATE MySchema.MyClass SET rlsprop = MySchema.SecurityPolicy(MySQLColumnName1, ...)
以下はその説明です。
-
MySchema は、そのクラスを含むスキーマ (パッケージ) です。
-
MyClass はそのクラスの名前です。
-
rlsprop は、行を読み取ることができるユーザおよびロールのリストを含むフィールドです。これは、既定では %READERLIST であり、それ以外は ROWLEVELSECURITY パラメータの宣言で指定されるプロパティ名です。
-
SecurityPolicy は、%SecurityPolicy() メソッドの定義で SqlName 値により指定される値です。%SecurityPolicy() メソッドに明示的な SQL 名がなく、そのクラスが MySchema.MyClass である場合、既定の名前は myClass_sys_SecurityPolicy (MySchema.MyClass_sys_SecurityPolicy の完全修飾形式) です。
-
MySQLColumnName1, ... は、%SecurityPolicy() クラス・メソッドで定義される、引数に対応する一連の SQL 列名 (存在する場合) です。
-
-
[実行] をクリックします。
-
必要に応じて、最初に削除したビューを再作成します。
パフォーマンスのヒントおよび情報
%READERLIST プロパティは計算フィールドであり、その値は %SecurityPolicy() メソッドによって決まります。INSERT または UPDATE が実行されるたびに、その行に対して %SecurityPolicy() が呼び出され、%READERLIST の値が自動的に入力されます。
%READERLIST プロパティのコレクション・インデックスが定義され、これにより、クエリ・オプティマイザで使用されて、行レベル・セキュリティが有効になったときのパフォーマンス上の影響を最小化できます。
通常、セキュリティ・ポリシーは複数のコンマ区切りのロールまたはユーザ名を返す可能性があるため、既定では、ROWLEVELSECURITY を 1 に設定すると、コレクション・インデックスは %READERLIST プロパティ (列) に対して定義されます。セキュリティ・ポリシーが複数のユーザまたはロール名を返すことがない場合は、ROWLEVELSECURITY パラメータをオーバーライドし、%RLI インデックスを通常の (非コレクション) ビットマップ・インデックスとして明示的に定義できます。通常は、これによりパフォーマンスが最適化されます。
セキュリティのヒントおよび情報
行レベル・セキュリティを使用する際は、以下のセキュリティ要素に注意してください。
-
行レベル・セキュリティは、テーブルレベル・セキュリティに加えて処理を行います。SELECT、INSERT、UPDATE、または DELETE 文を実行するには、ユーザは該当する行に対してテーブルレベル・アクセスと行レベル・アクセスの両方を許可されている必要があります。
-
ユーザ特権は、実行時 (SQL コマンドの実行を試行する際) に動的に確認されます。
-
更新可能なビューを作成し、WITH CHECK OPTION を指定した場合、そのビューの INSERT 処理は、挿入される行が、ビューで指定された WHERE 句を満たすかどうかを確認します。さらに、行レベルのセキュリティを持つテーブルからビューを作成している場合、ビューで SELECT * FROM のコマンドを発行した際、ビューの WHERE 句または暗黙の行レベルのセキュリティ述語により行を表示できないと、INSERT は失敗します。
-
行へアクセスできる場合は、%READERLIST フィールド (または、行を表示できるユーザおよびロールのリストを保持する任意のフィールド) の値を変更できます。これは、行に対する自分自身のアクセス権を直接的または間接的に削除するアクションを実行できることを示します。
-
行の挿入を試みた際に、その挿入が仮に行レベル・セキュリティが定義されていない状態で UNIQUE 制約に違反するようなものであれば、行レベル・セキュリティが有効なことによりたとえ制約のエラーを引き起こす行が更新トランザクションからは参照できないとしても、行の挿入は制約に違反することになります。