博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
zk Acl权限:只有一个账号有crdwa权限,匿名用户只有r权限
阅读量:6937 次
发布时间:2019-06-27

本文共 2102 字,大约阅读时间需要 7 分钟。

hot3.png

起因

    最近在做多租户改造,租户使用的配置项都要放到zk上(如数据库配置、redis配置、阿里oss配置、每个租户的域名配置等),每个子系统去zk读取配置。当配置信息改变时,通过zk的watch机制,给子系统发消息,子系统接收到消息之后,再去做相应的处理(如:租户1的数据库配置变了,就重新创建数据库连接池)。

    图1:系统关系逻辑及问题描述

151901_inRF_2475326.png

问题描述:

主要是只读的那些zkClient,不用账号密码,就能读(r)到zk上的数据。而不是给子系统分配账号密码。

子系统访问zk的时候,是不能带账号密码的。

如果用digest 给子系统分配统一的一个账号密码,在代码的层面是可以实现的。

但是老大要求,子系统访问zk的时候,不能带着密码。而且,只能有读(r)权限。

思路

152845_8LYM_2475326.png

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

使用命令看一下world的权限是cdrwa(也就是anyone拥有所有权限)

152952_dY48_2475326.png

所以,突然想到,能不能把world身份认证方式的默认权限设置成r,而admin的账号分配给crdwa权限。

于是使用代码:

public void set(String path, String data) {        createPathIfNotExists(path);        zkClient.writeData(path, data);    }    /**     * 如果path不存在,则创建。     *     * @param path     */    private void createPathIfNotExists(String path) {        String id = null;        try {            id = generateDigest("admin:admin"); // admin用户的账号:密码        } catch (NoSuchAlgorithmException e) {            throw new RRException("zk生成idPassword失败。zkPassword=" + zkPassword + ",zkPassword=" + zkPassword);        }        // 创建znode时,同时设置Acl权限:        List
acl = new ArrayList<>(); acl.add(new ACL(ZooDefs.Perms.ALL, new Id("digest", id))); acl.add(new ACL(ZooDefs.Perms.READ, new Id("world", "anyone"))); createPersistentIfNotExists(path, acl); } private void createPersistentIfNotExists(String path, List
acl) { if (!zkClient.exists(path)) { zkClient.createPersistent(path, true, acl); } }

这样,world默认的权限就改为了readOnly的了:

155259_SVbz_2475326.png

 

参考

 然而,ACL毕竟仅仅是访问控制,并非完善的权限管理,通过这种方式做多集群隔离,还有很多局限性:

(1)ACL并无递归机制,任何一个znode创建后,都需要单独设置ACL,无法继承父节点的ACL设置。

(2)除了ip这种scheme,digest和auth的使用对用户都不是透明的,这也给使用带来了很大的成本,很多依赖zookeeper的开源框架也没有加入对ACL的支持,例如hbase,storm

2. session的超时问题:

  ZKClient框架里会经常看见一些while语句,是由这些while语句完成的,比如ZkClient.retryUntilConnected方法 

(感谢紫川的反馈,此条可能存在描述性问题。经校对:ZkClient貌似还是有对Session Expired 处理的,在ZkClient.processStateChanged方法中。虽然能重新连接,但是连接上是一个新的 session,原有创建的ephemeral znode(即临时节点)和watch会被删除,程序上你可能需要处理这个问题。欢迎大家提出意见,万分感谢)

    对上面引用的补充:zkClient重新连接之后,还会把通过org.I0Itec.zkclient.ZkClient#addAuthInfo方法设置的权限信息给删掉。也需要自己去处理这个问题。详情:

 

转载于:https://my.oschina.net/anxiaole/blog/1814143

你可能感兴趣的文章
SpringMVC 架构、原理
查看>>
Spring Shiro
查看>>
小蚂蚁学习数据结构(10)——树的基本介绍
查看>>
linux apache
查看>>
在CMD命令行下关闭进程的命令
查看>>
puppet学习笔记之安装与配置
查看>>
ROS教程(6)---×××配置及应用
查看>>
Nginx服务器搭建和基本配置详解
查看>>
vSphere 4.1 的新增功能
查看>>
栈的实现,入栈判断是否Full,出栈判断是否Empty
查看>>
nagios 安装配置
查看>>
centos 6.5下搭建ipsec/xl2tpd ×××
查看>>
【BFS】POJ 3278
查看>>
Python字符串格式化
查看>>
计算时针与分针夹角的度数的算法
查看>>
访问者设计模式
查看>>
支持伍洲彤鄙视蔡国庆
查看>>
我的友情链接
查看>>
Apache Shiro学习笔记(七)Servlet3.0 Listener介绍
查看>>
zabbix2
查看>>