ZooKeeper ACL

来源:互联网 发布:大承网络 空中网 编辑:程序博客网 时间:2024/04/28 22:56

ZooKeeper通过ACL来对ZNode进行访问控制。ZooKeeper客户端为ZNode指定ACL列表,ZooKeeper服务器根据ACL列表判定某个请求ZNode的客户端是否有对应操作的权限。

一个ACL对象由Permissions和Ids两部分组成。

Permissions用一组权限位(permission bits)来表示对应的权限,0表示无权限,1表示有权限。ZooKeeper中有5种权限,从低位到高位分别是READ、WRITE、CREATE、DELETE和ADMIN,它们的含义是:

* READ: 允许获取该节点的值和列出子节点。
* WRITE: 允许设置该节点的值。
* CREATE: 允许创建子节点。
* DELETE: 可以删除子节点。
* ADMIN: 允许为该节点设置权限。

ACL的Permissions可以是以上5种权限中的1种或多种,例如org.apache.zookeeper.ZooDefs.Perms定义的ALL类型,就是将以上5种权限做个‘或’运算,表示拥有所有权限。

12345678
public interface Perms {    int READ = 1 << 0;    int WRITE = 1 << 1;    int CREATE = 1 << 2;    int DELETE = 1 << 3;    int ADMIN = 1 << 4;    int ALL = READ | WRITE | CREATE | DELETE | ADMIN;}

ZooKeeper中,ZNode没有Owner的概念,那些拥有ADMIN权限的客户端即等价于Owner,通过改变ZNode的ACL来进行权限管理。

如果说Permissions定义了ZNode有哪些操作可以做,那么Ids定义了ZNode有哪些人可以做。Ids由两部分组成:schema和expression,共同标识了一个允许接入的ZooKeeper客户端。schema用于区分客户端的类型,expression表示该类型下客户端的标识。ZooKeeper有内置的schema,用户也可以自定义。内置的schema有:

* world: world schema下只有一个expression: anyone。表示任何人。
* auth: auth schema下的expression为空。表示任何已经通过认证的客户端。
* digest: digest schema下的expression格式为username:password,相当于为ZNode指定一个“用户名+密码”,其他客户端要行使相应权限时,需要事先验证“用户名+密码”。服务器端为ZNode存储的认证信息为username:base64(SHA1(password))。
* ip: ip schema下的expression为CIDR格式的ip地址。

以下是一个利用digest schema验证的Demo:

123456789101112131415161718192021222324252627282930313233343536
// 初始化两类权限。admin拥有所有权限。guest只有写权限。List<ACL> acls = new ArrayList<ACL>();Id id1 = new Id("digest",         DigestAuthenticationProvider.generateDigest("admin:admin"));ACL acl1 = new ACL(ZooDefs.Perms.ALL, id1);Id id2 = new Id("digest",         DigestAuthenticationProvider.generateDigest("guest:guest"));ACL acl2 = new ACL(ZooDefs.Perms.WRITE, id2);acls.add(acl1);acls.add(acl2); // zk1用guest认证,创建/test ZNode。// /test允许admin任意操作,允许guest只能进行写操作。ZooKeeper zk1 = new ZooKeeper("127.0.0.1:2181", 2000, null);zk1.addAuthInfo("digest", "guest:guest".getBytes());zk1.create("/test", "data".getBytes(), acls, CreateMode.PERSISTENT); // zk1尝试读取/test// ZNode节点值,抛org.apache.zookeeper.KeeperException$NoAuthException异常。try {    System.out.println("zk1: " + new String(zk1.getData("/test", false, null)));} catch (Exception e) {    e.printStackTrace();} // zk2用admin登陆,可以正常读取/test ZNode节点值。ZooKeeper zk2 = new ZooKeeper("127.0.0.1:2181", 2000, null);zk2.addAuthInfo("digest", "admin:admin".getBytes());try {    System.out.println("zk2: " + new String(zk2.getData("/test", false, null)));} catch (Exception e) {    e.printStackTrace();} zk1.close();zk2.close();
原创粉丝点击