文不打算对这部分代码进行全面的解读,而是先对几个主要类的职能进行概述,然后再罗列一些有价值的重要细节。

  • 第一部分:HBase Security 概述

HBase Security主要是基于User和User Group(Role)对表(或是更粒度的Family、Qualifer)进行安全检查(目前HBase Security暂不支持基于行的安全检查,但后续版本中会追加进来)。在authentication方面,它主要是通过Kerberos来完成的。这部分不是HBase Security实现的重点,HBase Security的大部分代码时在解决authorization的问题,也就是根据用户权限判定其是否有权访问某项资源。
HBase Security主要有这样几个重要的类:
org.apache.hadoop.hbase.security.access.AccessController
这是对所有访问进行拦截的入口,它既是MasterObserver又是RegionObserver,言下之意,它能拦截所有的操作。
org.apache.hadoop.hbase.security.access.AccessControlLists
这是专门负责对Permission进行读写(包括数据库和ZooKeeper)操作的类,你可以认为这一个DAO或是Repository
org.apache.hadoop.hbase.security.access.TableAuthManager
这是负责对用户进行权限检查的类,它主要有多个重载的authorize方法组成。同时,由于这个类的实例cache了所用的permission,因此它还有一些借助ZKPermissionWatcher进行同步本地与ZooKeeper数据的工作。

org.apache.hadoop.hbase.security.access.ZKPermissionWatcher
这是一个专门监视_acl_节点的一个ZooKeeper的Watcher. HBase Security在设计上为了考虑性能,会把所有的permission加载到内存中,但是如果permission发生变化,各节点需要同步这些变化,因此将所有的permission写入到ZooKeeper,然后再通过一个实时监控和更新permission。而ZKPermissionWatcher就是这负责这项工作的。
补充一句:从代码上看,TableAuthManager和ZKPermissionWatcher两个类耦合过于紧密,彼此互为对方的field. 此处的设计并不好,其实可以将两者合二为一,让TableAuthManager实现ZooKeeperListener。

  • 第二部分:若干重要细节

以下是一些有价值的细节问题,有关于配置部署的,有关于代码实现的。
1. 打开安全检查的方式是注册一些安全相关的coprocessor, 具体做法是在所有节点的hbase-site.xml中加入以下内容重启集群,  其中指定rpc engine为SecureRpcEngine
是因为该引擎能传递remote client传递的用户凭证(如用户名..),安全检查是以用户提供的凭证为基础进行的.

<property>
<name>hbase.rpc.engine</name>
<value>org.apache.hadoop.hbase.ipc.SecureRpcEngine</value>
</property>
<property>
<name>hbase.coprocessor.master.classes</name>
<value>org.apache.hadoop.hbase.security.access.AccessController</value>
</property>
<property>
<name>hbase.coprocessor.region.classes</name>
<value>org.apache.hadoop.hbase.security.token.TokenProvider,org.apache.hadoop.hbase.security.access.AccessController</value>
</property>

2. 打开安全机制前,最好指定一个superuser, 否则在刚打开安全机制时,_acl_表为空,意味着任何用户都无法从事任何操作,所以需要使用superuser来为用户分配权限.指定superuser的方法是在hbase-site.xml中加入:

 <property>
<name>hbase.superuser</name>
<value>superuser-accout: such as root</value>
</property>

3. 表的owner,也就是建表账户将自动拥有对该表的所有操作权限:RWXCA. 参见方法:

org.apache.hadoop.hbase.security.access.RowBasedAccessController.postCreateTable(...)

4. 用户或组的权限可以指定到 <table> <column family> <column qualifier> 三种不同的层次(粒度)上. 通过试验表明, 下层权限会自动继承上层权限!,.如给一个sample表R的权限,column family:cf也是R的权限,而qualifier:q是W的权限,那么用户即能读取也能写入cf:q.

5. 紧接第4点,考虑一种更为复杂的情况:

假定sample表有100个qualifier, 100个qualifier分属多个family,假定没有指定sample表级别的读权限,但是通过对多个family和family下的qualifier设定读权限,其中80个qualifier已经具备了读权限,那么,当该用户执行scan 'sample' 操作时,结果会如何呢?通过试验表明,所有具备读权限的qualifier都列出了,所有没有读权限的qualifier都被过滤掉了。 这是一种合理的处理方式,而关于这部分的处理逻辑是通过在权限检查时通过
org.apache.hadoop.hbase.security.access.AccessControlFilter进行过滤实现的。这个Filter其实也非常简单,它是主要是通过
org.apache.hadoop.hbase.security.access.TableAuthManager.authorize(User, byte[], KeyValue, Action)进行最细度(精确的 qualifier)的检查,只有确定有权读写的qualifier才会通过检查,否则就被过滤掉。

