HBase源码分析之权限验证中讲过了自带的simple认证方式,Apache有个项目,也提供了权限验证,就是Ranger。Ranger的安装方式比较复杂,具体看: https://cwiki.apache.org/confluence/display/RANGER/Apache+Ranger+0.5.0+Installation
个人感觉Ranger还是一个粗糙的应用,和我预期的Apache顶级项目有差距,代码没注释,格式也很混乱。
Ranger的权限管理是通过RangerAuthorizationCoprocessor来实现的,实现了MasterObserver、RegionServerObserver、RegionObserver、BulkLoadObserver,各种回调。
和HBase的grant、revoke同步
配置中配置了grant、revoke的时候,是否相应的刷新ranger的标记位UpdateRangerPoliciesOnGrantRevoke
UpdateRangerPoliciesOnGrantRevoke = RangerConfiguration.getInstance().getBoolean(RangerHadoopConstants.HBASE_UPDATE_RANGER_POLICIES_ON_GRANT_REVOKE_PROP, RangerHadoopConstants.HBASE_UPDATE_RANGER_POLICIES_ON_GRANT_REVOKE_DEFAULT_VALUE);
RangerAuthorizationCoprocessor实现了CoprocessorService接口,将自己注册进去,监听grant、revoke。
@Override
public Service getService() {
return AccessControlProtos.AccessControlService.newReflectiveService(this);
}
实现了这2个方法,在这2个方法中判断UpdateRangerPoliciesOnGrantRevoke如果为true,就更新下自己的配置。
/**
* <code>rpc Grant(.GrantRequest) returns (.GrantResponse);</code>
*/
public abstract void grant(
com.google.protobuf.RpcController controller,
org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.GrantRequest request,
com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.GrantResponse> done);
/**
* <code>rpc Revoke(.RevokeRequest) returns (.RevokeResponse);</code>
*/
public abstract void revoke(
com.google.protobuf.RpcController controller,
org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.RevokeRequest request,
com.google.protobuf.RpcCallback<org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.RevokeResponse> done);
Policy生效规则
各种操作之前调用evaluateAccess,代码简直裹脚布,总结起来就是判断了Namespace、table、column、qualifier的设置,将所有设置集中到AuthorizationSession中,然后调用AuthorizationSession的authorize,判断权限。
ColumnFamilyAccessResult evaluateAccess(String operation, Action action, final RegionCoprocessorEnvironment env,
final Map<byte[], ? extends Collection<?>> familyMap) throws AccessDeniedException {
String access = _authUtils.getAccess(action);
User user = getActiveUser();
String userName = _userUtils.getUserAsString(user);