zookeeper节点之 java操作 和zookeeper-权限(ACL),设置超级用户(二)

java 操作zookeeper:

先贴上java连接zookeeper代码

public class zookeeperConnection {

final static CountDownLatch connectedSignal = new CountDownLatch(1);
static ZooKeeper zooKeeper = null;
// 1、连接zookeeper
public static ZooKeeper connect(String host) throws IOException, InterruptedException{
zooKeeper = new ZooKeeper(host,5000,new Watcher() {

@Override
public void process(WatchedEvent watchedEvent) {
// 2、异步连接
if(watchedEvent.getState() == KeeperState.SyncConnected){
connectedSignal.countDown();
}
}

});
connectedSignal.await();
System.out.println("连接成功");
return zooKeeper;
}

public static void close() throws InterruptedException{
System.out.println("关闭成功");
zooKeeper.close();
}

public static void main(String[] args) throws IOException, InterruptedException {
zookeeperConnection.connect("192.168.44.5:2181");
zookeeperConnection.close();
}
}

 java创建节点

public class IdAcl {
    public static void main(String[] args) throws KeeperException {
        try {
//            连接
            ZooKeeper connect = zookeeperConnection.connect("127.0.0.1:2181");
//            确认id(确认目标,客户端)
            Id id = new Id();
            id.setScheme("ip");
//            127.0.0.1 在zookeeper里和localhost 是不一样的 因为zookeeper里面不会做dns校验
            id.setId("127.0.0.1");
// 设置一段ip
       id.setId("127.0.0.1/255");
// 创建acl (授权-增删改查) ACL acl = new ACL(); acl.setId(id); acl.setPerms(ZooDefs.Perms.ALL); // 创建acl集合 List<ACL> list = new ArrayList<>(); list.add(acl); // 创建节点 connect.create("/aclid","id:id".getBytes(),list, CreateMode.PERSISTENT); } catch (IOException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } } }

 

解释:ZooDefs.Ids.OPEN_ACL_UNSAFE:

OPEN_ACL_UNSAFE: 创建任何人都可以操作的节点
READ_ACL_UNSAFE: 创建任何人都可以读的节点
CREATOR_ALL_ACL: 设置了Auth的用户可以使用该ACL集合创建节点,该节点也只能被同样Auth授权的用户操作

 

Watcher
可以设置Watcher的方式:

1) 在ZooKeeper的构造函数中可以设置Watcher

2) 使用ZooKeeper.register(Watcher)显示的更改在构造函数中设置的默认Watcher

3) 通过某些方法的调用可以更改某个path对应节点的Watcher?    

 

具体可以设置Watcher的方法如下所示:

1)     构造函数: state changes or node events 

2)     Register: 修改构造函数中指定的默认Watcher.

3)     getData: triggered by sets data on the node, or deletes the node. 

4)     getChildren: triggered by deletes the node or creates/delete a child under the node. 

5)     exists: triggered by creates/delete the node or sets the data on the node.

其中构造函数阶段指定的Watcher一直有效(register方式属于该类),其余方法设置的Watcher仅有效一次。在方法调用时,如果指 定开启watcher,如果该节点通过getData、getChildren和exists设置了Watcher,就触发该Watcher,然后使得该 Watcher失效(但默认的Watcher还一直生效),否则触发构造函数中设定的默认Watcher。

二、zookeeper-权限(ACL)

ACL用于控制Znode的访问,和Unix文件访问权限类似,提供对某类用户设置某种权限的能力(如Unix中对Owner提供读、写、执行的权限), 但是在ZooKeeper中没有Owner、Group等概念,于是在ZooKeeper中使用ID表示某一类用户,可以对ID设置某种权限。 (ZooKeeper对ID的数量没有限制,不像Unix文件仅支持三种类型用户)

ACL 权限控制,使用:scheme:id:perm 来标识,主要涵盖 3 个方面:
  权限模式(Scheme):授权的策略(客户端有很多类型(1、ip,2、用户名:密码,3、world:anyone))
  授权对象(ID):授权的对象(就是客户端)
  权限(Permission):授予的权限(crwda)

其特性如下:
  ZooKeeper的权限控制是基于每个znode节点的,需要对每个节点设置权限
  每个znode支持设置多种权限控制方案和多个权限
  子节点不会继承父节点的权限,客户端无权访问某节点,但可能可以访问它的子节点

     Id id = new Id();
id.setId("1");
// digest 是加密解密作用,如果想设置ip 里面直接写成ip就可以了
     id.setScheme("digest");
        ACL acl = new ACL();
acl.setId(id);
// 权限: 所有,增删改 ZooDefs.Perms.CREATE; ZooDefs.Perms.DELETE (CREATE、READ、WRITE、DELETE、ADMIN )
        acl.setPerms(ZooDefs.Perms.ALL);
byte[] data = "localhots:8099".getBytes();
List<ACL> acls = new ArrayList<>();
acls.add(acl);
// 创建 ZooDefs.Ids.OPEN_ACL_UNSAFE 权限 PERSISTENT_SEQUENTIAL 持久化节点- 顺序 ,临时节点(EPHEMERAL),顺序节点(SEQUENTIAL)
zooKeeper.create("/alomsc",data, acls, CreateMode.PERSISTENT_SEQUENTIAL);
// zooKeeper.create("/alomsc",data, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);

