zookeeper-3.8.3-基于ACL的访问控制
ZooKeeper基于ACL的访问控制
ZooKeeper 用ACL控制对znode的访问,类似UNIX文件权限,但无znode所有者概念,ACL指定ID及对应权限,且仅作用于特定znode,不递归。
ZooKeeper支持可插拔认证方案,ID格式为scheme:expression
。客户端认证时,其对应ID与连接关联,访问znode时与ACL比对。
ACL权限
- CREATE:可创建子节点。
- READ:可获取节点数据和列出子节点。
- WRITE:可设置节点数据。
- DELETE:可删除子节点。
- ADMIN:可设置权限。
CREATE
和DELETE
从WRITE
分离实现细粒度控制,ADMIN
类似所有者权限,所有人隐式有LOOKUP
权限(可查看节点状态)。获取znode的ACL需READ
或ADMIN
权限,无ADMIN
权限时digest
哈希值会被屏蔽。
内置ACL方案
- world:ID为
anyone
,代表任何人。 - auth:特殊方案,忽略
expression
,用当前用户认证信息,无认证用户时设ACL会失败。 - digest:用
username:password
生成MD5哈希作ACL ID标识,认证时明文发送username:password
。 - ip:用客户端主机IP作ACL ID标识,表达式为
addr/bits
。 - x509:用客户端X500主体作ACL ID标识,安全端口下客户端自动认证并设
x509
认证信息。
ZooKeeper C客户端API
C库提供权限常量(如ZOO_PERM_READ
等)和标准ACL ID(如ZOO_ANYONE_ID_UNSAFE
等),还有三个标准ACL(如ZOO_OPEN_ACL_UNSAFE
完全开放)。相关操作有:
zoo_add_auth
:用于客户端向服务器认证,可多次调用。zoo_create
:创建新节点,需父节点有CREATE
权限。zoo_get_acl
:获取节点ACL信息,需READ
或ADMIN
权限。zoo_set_acl
:替换节点ACL列表,需节点有ADMIN
权限。
并给出使用“foo”方案认证并创建仅具创建权限临时节点的示例代码。
可插拔的ZooKeeper身份验证
ZooKeeper有可插拔身份验证框架,涉及客户端认证和在ACL中找对应条目两个操作。身份验证插件需实现特定接口:
public interface AuthenticationProvider {
String getScheme();
KeeperException.Code handleAuthentication(ServerCnxn cnxn, byte authData[]);
boolean isValid(String id);
boolean matches(String id, String aclExpr);
boolean isAuthenticated();
}
getScheme
返回插件标识字符串。handleAuthentication
处理客户端认证信息。isValid
验证ID格式。matches
匹配客户端认证信息和ACL条目。isAuthenticated
确定认证信息是否加入ACL。
内置ip
和digest
插件,可通过系统属性添加插件,服务器启动时查找zookeeper.authProvider.
开头的属性并解析为插件类名,所有服务器插件定义需一致。
3.6.0版本提供另一抽象:
public abstract class ServerAuthenticationProvider implements AuthenticationProvider {
public abstract KeeperException.Code handleAuthentication(ServerObjs serverObjs, byte authData[]);
public abstract boolean matches(ServerObjs serverObjs, MatchValues matchValues);
}
扩展该类可接收额外参数(ServerObjs
和MatchValues
) ,涉及ZooKeeperServer
实例、当前连接、操作路径、操作值及setAcl()
时设置的ACL列表等信息。