如何为表行实现类似于ACL的UNIX

问题描述 投票:0回答:1

我是SQL新手,请原谅我提出愚蠢的问题。我正在为大学项目创建我的第一个现实应用程序。

其核心是要处理成千上万的用户,除非给予特权,否则这些用户不应该能够互相读取或写入数据。就像Linux对用户和组一样。

在我尝试过的以下模式中,如果用户具有读取权限,则用户可以查看(读取)和编辑(写入)其他用户。(r = 2 w = 1 r + w =​​ 3)。

例如,如果cgroup_1是管理员,cgroup_2是管理员,而unixperm是32,则意味着管理员组中的用户可以读+写(3),而管理员组中的用户只能读(2)

create table cgroups
(
    id int unsigned primary key auto_increment,
    title varchar(100) not null unique,

    cunixperm  tinyint unsigned not null default 32 ,# r=2 w=1
    cgroup_1   int unsigned not null default 1 references cgroups (id) on delete cascade on update cascade,
    cgroup_2   int unsigned references cgroups (id) on delete cascade on update cascade
);


create table users
(
    id          int unsigned auto_increment primary key,
    username    varchar(255) not null unique,

    cunixperm  tinyint unsigned not null default 30, # r=2 w=1 3=r+w
    cgroup_1   int unsigned default 1 not null references cgroups (id) on delete cascade on update cascade ,
    cgroup_2   int unsigned references cgroups (id) on delete cascade on update cascade
);

create table many_users_in_many_cgroups
(
    user_id int unsigned references users(id),
    cgroup_id int unsigned references cgroups(id),
    primary key (user_id,cgroup_id)
);


insert into cgroups(title)
values ('admins'),('managers'),('writers');

insert into users(username, cunixperm, cgroup_1, cgroup_2)
values ('user1',30,1,null),
       ('user2',30,1,2),
       ('user3',22,2,2),
       ('user4',02,3,3);

insert into many_users_in_many_cgroups
values (1,1),(2,2),(3,3),(4,4);

现在假设用户2已登录我的应用程序,我如何仅向用户显示其具有读取(2)或读取+写入(3)权限的行。

如果上面的模式不是(可能)合适,请给我一个带有合适方案的例子

我目前正在使用MariaDB,但也为其他人开放解决方案。

sql security row acl
1个回答
1
投票

简单的答案是:访问部分的控件内置在应用程序中。

该机制必须位于SQL外部,因为SQL只能(通常)仅授予表级别的访问权限,而不授予行或列的访问权限。

关于如何精确编程,一种方法是这样。假设您有一个这样的数据表(我使用的是伪SQL,因为我不记得确切的Mysql语法):

Create table data (
rowid unique auto-increment,
datafield text);

Create table data_acl(
rowid foreign key references data (rowid),
cgroup references cgroups(id),
permissions int);

这假定所有用户都在某个cgroup中,因此要授予用户访问权限,您要授予cgroup访问权限。这使操作变得更容易,并且遵循每个用户都有自己的组的Unix理念。

您的用户表只需要列出用户名。

您的cgroups表仅需要列出用户和组。

Create table cgroups (
Id autoincrement int,
name);

Create table cgroup_users (
user_id foreign key references users(id),
cgroup_id foreign key references cgroups(id)
);

现在仅列出用户有权访问的所有数据行:

Select distinct datafield,acl.permissions from data d, data_acl acl, cgroups g 
Where d.rowid=acl.rowid and acl.cgroup in (select distinct cgroup_id from cgroup_users where user_id=?)

对不起,请通过手机发布。

© www.soinside.com 2019 - 2024. All rights reserved.