訪問控制使用視圖我有表,其內容的模式基本上可歸結爲:在PostgreSQL中
- 一組用戶的
- 一組對象組
- 的訪問控制列表(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;
我的問題是,這是一個好的方法嗎?做這些創建臨時VIEW語句產生顯著的開銷,特別是相對於一對夫婦簡單的查詢?
此外,有沒有一種方法,使這些觀點在我的數據庫定義永久性的,然後綁定一個值到每個會話的用戶名?這樣,就不必創建所有這些觀點在用戶每次加載頁面的時間。
在檢查更新/刪除,如果我只是指用戶通過ID而不是名字,我不能放棄CREATE VIEW AllowedUserGroup並直接引用該部分的acl? – 2010-02-22 06:59:19
當然,這將工作得很好。你也可以爲SELECT使用AllowedUserGroup,但我認爲AllowedObjects稍微有用。您也可以讓AllowedObjects將'objects'連接到AllowedUserGroup,這樣整個ACL /組/用戶邏輯就包含在AllowedUserGroup視圖中了......執行路徑應該是相同的。 – richardtallent 2010-02-22 20:34:50