权限管理ACL
ZooKeeper 的权限管理亦即ACL 控制功能,使用ACL来对Znode进行访问控制。Zookeeper对于用户类别的区分,不止局限于所有者(owner)、组 (group)、所有人(world)三个级别。Zookeeper中,数据节点没有"所有者"的概念。访问者利用id标识自己的身份,并获得与之相应的 不同的访问权限。
ZooKeeper 的权限管理通过Server、Client 两端协调完成:
(1) Server端
一个ZooKeeper 的节点存储两部分内容:数据和状态,状态中包含ACL 信息。创建一个znode 会产生一个ACL 列表,列表中每个ACL 包括:
① 权限perms
② 验证模式scheme
③ 具体内容expression:Ids
ZooKeeper 提供了如下几种验证模式:
① Digest: Client 端由用户名和密码验证,譬如user:pwd
② Host: Client 端由主机名验证,譬如localhost
③ Ip:Client 端由IP 地址验证,譬如172.2.0.0/24
④ World :固定用户为anyone,为所有Client 端开放权限
权限许可集合如下:
① Create 允许对子节点Create 操作
② Read 允许对本节点GetChildren 和GetData 操作
③ Write 允许对本节点SetData 操作
④ Delete 允许对子节点Delete 操作
⑤ Admin 允许对本节点setAcl 操作
另外,ZooKeeper Java API支持三种标准的用户权限,它们分别为:
① ZOO_PEN_ACL_UNSAFE:对于所有的ACL来说都是完全开放的,任何应用程序可以在节点上执行任何操作,比如创建、列出并删除子节点。
② ZOO_READ_ACL_UNSAFE:对于任意的应用程序来说,仅仅具有读权限。
③ ZOO_CREATOR_ALL_ACL:授予节点创建者所有权限。需要注意的是,设置此权限之前,创建者必须已经通了服务器的认证。
Znode ACL 权限用一个int 型数字perms 表示,perms 的5 个二进制位分别表示setacl、delete、create、write、read。比如adcwr=0x1f,----r=0x1,a-c-r=0x15。
(2) 客户端
Client 通过调用addAuthInfo()函数设置当前会话的Author信息(针对Digest 验证模式)。Server 收到Client 发送的操作请求(除exists、getAcl 之外),需要进行ACL 验证:对该请求携带的Author 明文信息加密,并与目标节点的ACL 信息进行比较,如果匹配则具有相应的权限,否则请求被Server 拒绝。
public class NewDigest {
public static void main(String[] args) throws Exception {//new一个acl
List<ACL> acls = new ArrayList<ACL>();
//添加第一个id,采用用户名密码形式
Id id1 = new Id("digest",DigestAuthenticationProvider.generateDigest("admin:admin"));
ACL acl1 = new ACL(ZooDefs.Perms.ALL, id1);
acls.add(acl1);
//添加第二个id,所有用户可读权限
Id id2 = new Id("world", "anyone");
ACL acl2 = new ACL(ZooDefs.Perms.READ, id2);
acls.add(acl2);
// Zk用admin认证,创建/test ZNode。
ZooKeeper Zk = new ZooKeeper("host1:2181,host2:2181,host3:2181",2000, null);
Zk.addAuthInfo("digest", "admin:admin".getBytes());
Zk.create("/test", "data".getBytes(), acls, CreateMode.PERSISTENT);
}
}