鲁春利的工作笔记,谁说程序员不能有文艺范?
为了避免存储在ZooKeeper服务器上的数据被其他进程干扰或人为操作修改,需要对ZooKeeper上的数据访问进行权限控制(Access Control)。ZooKeeper提供了ACL的权限控制机制,来控制客户端对数据节点的访问控制。
ZooKeeper提供了多种权限控制模式(Scheme),分别是world、auth、digest、ip和super。
开发人员如果要使用ZooKeeper的权限控制功能,需要在ZooKeeper回话创建后,给该回话添加相关的权限信息(AuthInfo)。ZooKeeper客户端提供了相应的API接口来进行权限信息的设置:
addAuthInfo(String scheme, byte [] auth) scheme :权限控制模式,world、auth、digest、ip和super auth :具体的权限信息
说明:该接口主要用于为当前ZooKeeper会话添加权限信息,之后凡是通过该会话对ZooKeeper服务端进行的任何操作,都会带上该权限信息。
使用包含权限信息的ZooKeeper会话操作数据节点
package com.invic.zk; import java.io.IOException; import java.util.concurrent.CountDownLatch; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZooDefs.Ids; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.data.Stat; /** * * @author lucl * */ public class CusZookeeperACL { /** * @param args */ public static void main(String[] args) { String path = "/zk-book-auth"; String childPath = path + "/child"; String connectString = "nnode:2181,dnode1:2181,dnode2:2181"; int sessionTimeout = 30 * 1000; System.out.println("===============第一次、创建节点================"); { try { final CountDownLatch latch = new CountDownLatch(1); ZooKeeper zk = new ZooKeeper(connectString, sessionTimeout, new Watcher() { @Override public void process(WatchedEvent event) { System.out.println(event.getState()); // SyncConnected if (KeeperState.SyncConnected == event.getState()) { System.out.println("zk session established : SyncConnected."); if (EventType.None == event.getType() && null == event.getPath()) { latch.countDown(); } } } }); latch.await(); // 权限信息 // 模式:world、auth、digest、ip和super // auth:具体权限信息 zk.addAuthInfo("digest", "foo:true".getBytes()); // 创建节点,此时节点就受到了权限控制 byte [] initData = "init".getBytes(); byte [] childData = "child".getBytes(); zk.create(path, initData , Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT); zk.create(childPath, childData, Ids.CREATOR_ALL_ACL, CreateMode.EPHEMERAL); Thread.sleep(sessionTimeout); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } catch (KeeperException e) { e.printStackTrace(); } } System.out.println("==============第二次、未带权限信息的连接==============="); { ZooKeeper zk2 = null; try { zk2 = new ZooKeeper(connectString, sessionTimeout, new Watcher() { @Override public void process(WatchedEvent event) { System.out.println(event.getState()); // SyncConnected } }); } catch (IOException e) { e.printStackTrace(); } try { Thread.sleep(sessionTimeout); } catch (InterruptedException e) { e.printStackTrace(); } if (null != zk2) { Stat stat = new Stat(); try { // 获取数据报错: KeeperErrorCode = NoAuth for /zk-book-auth byte [] bytes = zk2.getData(path, false, stat); System.out.println("Get data from zk : " + new String(bytes)); } catch (KeeperException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } try { Thread.sleep(sessionTimeout); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("==============第三次、正确的权限信息的连接==============="); { ZooKeeper zk3 = null; try { zk3 = new ZooKeeper(connectString, sessionTimeout, new Watcher() { @Override public void process(WatchedEvent event) { System.out.println(event.getState()); // SyncConnected } }); zk3.addAuthInfo("digest", "foo:true".getBytes()); } catch (IOException e) { e.printStackTrace(); } try { Thread.sleep(sessionTimeout); } catch (InterruptedException e) { e.printStackTrace(); } if (null != zk3) { try { byte[] datas = zk3.getData(path, true, null); // Get data from zk : init System.out.println("Get data from zk : " + new String(datas)); } catch (KeeperException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } try { Thread.sleep(sessionTimeout); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("==============第四次、错误的权限信息的连接==============="); { ZooKeeper zk4 = null; try { zk4 = new ZooKeeper(connectString, sessionTimeout, new Watcher() { @Override public void process(WatchedEvent event) { System.out.println(event.getState()); // SyncConnected } }); zk4.addAuthInfo("digest", "foo:false".getBytes()); } catch (IOException e) { e.printStackTrace(); } try { Thread.sleep(sessionTimeout); } catch (InterruptedException e) { e.printStackTrace(); } if (null != zk4) { try { byte[] datas = zk4.getData(path, true, null); // Get data from zk : init System.out.println("Get data from zk : " + new String(datas)); } catch (KeeperException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } try { Thread.sleep(sessionTimeout); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("==============第五次、未指定权限信息的连接==============="); { ZooKeeper zk5 = null; try { zk5 = new ZooKeeper(connectString, sessionTimeout, new Watcher() { @Override public void process(WatchedEvent event) { System.out.println(event.getState()); // SyncConnected } }); } catch (IOException e) { e.printStackTrace(); } try { Thread.sleep(sessionTimeout); } catch (InterruptedException e) { e.printStackTrace(); } if (null != zk5) { try { // 删除path的子节点KeeperErrorCode = NoAuth for /zk-book-auth/child zk5.delete(path + "/child", -1); } catch (InterruptedException e) { e.printStackTrace(); } catch (KeeperException e) { e.printStackTrace(); } } try { Thread.sleep(sessionTimeout); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("==============第六次、指定权限信息的连接==============="); { ZooKeeper zk6 = null; try { zk6 = new ZooKeeper(connectString, sessionTimeout, new Watcher() { @Override public void process(WatchedEvent event) { System.out.println(event.getState()); // SyncConnected } }); zk6.addAuthInfo("digest", "foo:true".getBytes()); } catch (IOException e) { e.printStackTrace(); } try { Thread.sleep(sessionTimeout); } catch (InterruptedException e) { e.printStackTrace(); } if (null != zk6) { try { // 成功删除 zk6.delete(childPath, -1); } catch (InterruptedException e) { e.printStackTrace(); } catch (KeeperException e) { e.printStackTrace(); } } try { Thread.sleep(sessionTimeout); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("==============第七次、未指定权限信息的连接==============="); { ZooKeeper zk7 = null; try { zk7 = new ZooKeeper(connectString, sessionTimeout, new Watcher() { @Override public void process(WatchedEvent event) { System.out.println(event.getState()); // SyncConnected } }); } catch (IOException e) { e.printStackTrace(); } try { Thread.sleep(sessionTimeout); } catch (InterruptedException e) { e.printStackTrace(); } if (null != zk7) { try { // 本次为删除path路径,成功删除--权限信息只对子节点起左右 zk7.delete(path, -1); } catch (InterruptedException e) { e.printStackTrace(); } catch (KeeperException e) { e.printStackTrace(); } } try { Thread.sleep(sessionTimeout); } catch (InterruptedException e) { e.printStackTrace(); } } } }