【问题标题】:Row level permissions for entities based on roles基于角色的实体的行级权限
【发布时间】:2011-07-26 18:04:37
【问题描述】:

使用基于角色的权限,并说表中的每一行代表一个实体,例如Products 表,每一行代表一个 Product 实体。

您如何提供基于角色的产品级安全性?

例如销售组可以访问 ID 为 1,234,432,532,34 的产品

可以为多个角色授予对任何给定产品的权限。

目标是为如下查询提供有效的数据库调用:

var products = ProductDao.GetProductsByRole(234);  // roleID = 234

【问题讨论】:

    标签: c# asp.net sql-server


    【解决方案1】:

    多对多关系存储在单独的表中:

    create table Products( 
        ProductId int not null identity (1,1),
        Name nvarchar(256) not null,
        Description nvarchar(max),
        constraint PK_Products primary key (ProductId),
        constraint UNQ_Products_Name unique (Name));
    
    create table Roles(
        RoleId int not null identity (1,1),
        Name nvarchar(256) not null,
        Description nvarchar(max),
        constraint PK_Roles primary key (RoleId),
        constraint UNQ_Roles_Name unique (Name));
    go
    
    create table ProductRolePermissions (
        ProductId int not null,
        RoleId int not null,
        constraint FK_ProductRolePermissions_Products
            foreign key (ProductId) 
            references Products(ProductId),
        constraint FK_ProductRolePermissions_roles
            foreign key (RoleId) 
            references Roles(RoleId));
    go
    
    create unique clustered index CDX_ProductRolePermissions 
       on ProductRolePermissions (RoleId, ProductId);
    create unique nonclustered index NDX_ProductRolePermissions 
       on ProductRolePermissions (ProductId, RoleId);
    go
    
    
    create function dbo.GetProductsByRole( @roleId int)
    returns table
    with schemabinding
    as return (
        select ProductId 
        from dbo.ProductRolePermissions
        where RoleId = @roleId);
    go
    
    
    insert into Products (Name) 
           values ('P1'), ('P2'), ('P3'), ('P4');
    insert into Roles (Name) 
           values ('G1'), ('G2');
    insert into ProductRolePermissions (ProductId, RoleId) 
           values (1,1), (3,1), (2,2), (3,2);
    go
    
    select 'Products permitted for G1', p.* 
    from dbo.GetProductsByRole(1) r
    join Products p on r.ProductId = p.ProductId;
    
    select 'Products permitted for G2', p.* 
    from dbo.GetProductsByRole(2) r
    join Products p on r.ProductId = p.ProductId;
    

    如果您想遵循经典的授予/拒绝/撤销权限模型来获得具有多个角色成员资格的读/写/完全访问权限,事情会变得更加复杂。

    【讨论】:

    • 您认为对于具有更多行(例如 100000 行)的表来说,这是最佳解决方案吗?如果我实施您的解决方案,我认为它会导致更多的性能和用户管理问题。你对我的问题有什么想法吗? tnx/
    猜你喜欢
    • 2018-05-29
    • 2023-03-15
    • 2021-09-16
    • 1970-01-01
    • 2019-12-08
    • 2020-03-26
    • 1970-01-01
    • 2020-03-05
    • 2020-12-18
    相关资源
    最近更新 更多