ZK ACL访问控制处理流程

来源:互联网 发布:网络大V发布谣言 编辑:程序博客网 时间:2024/05/16 11:38

Zk 对znode操作采用ACL进行了访问权限控制,类似于linux提供的读写权限,ZK将操作权限划分以下几种:CREATE/READ/WRITE/DELETE/ADMIN,

·        CREATE: 表示有权限创建一个子节点

·        READ: 表示可以getData或者getChildren

·        WRITE: 表示可以setData

·        DELETE: 表示可以delete子节点

·        ADMIN: 表示可以通过setACL设置znode权限

Create和delete权限是从write权限中拆分出来的,注意与linux中write的区别。ZK中使用常量类来标明了这些权限。

将这些权限与一系列Id进行关联就构成了节点的ACL控制对,可以这么看这个映射关系。

ACL=PermßàID

而ID由scheme和实际的字符串id组成。Scheme表示了与实际字符串id对应的认证scheme标识符,也就是说在对字符串id进行认证时,需要根据scheme找到对应的认证服务提供者来对id进行校验认证,例如Scheme=digest  id=qingxu:pwd,表示digest关键字对应的认证服务提供者来对qingxu:pwd进行认证,

ZK提供了目前提供了基于客户端IP(scheme=ip)和基于摘要(SHA1,scheme=digest)用户密码的两种提供者, 他们都实现了AuthenticationProvider接口, 用户也可以通过设置以zookeeper.authProvider.开头的系统属性来增加其他用户自定义的授权方式(ProviderRegistry在初始化时会将自定义的授权方式加载进来)。在ZK服务端,授权Provider以HashMap的方式驻留在内存中,key是scheme,value是AuthenticationProvider接口的实现类,这样通过AuthenticationProvider getProvider(String scheme) 就可以得到具体的认证服务了。

在客户端准备创建znode时,create方法要求指定对本znode的ACL列表,标明:谁(id)采用某种认证方式(scheme)之后可以采取某种操作(perm).

public String create(final String path,byte data[], List<ACL> acl,

           CreateMode createMode)

可以对一个znode使用多个ACL,当服务器端创建节点时会将这个ACL列表与该znode关联,并在随后某个时间持久化到snapshot中,当客户端对这个节点或者子节点进行操作时,会检查当前连接上来的客户端是否具有权限操作该节点,如果没有权限,就会抛出No Auth异常。对于有的权限认证信息,客户端不需要传递额外的信息给服务器,例如anyone,表示任何人,对于类似digest的认证服务,由于需要客户端提供用户密码,然后与服务端的用户密码进行校验(用户密码两者组合起来被认为是一个用户id),客户端输入认证服务的地方是通过通过客户端ZK的addAuthInfo(String scheme, byte auth[])方法添加对应认证信息(例如用户密码),这些认证信息会传递到服务器端做一些处理(主要是scheme服务器是否支持,对于scheme=digest主要是判定下是否super超级用户登录来了,scheme=ip就简单记录下当前登录ip),并保存在authinfo这个客户端列表中,以后这个连接就可以一直使用这个认证信息.

addAuthInfo 后的服务端流程如下:

服务器在节点进行权限检查时checkACL()流程如下:

Super用户直接通过,不进行任何权限(perm比较),可以进行任何操作。

否则,当前要进行的操作需要的权限perm与znode拥有的权限一致时,再比较用户。如果与znode上所有ACLperm都不一致,就表示没有通过校验,抛出NoAuthException异常。

如果该节点ACL是任何人都能访问(shceme=world 并且id=anyone),直接通过验证,否则,根据scheme找到认证服务provider,然后从authinfo中查找与该scheme相等同时id也match的ACL,找到则认证通过。如果所有的都没有验证通过,就抛出NoAuthException


最后:如果ZK服务器不想进行checkACL,那么服务器系统属性zookeeper.skipACL=yes即可。



原创粉丝点击