在《zookeeper介绍及环境搭建》、《zookeeper客户端的使用》和《zookeeper java api介绍》三篇文章中,分别介绍了ZooKeeper的实验环境搭建、ZooKeeper的数据结构、ZooKeeper客户端的使用和ZooKeeper提供的Java API。本篇文章我们将详细讨论ZooKeeper的另一个重要概念——ZooKeeper的节点权限。
ZooKeeper节点权限基本概念
ZooKeeper节点的数据结构非常类似于Linux文件系统的结构。在Linux文件系统中,每个文件或目录针对不同的用户和用户组都具有相应的rwx权限。同样的,在ZooKeeper中,每个节点针对不同的用户或主机也具有相应的权限。下面我们来看下ZooKeeper中节点权限的基本概念。
- 权限模式schema
在ZooKeeper中,权限模式schema有两种类型,分别是ip和digest。
ip模式是基于ip白名单的方式指定某个服务器具有哪些权限。
digest模式是基于用户名和密码的方式指定哪个人具有什么样的权限。 - 授权对象ID
在ip权限模式下,ID就是具体的ip地址字符串。
在digest权限模式下,ID是username:Base64(Sha1(username:password))字符串。 - 权限permission
在ZooKeeper中,有create(c)、delete(d)、read(r)、write(w)和admin(a)这五种权限类型。
在ZooKeeper中,就是通过schema、ID和permission指定一个节点的权限信息。
权限对象ACL
在ZooKeeper中,权限的信息是通过org.apache.zookeeper.data.ACL
这个类指定的。ACL类的部分源码如下:
public class ACL implements Record {
private int perms;
private Id id;
. . .
}
org.apache.zookeeper.data.Id
类的部分源码如下:
public class Id implements Record {
private String scheme;
private String id;
. . .
}
在ACL类中,perms字段对应的就是我们上面提到的权限(permission)字段。而在Id类中的scheme和id两个字段对应的就是权限模式(schema)和授权对象(ID)。
我们通过下面的代码,就可以构造一个针对ip的权限对象:
ACL aclIp = new ACL(ZooDefs.Perms.READ | ZooDefs.Perms.WRITE, new Id("ip","192.168.1.110"));
ACL构造函数中的第一个参数是permission信息,可以通过ZooDefs.Perms.READ | ZooDefs.Perms.WRITE
这种方式同时指定多个权限。ACL构造函数的第二个参数是一个Id对象,Id对象中包含了schema和授权对象的信息,这里指定schema采用ip白名单的方式,授权对象是对应的服务器ip地址。
下面的代码可以采用schema为digest的方式构造一个ACL对象:
String authStr = DigestAuthenticationProvider.generateDigest("poype:123456");
ACL aclDigest = new ACL(ZooDefs.Perms.READ | ZooDefs.Perms.WRITE, new Id("digest",authStr));
这里构造的Id对象采用digest模式构造,authStr是包含用户名和密码信息的字符串。当schema为digest时,授权对象是username:Base64(Sha1(username:password))形式的字符串。为了简化我们编程,ZooKeeper提供了对应的工具类,我们可以通过DigestAuthenticationProvider.generateDigest
这个方法生成对应的授权对象字符串。这里poype是用户名,123456是密码。
下面的代码使用构造好的两个ACL对象创建一个zk节点:
ArrayList<ACL> acls = new ArrayList<ACL>();
acls.add(aclIp);
acls.add(aclDigest);
// 创建节点时用acls作为权限信息
String path = zooKeeper.create("/poype", "789".getBytes(), acls, CreateMode.PERSISTENT);
上面构造的/poype节点同时具有aclIp和aclDigest两个对象指定的权限。也就是说,/poype节点可以被ip地址为192.168.1.110的服务器读写,也可以被用户名为poype,密码是123456的用户读写。
此时在一台没有权限的机器上访问/poype节点,就会抛出下面的异常:
为了使该服务器可以访问/poype节点,可以使用用户名和密码给为该服务器增加授权。
使用命令addauth digest poype:123456
增加digest授权。
可以通过下面的代码增加digest授权:
zooKeeper.addAuthInfo("digest","poype:123456".getBytes());
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。