栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

zookeeper源码解析(十三)

zookeeper源码解析(十三)

2021SC@SDUSC

ACL基本概念

ZooKeeper 的权限管理亦即ACL控制功能,使用ACL来对Znode进行访问控制。ACL的实现和Unix文件访问许可非常相似:它使用许可位来对一个节点的不同操作进行允许或禁止的权限控制。但是和标准的Unix许可不同的是,Zookeeper对于用户类别的区分,不止局限于所有者(owner)、组 (group)、所有人(world)三个级别。Zookeeper中,数据节点没有"所有者"的概念。访问者利用id标识自己的身份,并获得与之相应的不同的访问权限。

深入ACL源码

我们首先来看看ACL类

public class ACL implements Record {
  private int perms;
  private org.apache.zookeeper.data.Id id;

如上,该类实现了Record接口(在zookeeper中实现该接口,表明类是生成的)

ACL类有两个变量,分别代表了权限值(perms)和ACL的验证实体(id)。

紧接着,我们来考察ID类,该类代表不同ACL模式下的具体实体。

public class Id implements Record {
  private String scheme;
  private String id;

如上,同样地,该类实现了Record接口

Record类有两个变量,scheme指验证模式,而id则代表在scheme的验证模式下的具体内容。

perms
@InterfaceAudience.Public
    public interface Perms {

        int READ = 1 << 0;

        int WRITE = 1 << 1;

        int CREATE = 1 << 2;

        int DELETE = 1 << 3;

        int ADMIN = 1 << 4;

        int ALL = READ | WRITE | CREATE | DELETE | ADMIN;

    }

zookeeper中的权限设置与Unix的文件权限(可读,可写,可执行)很类似,对某种权限的表示也仅仅用一个bit,如上所示,int的最后五个bit依次表示(Admin,Delete,Create,Write,Read)

具体地,这五种权限是指:

① Read 允许对本节点GetChildren 和GetData 操作

② Write 允许对本节点SetData 操作

③ Create 允许对子节点Create 操作

④ Delete 允许对子节点Delete 操作

⑤ Admin 允许对本节点setAcl 操作

PS:关于权限设置,有两点要注意

  1. zk的权限系统中没有所谓user,group,others的概念,也就是说没有一个用户或者说用户组是一个znode的拥有者,但是可以给一群用户或一个用户赋予某个znode admin的权限。
  2. 对某个znode设置的ACL只对它自己有效,对它的子节点无效的

 PPS:perms我想应该是permissions的缩写

scheme

zookeeper默认提供了五种scheme(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段

⑤super: 在这种scheme情况下,对应的id拥有超级权限,可以做任何事情(cdrwa---也就是上述五种权限)

@InterfaceAudience.Public
    public interface Ids {

        
        //默认的为world模式设置的ID
        Id ANYONE_ID_UNSAFE = new Id("world", "anyone");

        //默认的为auth模式设置的ID,代表了任何已经被确认的用户,在setacl的时候使用
        Id AUTH_IDS = new Id("auth", "");

        //默认的open ACL LIst,表示所有用户(ANYONE_ID_UNSAFE)有所有权限
        @SuppressFBWarnings(value = "MS_MUTABLE_COLLECTION", justification = "Cannot break API")
        ArrayList OPEN_ACL_UNSAFE = new ArrayList(Collections.singletonList(new ACL(Perms.ALL, ANYONE_ID_UNSAFE)));

        //默认的creator ACL LIst,表示auth_ids这些账号有所有权限
        @SuppressFBWarnings(value = "MS_MUTABLE_COLLECTION", justification = "Cannot break API")
        ArrayList CREATOR_ALL_ACL = new ArrayList(Collections.singletonList(new ACL(Perms.ALL, AUTH_IDS)));

        //默认的read ACL LIst,表示所有账号(ANYONE_ID_UNSAFE)有read权限
        @SuppressFBWarnings(value = "MS_MUTABLE_COLLECTION", justification = "Cannot break API")
        ArrayList READ_ACL_UNSAFE = new ArrayList(Collections.singletonList(new ACL(Perms.READ, ANYONE_ID_UNSAFE)));

    }

如上,我们可以看到zookeeper提供了两种默认的ID实例,分别是world和auth两种scheme的实现

public KeeperException.Code handleAuthentication(ServerCnxn cnxn, byte[] authData) {
        //把验证信息转换为string
        String id = new String(authData);
        try {
            //加密
            String digest = generateDigest(id);
            //判断是否是super    
            if (digest.equals(superDigest)) {
                //加入一个super的Id
                cnxn.addAuthInfo(new Id("super", ""));
            }

            //加入digest schema下的id为digest变量值的ID
            cnxn.addAuthInfo(new Id(getScheme(), digest));
            return KeeperException.Code.OK;
        } catch (NoSuchAlgorithmException e) {
            LOG.error("Missing algorithm", e);
        }
        return KeeperException.Code.AUTHFAILED;
    }

如上,在 DigestAuthenticationProvider类的handleAuthentication方法中实现了super scheme和digest scheme

注:superDigest的值可以在运行前配置环境变量来控制

    public String getScheme() {
        return "ip";
    }

    public KeeperException.Code handleAuthentication(ServerCnxn cnxn, byte[] authData) {
        String id = cnxn.getRemoteSocketAddress().getAddress().getHostAddress();
        cnxn.addAuthInfo(new Id(getScheme(), id));
        return KeeperException.Code.OK;
    }

如上,在IPAuthenticationProvider类的handleAuthentication方法中实现了ip scheme

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/682445.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号