提到权限控制,我们比较熟悉的应该是Linux系统中UGO(User,Group,Others)权限控制。针对文件或者目录,可以对用户,用户所在的组,其他用户分配不同的权限。但是它比较有局限性,比如我想要U1所在的组G1对F1有读权限,另一个所在组G2对F1有写权限,就无法解决。
而ACL权限控制,也叫访问控制列表。是一种比较新颖而且更细粒度的权限管理方式。可以针对任意用户和组进行细粒度的权限控制。
权限控制包括三个方面,权限模式(scheme),授权对象(ID)和权限(Permission)。
通常用”scheme:id:permission”来标识一个有效的ACL信息。
权限三要素
权限模式
确定权限验证过程中使用的检查策略。常见的四种模式是:
IP:通过ip进行权限控制,比如设置了ip:192.168.109.133那么表示权限控制都是针对这个ip来的。
Digest:最常用。形如”username:password”形式的权限标识进行控制。
world:最开放.对所有用户开放,所有用户都不需要权限验证就可以操作ZK。可以认为这模式没啥作用
super:超级用户可以对ZK进行任何操作。
授权对象
授权对象是指权限赋予的用户或者一个指定的实体。例如IP地址或是机器等。不同权限模式对应不同的授权对象。
比如IP模式对应的授权对象是一个IP地址或者IP段;
Digest\Super模式对应的是自定义授权对象,形如username:Base64(Sha1(username:password))字符串;
World只有一个ID”anyone”
权限
即可以被允许执行的操作。
create(C):数据节点的创建权限
delete(D):删除权限
read(R):读权限
write(W):写权限
admin(A):管理权限
自定义权限
Zookeeper提供的权限模式绝大部分能满足需求,但是有时候也可以通过指定方式对Zookeeper的权限进行扩展。这些扩展的权限控制方式可以像插件一样插入到Zookeeper的权限体系中。
Zookeeper定义了一个标准权限控制器需要实现AuthenticationProvider接口:
public interface AuthenticationProvider {
String getScheme();
Code handleAuthentication(ServerCnxn var1, byte[] var2);
boolean matches(String var1, String var2);
boolean isAuthenticated();
boolean isValid(String var1);
}
比如DigestAuthentication和IPAuthenticationProvider都实现了该接口。
完成自定义控制器开发后,要注册到ZK服务器上去,两种方式:
配置文件zoo.cfg:authProvider.1=com.lyl.CustomAuthenticationProvider
系统属性-Dzookeeper.authProvider.X:
-Dzookeeper.authProvider.1=com.lyl.CustomAuthenticationProvider(在ZK启动参数中配置)
权限设置
实际操作中,我们如何进行权限的设置呢?
创建数据节点的时候设置ACL
create [-s] [-e] path data acl
使用ACL命令单独对已经存在的数据节点进行ACL设置
setAcl path acl
JAVA客户端设置
通过addAuthInfo(String scheme, byte[] auth)添加权限
public class AuthDemo {
public static void main(String[] args) throws Exception {
ZooKeeper zooKeeper1 = new ZooKeeper("master:2181", 5000, null);
//添加权限控制
zooKeeper1.addAuthInfo("digest", "lyl:true".getBytes());
zooKeeper1.create("/lyl", "acl".getBytes(), ZooDefs.Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);
String s = new String(zooKeeper1.getData("/lyl", false, null));
System.out.println(s);
ZooKeeper zooKeeper2 = new ZooKeeper("master:2181", 5000, null);
zooKeeper2.getData("/lyl", false, null);
}
}
由于zookeeper2没有对应的权限,因此会抛出Exception in thread “main” org.apache.zookeeper.KeeperException$NoAuthException: KeeperErrorCode = NoAuth for /lyl异常。
要注意一个问题,删除节点的权限控制有点不一样,只是控制子节点,即客户端对某个节点添加权限信息后,对于删除操作而言,其作用范围是其子节点,而该节点依然可以自由的删除。
public class AuthDemo {
public static void main(String[] args) throws Exception {
ZooKeeper zooKeeper1 = new ZooKeeper("master:2181", 5000, null);
//添加权限控制
zooKeeper1.addAuthInfo("digest", "lyl:true".getBytes());
zooKeeper1.create("/lyl/a1", "acl".getBytes(), ZooDefs.Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);
ZooKeeper zooKeeper2 = new ZooKeeper("master:2181", 5000, null);
zooKeeper1.delete("/lyl/a1",-1);
//zookeeper2具有删除/lyl的权限 但它不具有删除/lyl/a1的权限
zooKeeper2.delete("/lyl",-1);
}
}
BDStar原创文章。发布者:Liuyanling,转载请注明出处:http://bigdata-star.com/archives/1773