ACL(access control)用来控制对节点的读写访问。每个节点都可以定义自己的ACL,用来控制客户端对节点的访问。
权限类型有以下几种:
READ(可读取节点数据和子节点列表)
WRITE(可写入节点数据)
CREATE(可创建子节点)
DELETE(可删除节点)
ADMIN(可设置节点的ACL)
可以看到权限类型控制的粒度还是比较细的。前4种对应zookeeper对节点的4种接口操作。最后一个admin权限可以对节点ACL进行设置。这几种权限被定义在ZooDefs.Perms对象种。
zookeeper提供了多种权限控制模式:
world:has a single id, anyone, that represents anyone
ip:该模式基于客户端的IP地址对访问进行限制。可以配置允许或拒绝特定IP地址范围的访问。
digest:digest模式要求客户端提供用户名和密码来验证身份。在ZooKeeper中,用户信息以username:password形式存储在ACL中。只有提供正确的用户名和密码组合才能执行操作。
auth:该模式要求客户端在与ZooKeeper建立连接之前进行身份验证。只有通过身份验证的客户端才能执行后续操作。这种模式常用于创建自定义认证方案。
权限设置被封装成ACL对象。ACL对象创建需要两个参数:权限和认证信息。权限可以从ZooDefs.Perms对象使用枚举值,认证信息可以通过Id对象指定。如以下几种方式:
new ACL(ZooDefs.Perms.CREATE, new Id("ip", "127.0.0.1"));
new ACL(ZooDefs.Perms.WRITE, new Id("digest", "username:password"));
new ACL(ZooDefs.Perms.DELETE, new Id("auth", "456565656"));
new ACL(ZooDefs.Perms.ALL, ZooDefs.Ids.AUTH_IDS);
这里注意ZooDefs.Ids.AUTH_IDS方式默认会被客户端设置的认证信息取代。
zkCli.sh权限操作
#设置客户端auth
addauth scheme auth
#创建节点指定ACL,crwda是5种权限的首字母
create /acl_test mydata ip:127.0.0.1:crwda
#获取节点权限
getAcl /acl_test
#设置权限
setAcl /acl_auth_test auth:user1:12345:crwad
这里使用curator演示digest方式例子:
第一个client user1:123456创建节点
CuratorFramework client = CuratorFrameworkFactory.builder()
.authorization("digest", "user1:123456".getBytes())
.connectString("localhost:2181")
.retryPolicy(new ExponentialBackoffRetry(1000, 3))
.build();
client.start();
String path = "/acl_digest";
//使用client的authorization认证信息
ACL acl = new ACL(ZooDefs.Perms.ALL, ZooDefs.Ids.AUTH_IDS);
List<ACL> aclList = new ArrayList<>();
aclList.add(acl);
//创建节点使用withAcls设置ACL
client.create().withACL(aclList).forPath(path, "test".getBytes());
client.close();
第二个client user2:123456访问节点
CuratorFramework client = CuratorFrameworkFactory.builder().connectString("localhost:2181")
.authorization("digest", "user2:123456".getBytes())
.retryPolicy(new RetryOneTime(1))
.build();
client.start();
String path = "/acl_digest";
byte[] data = client.getData().forPath(path);
System.out.println(new String(data));
client.close();
第二个client访问会报错无法访问
org.apache.zookeeper.KeeperException$NoAuthException: KeeperErrorCode = NoAuth for /acl_digest