Zookeeper的ACL(Access Control List),分为三个维度:scheme、id、permission
- scheme: 代表授权策略,表示采用哪一种机制
- id: 代表用户
- permission: 代表权限,如只读、读写、管理等等
Zookeeper提供了如下几种机制(scheme):
- world: 它下面只有一个id,叫anyone , world:anyone代表任何人,zookeeper中对所有人有权限的结点就是属于world:anyone的
- auth: 它不需要id,只要是通过authentication的user都有权限(zookeeper支持通过kerberos来进行authencation, 也支持username/password形式的authentication)
- digest: 它对应的id为username:BASE64(SHA1(password)),它需要先通过username:password形式的authentication
- ip: 它对应的id为客户机的IP地址,设置的时候可以设置一个ip段,比如ip:192.168.1.0/16, 表示匹配前16个bit的IP段
我们先来看一下ACL的常用命令,如下:
- getAcl: 获取指定节点的ACL信息
- setAcl: 设置指定节点的ACL信息
- addauth: 注册会话授权信息
首先我们先来获取一下指定的节点的ACL信息,进行查看,如下:
我们可以清楚的看到其scheme的值为world,表示任何人,然后world对于的 id 值为 anyone ,最后就是其权限,值为 cdrwa,其含义分为为:create、delete、read、write、admin 。
- create:是否有创建节点的权限
- delete:是否有删除节点的权限
- read:是否有读取数据的权限
- write:是否有修改节点的权限,如下 set 方法
- admin:是否有给子节点设置权限的权力
在明确了上述节点权限的含义后,我们就可以使用setAcl
命令来改变节点的权限啦,首先我们将 node1 节点的删除权限给去除了,这是 node1 节点只有cwra权限了
然后我们 node1 节点下创建一个子节点,然后再进行删除测试,如下:
如果我们需要删除,则需要重新使用setAcl
命令给node1节点赋予delete的权限
上述我们介绍了getAcl
和setAcl
的用法,要是我们需要可以设置账户密码,而不是所有人都可以操作呢?这里我们就需要用到addauth
命令了,它可以用来注册会话授权信息,接下来我们来看看如何使用,首先我们先来创建一个节点 node2
然后我们使用 addauth
来注册一个会话授权,然后就给刚刚创建的 node2 节点赋予 user1 会话的 crwa 权限
这时因为我们还没有退出,所以是可以对该节点进行 crwa 操作的,这里我们先执行 quit
命令退出,然后再进行连接,然后再 node2 节点下进行创建节点测试
这里发现无法进行创建,所以我们需要操作 node2 节点时,我们需要先获取之前设置的会话权限,如下:
上述其实介绍的就是我们的 scheme 的第二种机制—— auth,那么它与第三种机制—— digest 有什么区别呢?其实最主要的区别就是一个是明文,一个是密文。
我们可以看出我们在使用 auth 给节点进行设置权限时,采用的是明文,如下
那么我们在使用 digest 进行给节点赋予权限时,这里就需要使用密文了,这里我们使用 digest 的机制,将 node2 节点的 delete 权限添加回来,如下
那么现在有一个问题,我们知道账号密码为 user1:123456,那么我们是如何得到其密文,然后进行setAcl
命令的呢?这里我们可以通过如下命令得到其密文:
java -Djava.ext.dirs=/home/zookeeper/lib -cp /home/zookeeper/zookeeper-3.4.12.jar org.apache.zookeeper.server.auth.DigestAuthenticationProvider user1:123456
另外我们也可以在Zookeeper的代码中进行生成密文,见下图 DigestAuthenticationProvider 类,在项目中我们首先需要引入Zookeeper的依赖
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.12</version>
</dependency>
在该类下有一个Main方法,我们只需要将参数传递进去,就可以得到相应的密文了
其实这个加密方式我们上面也提到了,就是SHA1加上BASE64编码
最后就是大家在学习ACL权限控制的时候,有没有注册会话授权信息的时候,把节点的权限设置为了只读之类的操作,它既没有删除权限(d),也没有管理员权限(a),所以我们就没法给其重新进行授权,那么我们这时该怎么办呢?
这里其实我们可以给Zookeeper添加一个超级管理员账号,我们只需在Zookeeper的启动文件下,添加一个管理账号,然后再启动Zookeeper即可:
在上述红线处加上 “-Dzookeeper.DigestAuthenticationProvider.superDigest=账号:密码” ,如我们添加的超级管理员为:super:123456
:
至于如果获取我们对于账号密码的密文,在上述也就介绍过了
上述是以windows环境为例的,在Linux环境下添加超级管理员账号的步骤也是类似的,只需在zkServer.sh
文件中修改即可,这里就不重复介绍了。