【问题标题】:How to implement UNIX like ACL for table rows如何为表行实现类似 UNIX 的 ACL
【发布时间】:2020-06-18 01:51:24
【问题描述】:

我是新的 sql 东西,所以请原谅我提出愚蠢的问题。我正在为大学项目创建我的第一个现实生活应用程序。

在其核心,它需要处理数以千计的用户,除非被授予权限,否则这些用户应该无法读取或写入彼此的数据。就像 Linux 对用户和组所做的那样。

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

例如,如果cgroup_1 是 admin,cgroup_2 是 manager,unixperm 是 32,那么这意味着 admin 组中的用户可以读+写(3),managers 组中的用户只能读(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】:

    简短的回答是:访问部分的控制内置在应用程序中。

    该机制必须位于 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=?)
    

    抱歉格式化,从手机发布。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-03
      • 2021-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多