背景
- 在hive中進(jìn)行表創(chuàng)建的時候蚪腋,報(bào)無創(chuàng)建權(quán)限的錯誤凸克,如下所示:
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]
-
通過對代碼的查看基跑,發(fā)現(xiàn)hive用戶雖有權(quán)限查看到對應(yīng)的庫表瞧挤。但是在對庫表進(jìn)行創(chuàng)建和刪除時锡宋,ranger這邊檢測對應(yīng)的hdfs path及其子hdfs path均對hive用戶有權(quán)限。
ranger中hdfs path鑒權(quán)核心辦法
目前owner必須等于登錄用戶 - 但是上述鑒權(quán)方式不符合我們實(shí)際集群的權(quán)限結(jié)果特恬,我們僅需要:一級目錄和登錄用戶一致即可执俩,因此需要對ranger的代碼進(jìn)行修改。
代碼修改
- 修改了hive plugin中的RangerHiveAuthorizer.checkPrivileges方法
if(hiveObjType == HiveObjectType.URI && isPathInFSScheme(path)) {
FsAction permission = getURIAccessType(hiveOpType);
boolean isURIAccessAllowed = Boolean.FALSE;
try {
//只針對創(chuàng)建表和創(chuàng)建表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相關(guān)的操作還是走原來的鑒權(quán)方式
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;
}