6. Permission的Class Hierarchy:

Permission (包含了Action)

        |

        |--TablePermission (又包含了table,family,qualifier)

                    |

                    |--UserPermission(又包含了user)

7. 关于  cache:

AccessController在初始化的时候会load所有的permission,然后写到zookeeper里.参考:org.apache.hadoop.hbase.security.access.AccessController.initialize(RegionCoprocessorEnvironment)

同时, 一个ZooKeeper的监听器ZKPermissionWatcher会关注 ZooKeeper的任何变化,当Permission数据写入zookeeper时,方法org.apache.hadoop.hbase.security.access.ZKPermissionWatcher.nodeDataChanged(String)

会被触发,这个方法会负责把前面刚刚写入的Perssmion加载到缓存里!

Cache分为两类: 表级Cache和全局Cache.  表级Cache是一个以表名为Key,以这个表对应的<用户,权限>对为Value的Map, 而全局Cache 是指那些不针对某个具体表的全局Permission, 所以它的结构是一个<用户,权限>对组成的map. 关于全局Cache一个重要的细节是: 很显然, 所有的superuser是应该放在全局cache里,而且应被赋予所有权限.(参考:org.apache.hadoop.hbase.security.access.TableAuthManager.initGlobal(Configuration))

表级Cache:

TABLE_USER_CACHE: Map<TableName,Map<UserName,Permission>>
TABLE_GROUP_CACHE: Map<TableName,Map<UserName,Permission>>

全局Cache:

USER_CACHE:Map<USerName,Permission>
GROUP_CACHE: Map<TableName,Map<UserName,Permission>>

cache隶属于一个TableAuthManager实例, 而TableAuthManager是一个管理多个自身实例的单态, 它维护一个全局的map,这个map里一个ZooKeeperWatcher实例对应一个它的实例. 参考:org.apache.hadoop.hbase.security.access.TableAuthManager.get(ZooKeeperWatcher, Configuration)

8. ZooKeeperListener的典型应用案例:ZKPermissionWatcher

