ビューを使用すると、基盤となるテーブルへの直接アクセス権を付与することなく、特定のアカウントに対してテーブルのフィルター済みサブセットを公開できます。これにより、ビューは行レベルのアクセス制御に有効な仕組みとなります。各アカウントは、自身が権限を持つビューのみをクエリし、AnalyticDB for MySQL がそのビューで定義されたフィルターを強制的に適用します。
仕組み
SQL SECURITY DEFINER を指定してビューを作成すると、そのビューは作成者(definer)の権限で実行され、クエリを実行するアカウントの権限では実行されません。このため、以下の点が保証されます。
ビューに対して
SELECT権限が付与されたアカウントは、基盤となるテーブルに対する権限を一切持たなくても、そのビューをクエリできます。AnalyticDB for MySQL はビューの
WHERE句を自動的に適用するため、アカウントが参照できるのは、ビューで公開された行のみです。
この仕組みにより、データパーティションごとに個別のビューを作成し、各アカウントに該当するビューへのアクセス権を付与することで、アカウント間のデータ分離を実現できます。
シナリオ
customer テーブルには、複数の都道府県から取得した顧客レコードが格納されています。この例では、user1 には都道府県 ID が 1 のレコードのみを許可し、user2 には都道府県 ID が 2 のレコードのみを許可します。
テーブル定義:
CREATE TABLE `customer` (
`id` bigint AUTO_INCREMENT,
`province_id` bigint NOT NULL,
`user_info` varchar,
PRIMARY KEY (`id`)
) DISTRIBUTED BY HASH(`id`);テストデータ:
INSERT INTO customer (province_id, user_info)
VALUES (1, 'Tom'), (1, 'Jerry'), (2, 'Jerry'), (3, 'Mark');全テーブルには、3 つの都道府県にまたがる 4 行のデータが含まれます。
+---------------------+-------------+-----------+
| id | province_id | user_info |
+---------------------+-------------+-----------+
| 1369417242420617216 | 1 | Tom |
| 1369417242424811520 | 1 | Jerry |
| 1369417242424811522 | 3 | Mark |
| 1369417242424811521 | 2 | Jerry |
+---------------------+-------------+-----------+ビューに基づくアクセス制御の設定
前提条件
開始する前に、以下の条件を満たしていることを確認してください。
AnalyticDB for MySQL クラスター(
adb_demoデータベース)ビューの作成および権限付与のための管理者権限が付与されていること
user1およびuser2アカウントが事前に作成済みであること(「CREATE USER」をご参照ください)
ステップ 1:都道府県ごとのビューを作成
都道府県ごとに 1 つずつビューを作成します。各ビューは、customer テーブルを特定の province_id でフィルターします。SQL SECURITY DEFINER 句により、ビューは作成者の権限で実行されるため、ビューをクエリするアカウントは、customer テーブルへの直接アクセス権を必要としません。
-- 都道府県 1 用のビュー:province_id = 1 の行のみを公開
CREATE SQL SECURITY DEFINER VIEW v1 AS
SELECT * FROM customer WHERE province_id = 1;
-- 都道府県 2 用のビュー:province_id = 2 の行のみを公開
CREATE SQL SECURITY DEFINER VIEW v2 AS
SELECT * FROM customer WHERE province_id = 2;CREATE VIEW の完全な構文およびパラメーターについては、「CREATE VIEW」をご参照ください。
ステップ 2:各アカウントに該当するビューへのアクセス権を付与
基盤となるテーブルではなく、ビューに対して SELECT 権限を付与します。これにより、各アカウントは割り当てられたビューで公開された行のみを読み取れるようになり、基盤となる customer テーブルは両アカウントから完全にアクセス不可の状態になります。
-- user1 は v1(都道府県 1 のデータのみ)をクエリできます。
-- ビューに対して権限を付与することで、user1 が他の都道府県のデータにアクセスすることを防止します。
GRANT SELECT ON v1 TO user1;
-- user2 は v2(都道府県 2 のデータのみ)をクエリできます。
-- ビューに対して権限を付与することで、user2 が他の都道府県のデータにアクセスすることを防止します。
GRANT SELECT ON v2 TO user2;結果の検証
各アカウントで adb_demo データベースに接続し、割り当てられたビューに対して SELECT を実行します。以下に、各アカウントにおける許可されたクエリおよび拒否されたクエリの例を示します。
ユーザー1として:
-- user1 には v1 に対する SELECT 権限があります。このクエリは都道府県 1 のレコードのみを返します。
SELECT * FROM v1;+---------------------+-------------+-----------+
| ID | PROVINCE_ID | USER_INFO |
+---------------------+-------------+-----------+
| 1369417242420617216 | 1 | Tom |
| 1369417242424811520 | 1 | Jerry |
+---------------------+-------------+-----------+-- user1 には v2 に対する権限がありません。このクエリは拒否されます。
SELECT * FROM v2;ERROR 1815 (HY000): [9001, 2021083114191719216818804803453965343] : アクセスが拒否されましたuser2 として:
-- user2 には v2 に対する SELECT 権限があります。このクエリは都道府県 2 のレコードのみを返します。
SELECT * FROM v2;+---------------------+-------------+-----------+
| ID | PROVINCE_ID | USER_INFO |
+---------------------+-------------+-----------+
| 1369417242424811521 | 2 | Jerry |
+---------------------+-------------+-----------+-- user2 には v1 に対する権限がありません。このクエリは拒否されます。
SELECT * FROM v1;ERROR 1815 (HY000): [9001, 2021083114191719216818804803453965343] : アクセスが拒否されました次のステップ
追加の都道府県に対しても同様のパターンを拡張するには、各
province_id値ごとにビューを作成し、対応するアカウントにそのビューに対するSELECT権限を付与します。アクセス権を取り消すには、
REVOKE SELECT ON <view_name> FROM <account_name>を実行します。ビュー作成オプションの完全なリファレンスについては、「CREATE VIEW」をご参照ください。