1. scheme 采用何种方式授权

  **world:**默认方式,相当于全部都能访问
  **auth**:代表已经认证通过的用户(cli中可以通过addauth digest user:pwd 来添加当前上下文中的授权用户)
  **digest**:即用户名:密码这种方式认证,这也是业务系统中最常用的。用 *username:password* 字符串来产生一个MD5串,然后该串被用来作为ACL ID。认证是通过明文发送*username:password* 来进行的,当用在ACL时,表达式为*username:base64* ,base64是password的SHA1摘要的编码。
  **ip**:使用客户端的主机IP作为ACL ID 。这个ACL表达式的格式为*addr/bits* ,此时addr中的有效位与客户端addr中的有效位进行比对。

2. ID 给谁授予权限

  授权对象ID是指,权限赋予的用户或者一个实体,例如:IP 地址或者机器。授权模式 schema 与 授权对象 ID 之间

3. permission 授予什么权限

  **CREATE、READ、WRITE、DELETE、ADMIN** 也就是 **增、删、改、查、管理**权限,这5种权限简写为crwda

这5种权限中,delete是指对子节点的删除权限,其它4种权限指对自身节点的操作权限

**更详细的如下:

  **CREATE** c 可以创建子节点
  **DELETE** d 可以删除子节点(仅下一级节点)
  **READ** r 可以读取节点数据及显示子节点列表
  **WRITE** w 可以设置节点数据
  **ADMIN** a 可以设置节点访问控制列表权限

 给节点赋权限(ip)

//授权

zooKeeper.addAuthInfo("ip", "127.0.0.1".getBytes());
// // 获取版本
Stat stat = zooKeeper.exists(path, true);
// int version = stat.getVersion();
// System.out.println(version);
//
// 设置ip权限
// Id id = new Id();

// 127.0.0.1 在zookeeper里面和localhost是不一样的 ,zookeeper不会dns解析
// id.setScheme("ip");
// id.setId("192.168.44.1");
//
// // 2、创建权限对象
// ACL aclM = new ACL();
// aclM.setId(id);
// aclM.setPerms(Perms.ALL);
//
// // 3、添加到集合
// List<ACL> acls = new ArrayList<ACL>();
// acls.add(aclM);
//
// // 打印权限列表
// zooKeeper.setACL(path, acls, zooKeeper.exists(path, true).getAversion());

List<ACL> acl = zooKeeper.getACL(path, stat);
System.out.println(acl.toString());
System.out.println("设置权限成功");

linux 命令:

 setAcl /test2 ip:127.0.0.1:crwda   #修改此IP具有所有权限
 setAcl /test1 world:anyone:acd   #修改为所有人可以acd
addauth digest user:111222    #增加授权用户,明文用户名和密码
setAcl /test digest:用户名:密码:权限 加密后用户和密码 (eg:
setAcl /test digest: user:BBO7K8dPkoek
[zk: localhost:2181(CONNECTED) 44] create /t4 44
Created /t4
[zk: localhost:2181(CONNECTED) 45] addauth digest qlq:111222    #增加授权用户,明文用户名和密码
[zk: localhost:2181(CONNECTED) 46] setAcl /t4 auth:qlq:cdwra  #授予权限
cZxid = 0x40000001d
ctime = Tue Mar 12 15:16:56 CST 2019
mZxid = 0x40000001d
mtime = Tue Mar 12 15:16:56 CST 2019
pZxid = 0x40000001d
cversion = 0
dataVersion = 0
aclVersion = 1
ephemeralOwner = 0x0
dataLength = 2
numChildren = 0
[zk: localhost:2181(CONNECTED) 48] getAcl /t4
'digest,'qlq:JWNEexxIoeVompjU7O5pZzTU+VQ=
: cdrwa

 

 

 

设置超级用户

    /**
     * 生成超级用户
     * @param usernameAndPassword
     * SERVER_JVMFLAGS="-Dzookeeper.DigestAuthenticationProvider.superDigest=super:BBO7K8dPkoek/JxIHqXxM75QRpI= $SERVER_JVMFLAGS" 
     * @return
     */
    private static String superEncode(String usernameAndPassword){
        try {
            String generateDigest = DigestAuthenticationProvider.generateDigest(usernameAndPassword);
            return generateDigest;
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        return "";
    }
public static void main(String[] args) {
        // 用户名:super 密码:123456
        System.out.println(superEncode("super:123456"));
    }

 

 

linux 命令:

进入到zk的客户端目录级

 输入: vim ./zkEnv.sh

 

 

 

将原来的超级用户换成新生成的用户 ;标红的为用户的生成的密码

SERVER_JVMFLAGS="-Dzookeeper.DigestAuthenticationProvider.superDigest=super:BBO7K8dPkoek/JxIHqXxM75QRpI= $SERVER_JVMFLAGS" 

更换完成重启zookeeper服务

./zkServer.sh restart

注:超级管理员可以与多个,但是建议最好不要建多个超级管理员

 

posted @ 2020-04-27 17:35  AlexZS  Views(1387)  Comments(0Edit  收藏  举报