を用いたアクセス制御PostgreSQL
-
22-09-2019 - |
質問
私はスキーマのテーブル、その内容は基本的には抜:
- セットのユーザー
- セットオブジェクト群
- アクセス制御リスト(acl)を示すユーザーの閲覧個所や閲覧アクセスにどの団体
- セットオブジェ、それぞれの所属するそう。
作りたい簡易を支援するアプリケーションアクセス制御です。私は考え眺望が良いアプローチです。
ることもあって、以下のデータベース化初期設定:
/* Database definition */
BEGIN;
CREATE SCHEMA foo;
CREATE TABLE foo.users (
id SERIAL PRIMARY KEY,
name TEXT
);
CREATE TABLE foo.groups (
id SERIAL PRIMARY KEY,
name TEXT
);
CREATE TABLE foo.acl (
user_ INT REFERENCES foo.users,
group_ INT REFERENCES foo.groups
);
CREATE TABLE foo.objects (
id SERIAL PRIMARY KEY,
group_ INT REFERENCES foo.groups,
name TEXT,
data TEXT
);
/* Sample data */
-- Create groups A and B
INSERT INTO foo.groups VALUES (1, 'A');
INSERT INTO foo.groups VALUES (2, 'B');
-- Create objects belonging to group A
INSERT INTO foo.objects VALUES (1, 1, 'object in A', 'apples');
INSERT INTO foo.objects VALUES (2, 1, 'another object in A', 'asparagus');
-- Create objects belonging to group B
INSERT INTO foo.objects VALUES (3, 2, 'object in B', 'bananas');
INSERT INTO foo.objects VALUES (4, 2, 'object in B', 'blueberries');
-- Create users
INSERT INTO foo.users VALUES (1, 'alice');
INSERT INTO foo.users VALUES (2, 'amy');
INSERT INTO foo.users VALUES (3, 'billy');
INSERT INTO foo.users VALUES (4, 'bob');
INSERT INTO foo.users VALUES (5, 'caitlin');
INSERT INTO foo.users VALUES (6, 'charlie');
-- alice and amy can access group A
INSERT INTO foo.acl VALUES (1, 1);
INSERT INTO foo.acl VALUES (2, 1);
-- billy and bob can access group B
INSERT INTO foo.acl VALUES (3, 2);
INSERT INTO foo.acl VALUES (4, 2);
-- caitlin and charlie can access groups A and B
INSERT INTO foo.acl VALUES (5, 1);
INSERT INTO foo.acl VALUES (5, 2);
INSERT INTO foo.acl VALUES (6, 1);
INSERT INTO foo.acl VALUES (6, 2);
COMMIT;
私のアイデアを用意するミラーのデータベースのものを制限するコンテンツをみると、現在のユーザーが把握私のPHPスクリプトがアクセス(あれこれ試してみましょうだけの利用は、ユーザ'bob').ということで、全てのセッションのPostgreSQLを意味する人にアクセスのページを自分のサイト):
BEGIN;
CREATE TEMPORARY VIEW users AS
SELECT * FROM foo.users
WHERE name='bob';
CREATE TEMPORARY VIEW acl AS
SELECT acl.* FROM foo.acl, users
WHERE acl.user_=users.id;
CREATE TEMPORARY VIEW groups AS
SELECT groups.* FROM foo.groups, acl
WHERE groups.id=acl.group_;
CREATE TEMPORARY VIEW objects AS
SELECT objects.* FROM foo.objects, groups
WHERE objects.group_=groups.id;
COMMIT;
私の質問は、この良いアプローチを考えていますか。これらを一時的に保ビュー結果を報告するものでオーバーヘッドに比べるカップルで簡単なクエリー?
また、があるので、これらの眺めの常設のデータベースの定義、そして結合する値をユーザー名ョンをクリックします。このようにされているとは思いませんが、作で、これらすべて見る毎にユーザーを読み込むページです。
解決
複数の問題がこのアプローチ:
ユーザー ウェブ セッションは同じものではありません一つとして データベース セッション。複数のユーザーにと振り分けの設定に失敗します。
経営架作を破壊しました。
代わりに、私がお勧めするには、次のようなものが見
CREATE VIEW AllowedObjects
SELECT objects.*, users.name AS alloweduser
FROM objects
INNER JOIN groups ON groups.id = objects.group_
INNER JOIN acl ON acl.group_ = groups.id
INNER JOIN users ON users.id = acl.user_
そして、ものすオブジェクトを選択:
SELECT * FROM AllowedObjects
WHERE alloweduser='Bob'
これはボブとすることはできACLの接合に彼の特定のグループは、そうでない場合は異なるが必要だと思います。
この抽象化をは少し少な複合体が使用できるようにするにチェックのアクセス権更新および削除:
CREATE VIEW AllowedUserGroup
SELECT groups.id AS allowedgroup, users.name AS alloweduser
FROM groups
INNER JOIN acl ON acl.group_ = groups.id
INNER JOIN users ON users.id = acl.user_
これに平坦化したビューのユーザーをグループ、できるチェック対象のテーブルの中では、更新-削除:
UPDATE objects SET foo='bar' WHERE id=42 AND EXISTS
(SELECT NULL FROM AllowedUserGroup
WHERE alloweduser='Bob' AND allowedgroup = objects.group_)
所属していません StackOverflow