security的一个设计需求是:,所有region和master对应的coprocessor所依赖的authManager都需要加载所有的permission到cache里,通过内存中permission实例进行权限检查. security的实现方式是:当_acl_表对应的region open的时候,加载所有的permission(参考AcessController(L720-L723),当所有的permission加载之后,就把它们再写到zookeeper节点上,参考
org.apache.hadoop.hbase.security.access.AccessController.initialize(RegionCoprocessorEnvironment).

而由于所有的 authManager 实例都含有一个ZKPermissionWatcher,这是一个ZooKeeperListener, 当zookeeper节点上的数据发生变化时,这个watcher的nodeCreated方法会被触发,进而重新加载permission数据!

9. 关于AccessController和TableAuthManager与ZooKeeperWatcher的实例数量

对于AccessController来说,做为MasterObserver时, 会创建一个实例.作为BaseRegionObserver来说, 一个region(不是region server)会创建一个是实例!而TableAuthManager与ZooKeeperWatcher的实例是一一对应的,参考:

org.apache.hadoop.hbase.security.access.TableAuthManager.get(ZooKeeperWatcher, Configuration)

而ZooKeeperWatcher的实例自来于Master或Region启动( MasterObserver 的start方法和BaseRegionObserver的postOpen)时从MasterServices或RegionServerServices中取得的ZooKeeper的实例!而这个ZooKeeper实例是一个server(node)对应一个. 所以对于同一个regionserver上的所有region,引用的是同一个zookeeper实例.

Hadoop源码解析之: HBase Security的更多相关文章

  1. Hadoop源码解析之: TextInputFormat如何处理跨split的行

    我们知道hadoop将数据给到map进行处理前会使用InputFormat对数据进行两方面的预处理: 对输入数据进行切分,生成一组split,一个split会分发给一个mapper进行处理. 针对每个 ...

  2. Hadoop源码解析 1 --- Hadoop工程包架构解析

    1 Hadoop中各工程包依赖简述     Google的核心竞争技术是它的计算平台.Google的大牛们用了下面5篇文章,介绍了它们的计算设施.     GoogleCluster: http:// ...

  3. Hadoop源码解析之 rpc通信 client到server通信

    rpc是Hadoop分布式底层通信的基础,无论是client和namenode,namenode和datanode,以及yarn新框架之间的通信模式等等都是采用的rpc方式. 下面我们来概要分析一下H ...

  4. Spring Security 访问控制 源码解析

    上篇 Spring Security 登录校验 源码解析  分析了使用Spring Security时用户登录时验证并返回token过程,本篇分析下用户带token访问时,如何验证用户登录状态及权限问 ...

  5. Spring Security 解析(七) —— Spring Security Oauth2 源码解析

    Spring Security 解析(七) -- Spring Security Oauth2 源码解析   在学习Spring Cloud 时,遇到了授权服务oauth 相关内容时,总是一知半解,因 ...

  6. Spring Security源码解析一:UsernamePasswordAuthenticationFilter之登录流程

    一.前言 spring security安全框架作为spring系列组件中的一个,被广泛的运用在各项目中,那么spring security在程序中的工作流程是个什么样的呢,它是如何进行一系列的鉴权和 ...

  7. zookeeper集群搭建及Leader选举算法源码解析

    第一章.zookeeper概述 一.zookeeper 简介 zookeeper 是一个开源的分布式应用程序协调服务器,是 Hadoop 的重要组件. zooKeeper 是一个分布式的,开放源码的分 ...

  8. Flink 源码解析 —— 源码编译运行

    更新一篇知识星球里面的源码分析文章,去年写的,周末自己录了个视频,大家看下效果好吗?如果好的话,后面补录发在知识星球里面的其他源码解析文章. 前言 之前自己本地 clone 了 Flink 的源码,编 ...

  9. Flink 源码解析 —— 深度解析 Flink 是如何管理好内存的?

    前言 如今,许多用于分析大型数据集的开源系统都是用 Java 或者是基于 JVM 的编程语言实现的.最着名的例子是 Apache Hadoop,还有较新的框架,如 Apache Spark.Apach ...

随机推荐

  1. android JNI调用 execlp函数

    execlp()函数           execlp函数简单的来说就是C语言中执行系统命令的函数          execlp()会从PATH 环境变量所指的目录中查找符合参数file 的文件名, ...

  2. 为什么和其他语言相比C语言是快速的语言

    初入门的我们经常听见别人说"真正的程序员用C语言编程,C是最快的语言因为它是最靠近及其底层的语言."那么和其他语言相比C语言到底有什么特别的呢? C语言没有什么特别,这就是它快速的 ...

  3. LeeCode-Single Number II

    Given an array of integers, every element appears three times except for one. Find that single one. ...

  4. iptables or netfilter

    netfilter 内部有三个表:filter .nat .mangle 每个表又有不同的操作链: 1.在filter这个防火墙功能的表中有三个chain:INPUT.FORWARD.OUTPUT. ...

  5. IOS Custom NavigationItem --写titleView

    //先自己写一个titleView UIView *titleView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 20)];//all ...

  6. Expected authority at index 7: hdfs://

    hadoop版本:1.0.4 今天在跑TestForest的时候,居然出现了这个问题: Exception in thread "main" java.lang.IllegalAr ...

  7. Android集成科大讯飞SDK语音听写及语音合成功能实现

    前言 现在软件设计越来越人性化.智能化.一些常见的输入都慢慢向语音听写方向发展,一些常见的消息提示都向语音播报发展.所以语音合成和语音听写是手机软件开发必不可少的功能.目前国内这方面做的比较好的应该是 ...

  8. /boot磁盘空间不足,没盘扩展,只好删除旧内核了

    [xiejdm@localhost ~]$ uname -r -.el7.x86_64 [xiejdm@localhost ~]$ sudo rpm -qa | grep kernel kernel- ...

  9. python 3.5 之 单双三引号

    1. 单引号和双引号用法都是一样的,但是如果字符串里有相同的字符时要使用\进行转义 举例:1) print 'hello'2) print "hello"1和2,结果都是hello ...

  10. bootstrap之 Badge 角标

    添加 .am-badge class 到 <div> 或者 <span> 元素. 默认样式     <span class="am-badge"> ...