为避免存储在zk上的数据被其他人修改,需要最zk上的数据访问进行权限控制。
zk提供了基于ACL(访问控制列表)权限控制机制,zk提供了三种Provider:DigestAuthenticationProvider、IPAuthenticationProvider、SASLAuthenticationProvider。 常用方式的是基于digest方式进行权限控制,这样也方便基于现用的用户系统进行集成。 zkClient是基于zooKeeper客户端的二次封装,使用起来更简单方便。 添加授权信息接口:
public void addAuthInfo(final String scheme, final byte[] auth)
需要在完成zooKeeper连接创建后,给该连接会话添加上相关的权限信息,之后凡是通过该会合对zk的服务器端任何操作都会带上该权限。
创建节点时需要显式的调用有ACL参数的接口,否则创建的就是world的权限节点,任何人都可以访问:
public void createEphemeral(final String path, final Object data, final List<ACL> acl)
public String createEphemeralSequential(final String path, final Object data, final List<ACL> acl)
public void createPersistent(String path, Object data, List<ACL> acl)
public void setAcl(final String path, final List<ACL> acl)
public String createPersistentSequential(String path, Object data, List<ACL> acl)
......
对于删除节点操作,其作用范围是其子节点,即对节点N1添加权限后,可以删除,但对于N1的子节点来说,就必须使用相对应的权限信息才能删除。
基于digest的权限控制示例代码如下:
// 创建会话
final ZkClient zkClient = new ZkClient("192.168.1.220:2181", 5000, 5000);
// 构造权限信息
List<ACL> acl = new ArrayList<ACL>();
acl.add(new ACL(ZooDefs.Perms.ALL, new Id("digest", DigestAuthenticationProvider.generateDigest("admin:admin123"))));//需要Digest后数据
// 创建节点
zkClient.create("/path1", "helloworld!", acl, CreateMode.EPHEMERAL);
// 未添加授权信息,读取失败
try {
System.out.println(zkClient.readData("/path1"));
zkClient.delete("/path1");
} catch (Exception e) {
System.out.println("权限不够");
}
// 添加授权信息
zkClient.addAuthInfo("digest", "admin:admin123".getBytes());
// 读取节点
System.out.println(zkClient.readData("/path1"));
// 删除节点,成功
zkClient.delete("/path1");
System.out.println(zkClient.exists("/path1"));