本文将以 hive-agent 为例,讲解 Apache Ranger 如何在 Hive 中实现行权限
整体架构
![](https://img.haomeiwen.com/i9252736/294a763fcb456e6c.png)
核心方法
HivePlugin.evalRowFilterPolicies 解析过滤规则,生成RangerAccessResult
RangerHiveAuthorizer.getRowFilterExpression 获取行过滤表达式
RangerHiveAuthorizer.applyRowFilterAndColumnMasking 将过滤表达式转化为HivePrivilegeObject
重写逻辑
TableMask.create
将select * from tableA转化为select * from (select * from tableA where col=filter)
public String create(HivePrivilegeObject privObject, MaskAndFilterInfo maskAndFilterInfo)
throws SemanticException {
boolean doColumnMasking = false;
boolean doRowFiltering = false;
StringBuilder sb = new StringBuilder();
// 如果需要对字段mask,下面进行字段转化
sb.append("(SELECT ");
boolean firstOne = true;
List<String> exprs = privObject.getCellValueTransformers();
if (exprs != null) {
if (exprs.size() != privObject.getColumns().size()) {
throw new SemanticException("Expect " + privObject.getColumns().size() + " columns in "
+ privObject.getObjectName() + ", but only find " + exprs.size());
}
List<String> colTypes = maskAndFilterInfo.colTypes;
for (int index = 0; index < exprs.size(); index++) {
String expr = exprs.get(index);
if (expr == null) {
throw new SemanticException("Expect string type CellValueTransformer in "
+ privObject.getObjectName() + ", but only find null");
}
if (!firstOne) {
sb.append(", ");
} else {
firstOne = false;
}
String colName = privObject.getColumns().get(index);
if (!expr.equals(colName)) {
// CAST(expr AS COLTYPE) AS COLNAME
sb.append("CAST(" + expr + " AS " + colTypes.get(index) + ") AS "
+ HiveUtils.unparseIdentifier(colName, conf));
doColumnMasking = true;
} else {
sb.append(HiveUtils.unparseIdentifier(colName, conf));
}
}
}
// 不进行mask的直接生成select * 的子查询
if (!doColumnMasking) {
sb = new StringBuilder();
sb.append("(SELECT *");
}
if (!maskAndFilterInfo.isView && !maskAndFilterInfo.isNonNative) {
// put all virtual columns in RowResolver.
Iterator<VirtualColumn> vcs = VirtualColumn.getRegistry(conf).iterator();
while (vcs.hasNext()) {
VirtualColumn vc = vcs.next();
sb.append(", " + vc.getName());
}
}
sb.append(" FROM ");
sb.append(HiveUtils.unparseIdentifier(privObject.getDbname(), conf));
sb.append(".");
sb.append(HiveUtils.unparseIdentifier(privObject.getObjectName(), conf));
sb.append(" " + maskAndFilterInfo.additionalTabInfo);
String filter = privObject.getRowFilterExpression();
if (filter != null) {
// 添加过滤条件
sb.append(" WHERE " + filter);
doRowFiltering = true;
}
sb.append(")" + HiveUtils.unparseIdentifier(maskAndFilterInfo.alias, conf));
if (!doColumnMasking && !doRowFiltering) {
// nothing to do
return null;
} else {
LOG.debug("TableMask creates `" + sb.toString() + "`");
return sb.toString();
}
}
网友评论