背景
- 在hive中进行表创建的时候,报无创建权限的错误,如下所示:
Caused by: org.apache.hadoop.hive.ql.security.authorization.plugin.HiveAccessControlException: Permission denied: user [hive] does not have [ALL] privilege on [hdfs://xxxxxxxxxx/xxxxxxxxxx/xxxxxxxxxx/xxxxxxxxxx/xxxxxxxxxx]
at org.apache.ranger.authorization.hive.authorizer.RangerHiveAuthorizer.checkPrivileges(RangerHiveAuthorizer.java:274) ~[?:?]
at org.apache.hadoop.hive.ql.Driver.doAuthorizationV2(Driver.java:974) ~[hive-exec-2.3.3.jar:2.3.3]
at org.apache.hadoop.hive.ql.Driver.doAuthorization(Driver.java:761) ~[hive-exec-2.3.3.jar:2.3.3]
at org.apache.hadoop.hive.ql.Driver.compile(Driver.java:550) ~[hive-exec-2.3.3.jar:2.3.3]
-
通过对代码的查看,发现hive用户虽有权限查看到对应的库表。但是在对库表进行创建和删除时,ranger这边检测对应的hdfs path及其子hdfs path均对hive用户有权限。
- 但是上述鉴权方式不符合我们实际集群的权限结果,我们仅需要:一级目录和登录用户一致即可,因此需要对ranger的代码进行修改。
代码修改
- 修改了hive plugin中的RangerHiveAuthorizer.checkPrivileges方法
if(hiveObjType == HiveObjectType.URI && isPathInFSScheme(path)) {
FsAction permission = getURIAccessType(hiveOpType);
boolean isURIAccessAllowed = Boolean.FALSE;
try {
//只针对创建表和创建表by select的操作
if(hiveOpType == HiveOperationType.CREATETABLE || hiveOpType == HiveOperationType.CREATETABLE_AS_SELECT){
Path filePath = new Path(path);
FileSystem fs = FileSystem.get(filePath.toUri(), getHiveConf());
FileStatus fileStatus = fs.getFileStatus(filePath);
LOG.info("Login user is "+user+",hdfs file owner is "+fileStatus.getOwner());
//如果登陆用户==文件属主的话则通过
if (user.equals(fileStatus.getOwner())){
isURIAccessAllowed = Boolean.TRUE;
}
}else{
//其它的非CREATE相关的操作还是走原来的鉴权方式
isURIAccessAllowed = isURIAccessAllowed(user, permission, path, getHiveConf());
}
}catch (IOException e){
LOG.error("Falied to verify user URL permissions,Caused by: "+ e);
}
if(!isURIAccessAllowed) {
throw new HiveAccessControlException(String.format("Permission denied: user [%s] does not have [%s] privilege on [%s]", user, permission.name(), path));
}
continue;
}