关于权限访问控制设计

所谓“权限”,可以抽象地理解为:
主体(subject)对客体(object)的部分或者全部属性(attribute)进行的的操作(operation)
“访问控制”中的“操作”可以简化为读(read)和写(write)。
比如,
张三 修改 商品的库存
这里,
主体:张三
客体:商品
属性:库存
操作:修改(write)
通常这里的“客体”的“属性”“操作”也被成为“资源”。
插一句,我们通常所说的角色、角色组什么的,属于对这里“主体”的组织。
*  粒度
这里会涉及到一个粒度问题,也就是,访问控制要控制到多细,一般比较简单的系统中,我们会控制到“客体”这个粒度(也就是直接将属性全部包含到客体里)。
比如,张三修改商品
即,张三可以修改所有商品的所有属性。
但有时候我们会需要将粒度控制到部分属性,
比如,
库管人员(角色)可以修改商品的库存(一个属性)
张三可以修改商品的基本属性(多个属性)
*  过滤
还有一种情况,可能需要主体只能访问一部分客体。
此时,需要根据客体的某些属性进行过滤。
比如,
张三可以修改某个供应商(过滤属性)的商品库存
在描述时,可能是这样的:product{vendor:A}
这里的过滤表达式可能会比较复杂 – 比如还会增加类似条件:价格不高于100元。
类似的,主体和属性都存在需要过滤的情况,属性的过滤也就产生上面提到的“粒度”问题。
*  分配
权限本身也是一种“客体”,权限分配这个动作本身也是一个访问控制资源。
比如,
管理员可以分配商品的修改、读取权限给用户或角色
或者,重新按照上面的逻辑表达:
管理员(主体) 修改 商品的操作权限(客体) 主体(属性)
*  总结
访问控制逻辑的伪代码为:
function access(subject, object, attribute operation)
    permissions = 所有对object的权限定义
    permissions = filterBy({id:1}, stock, write)
    foreach(permissions as permission)
        if(permission.subject filter({role:admin})) return true
    return false
access({role:admin}, {id:1},{stock},{write})