英文名称
|
中文名称
|
描述
|
---|---|---|
Subject
|
主体
|
通常是用户或用户组
|
Object
|
对象
|
权限所作用的对象,通常指各类资源
|
Action
|
操作
|
对Object的操作,如:创建、删除、查询、修改等
|
Effect
|
结果/效力
|
规则匹配后的限制操作,如:Allow/ Deny
|
Condition
|
限制条件
|
权限生效的条件
|
Permission
|
权限
|
用来指代是否允许某人在某种条件下对某种资源做某种操作
|
Role
|
角色
|
权限集合,包含一个或多个权限(Permission)
|
Policy
|
策略
|
一组规则/声明,在特定用户尝试执行特定的操作时进行评估,然后将测咯应用于用户、组和角色
|
早期授权模型是一个十分简单的东西,简单到用户和权限之间就是之间关联的,这些对应关系可以存在于数据库,也可以存在于配置文件,这样当用户登录进来之后,只需要去查询当前用户对应的权限即可,没有其它错综复杂的关系在里面。
ACL(Access Control List,权限控制列表),是最早的、最基本的一种访问控制机制,是基于客体进行控制的模型,在其他模型中也有 ACL 的身影。
Subject
can Action
to Object
// Alice : read,write; Subject:Alice Action: read,write Object: File // Bob: read; Subject:Bob Action: read,write Object: File
DAC (Discretionary Access Control,自主访问控制),是 ACL 的扩展模型,灵活性更强。使用这种模型,不仅可以判断 Subject 是否可以对 Object 做 Action 操作,同时也能让 Subject 将 Object、Action 的相同权限授权给其他的 Subject。DAC和ACL的最主要的区别就是 自主这两个字,当一个用户拥有该资源的权限的时候,就可以将该资源的权限再分配给其它用户,这一过程称之为 自主。
Subject
can Action
to Object
Subject
can grant
other Subject
// Granting Alice article created permission. Subject:Alice Action: Create Object: Article // Alice grants Bob to create articles. Subject:Bob Action: Create Object: Article
MAC(Mandatory Access Control 强制访问控制),MAC是为了弥补DAC模型中权限控制过于分散的问题而诞生的。在MAC的设计中,每一个对象都都有一些权限标识,每个用户同样也会有一些权限标识,而用户能否对该对象进行操作取决于双方的权限标识的关系,这个限制判断通常是由系统硬性限制的。
Subject
can Action
to Object
Object
can be Action
by Subject
Subject: Alice Action: Create Object: Article Subject: Bob Action: Create Object: Article
Subject: Article Action: Create Object: Alice
Subject: Bob Action: Create Object: Article
ACL、DAC 和 MAC 是旧时代的权限控制模型,无法满足现代应用对权限控制的需求,于是诞生了新时代的权限模型。
RBAC (Role-Based Access Control,基于角色的访问控制),引入了 Role(角色)的概念,并且将权限与角色进行关联。用户通过扮演某种角色,具有该角色的所有权限。RBAC模型是20世纪90年代研究出来的一种模型,早在20世纪70年代的多用户计算时期,这种思想就已经被提出来,直到20世纪90年代中后期,RBAC才在研究团体中得到一些重视,并先后提出了许多类型的RBAC模型。其中以美国George Mason大学信息安全技术实验室(LIST)提出的RBAC96模型最具有代表性,并得到了普遍的公认。
r={sub,obj,act}
sub、act
,或者如果有两个访问实体, 则为 sub、sub2、obj、act
。
p={sub, obj, act}
或 p={sub, obj, act, eft}
m = r.sub == p.sub && r.act == p.act && r.obj == p.obj
这个简单和常见的匹配规则意味着如果请求的参数(访问实体,访问资源和访问方式)匹配, 如果可以在策略中找到资源和方法,那么策略结果( p.eft
)便会返回。 策略的结果将保存在 p.eft
中。
e = some (where (p.eft == allow))
e = some (where (p.eft == allow)) && !some(where (p.eft == deny)
此示例组合的逻辑含义是:如果有符合允许结果的策略且没有符合拒绝结果的策略, 结果是为真。 换言之,当匹配策略均为允许(没有任何否认)为真(更简单的是,既允许又同时否认,拒绝就具有优先地位)。
g
是一个 RBAC系统, g2
是另一个 RBAC 系统。 _, _
表示角色继承关系的前项和后项,即前项继承后项角色的权限。 一般来讲,如果您需要进行角色和用户的绑定,直接使用 g
即可。 当您需要表示角色(或者组)与用户和资源的绑定关系时,可以使用 g
和 g2
这样的表现形式。
[request_definition] r = sub, obj, act [policy_definition] p = sub, obj, act [role_definition] g = _, _ [matchers] m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act [policy_effect] e = some(where (p.eft == allow)) #注意:where 跟后面的条件中间会有一个空格,不然的话语法错误
[request_definition]
r = sub, obj, act
[policy_definition]
p = sub, obj, act
[role_definition]
g = _, _
[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act
[policy_effect]
e = some(where (p.eft == allow)) #注意:where 跟后面的条件中间会有一个空格,不然的话语法错误
// 初始化enforcer func init() { e, err = casbin.NewEnforcer("model.conf", "policy.csv") if err != nil { log.Fatalf("load file failed, %v", err.Error()) } } // 验证权限 func checkPermission(ctx *gin.Context, sub, obj, act string) { log.Printf("sub = %s obj = %s act = %s", sub, obj, act) ok, err := e.Enforce(sub, obj, act) if err != nil { log.Printf("enforce failed %s", err.Error()) ctx.String(http.StatusInternalServerError, "内部服务器错误") return } if !ok { log.Println("权限验证不通过") ctx.String(http.StatusOK, "权限验证不通过") return } log.Println("权限验证通过") ctx.String(http.StatusOK, "权限验证通过") } // 定义接口访问控制 func main() { r := gin.Default() r.GET("/users", func(ctx *gin.Context) { sub := ctx.Query("username") obj := ctx.Request.URL.Path act := ctx.Request.Method checkPermission(ctx, sub, obj, act) }) r.POST("/users", func(ctx *gin.Context) { sub := ctx.Query("username") obj := ctx.Request.URL.Path act := ctx.Request.Method checkPermission(ctx, sub, obj, act) }) r.Run() }
实现 ABAC 的核心机制是在请求发起后,subject attributes、object attributes 与 environment conditions 作为输入,PDP 根据 PEP 的数据去获取 policy 与环境条件,再进行计算,最后确定是否有权进行请求。
ABAC实现
可扩展访问控制标记语言(Extensible Access Control Markup Language,XACML)是目前 ABAC 唯一的国际公开标准,已经在全球范围内被广泛采用,XACML 灵活的扩展性及丰富的规则及函数是实现复杂访问控制规则的科学选择。 XACML 支持多种逻辑表达式和属性类型,具有很强的策略表达能力,非常适合对这种细粒度的大数据存储访问控制模型进行授权描述。同时具有可扩展性,能够支持大 数据环境下的灵活、动态访问控制的需求。 但是这个实现过于复杂以及并不成熟,采用的并不多。
在ABAC上实现比较好的就是AWS IAM,AWS 作为云计算的领导者,很早就实现了类似的功能,而使用 IAM 则是 operations 的必修课。参考这个视频,AWS ABAC
ABAC解决复杂场景问题
Attribute 易于管理
容易管理用户或资源的 attribute。如对用户而言,租户、业务线、部门、用户ID、所属团队空间等就是天然的 attribute;而对于需要管理的对象而言,年级、学科、学段、对象类型等都可以作为 attribute。除此以外,用户或对象关联的标签也也都可以作为 attribute 使用。
细粒度授权支持
细粒度的授权管理,在 policy 中允许判断很灵活,请求中属性可以基于正则表达式判断,也可以使用逻辑与、逻辑或的关系自由组合很多不同的访问规则。可以实现灵活的 policy,解析 JSON 或者 XML 去动态的创建规则,而这些含有规则的 JSON 或 XML,则是可以被编程实现的(在 RBAC 的时代,这是很难的)。
访问控制管理成本很低
系统管理员很友好,在 RBAC 的时代,如果我需要实现细粒度的资源管理或者经常 subject 与 object 的对应关系经常变动,那么管理员难以操作的,也很容易出现问题,其中常常被采用的解决方案就是创建那些本不应该存在的 role。但是在 ABAC 时代,管理员的管理对象会缩减到 policy,也就是只处理访问控制。如:医疗机构中,如果某个护士负责照顾老张,系统管理员只需要新建一个 policy 并写上允许访问即可,当老张出院后,只需要删除或者失效这个 policy 就可以了。在 RBAC 的环境中,你可能需要为某个虚拟的 role 动态的添加 permission,而 permission 如果到了针对单个病人的情况下,是绝对多如牛毛的,特别是有两个叫做老张的病人时。
动态的总体控制
Environment conditions 也能够提供统一的系统级别的控制,比如威胁等级或者按照区域划分安全级别,不同的区域使用 ABAC 时,可能环境上会有变化。例如我们常用红区来表示最高安全级别,那么我们默认就需要 deny 所有请求,并且会触发警报等等,但是在绿区这种办公区域,可能默认所有的请求都是被允许的等等。Environment conditions 可以提供“拉闸”这样的功能,而且它也是可以动态调整的。
ABAC优缺点
优点:
对于大型组织,基于RBCA的控制模型需要维护大量的角色和授权关系,相比而言, ABAC 更加灵活。
新增资源时, ABAC 仅需要维护较少的资源,而 RBAC 需要维护所有相关的角色,ABAC 可扩展性更强、更方便。
ABAC 有更加细粒度 控制和根据上下文动态执行, RBAC 只能基于静态的参数进行判断。
能力最为强大,基于描述主体、客体、动作和环境的属性进行鉴权,可实现非常精细化的权限管控。
缺点 :
模型构建相对比较复杂。
无法直观审计用户拥有哪些权限、 规则 复杂会提高管理成本。
定义权限时,不能直观看出用户和对象间的关系。
规则 如果稍微复杂一点,或者设计混乱,会给管理者维护和追查带来麻烦。
权限判断需要实时执行, 规则过多会导致性能问题。
PBAC
下一代权限模型
NGAC
参考文档
https://en.wikipedia.org/wiki/Access-control_list
https://xie.infoq.cn/article/b1c8f075c354654d38e6fab0b
https://dinolai.com/notes/others/authorization-models-acl-dac-mac-rbac-abac.html
https://www.jianshu.com/p/115938c6294e
https://www.jianshu.com/p/e596f3b5d53e
https://nvlpubs.nist.gov/nistpubs/specialpublications/NIST.SP.800-162.pdf
https://casbin.org/zh/docs/overview