您的位置:首页 > 其它

hive集成kerberos问题1

2014-03-21 23:39 218 查看
在hdfs+mapred+impala+kerberos运行正常后,开始测试hive+kerberos。hive0.11之后开始支持kerberos的验证,hive主要有两种访问方式,一种方法是shell运行,即直接运行hive命令,另一种方法时启动hiveserver,然后通过jdbc或odbc进行验证,其中第二种方法可以通过hive0.11的beeline进行测试。在使用hive shell运行时,主要遇到下面几个问题:1.权限验证问题。在hive操作hdfs数据的时候,权限是分为两层的,一个是hive层面的权限控制,主要是控制表的权限,一个是hdfs文件的权限控制,控制用户的读写操作。表的相关权限主要是写在hive的元数据库中,主要是TBL_PRIVS表(控制表的权限)和DB_PRIVS 表(控制库的权限)。在开启kerberos之后,传入hive的用户名是principal的全名,比如hdfs/gxxxx@KERBEROS_HADOOP,而hive权限表中的PRINCIPAL_NAME 字段是hdfs,会导致没有表的权限,虽然可以通过update表来更改相应的PRINCIPAL_NAME 的值,但是实际使用中缺乏可运维性。在hdfs层面,有一个user mapping的功能(由hadoop.security.auth_to_local参数控制),默认会把principal的全名进行map,转换为unix的用户名形式。
2.hook的问题。由于hive有grant的bug,因此线上使用了hook来做用户验证,即执行grant语法是会判断当前用户是否是hdfs用户,如果不是则报错,主要的代码如下(老毕提供):
import java.util.HashSet;
import org.apache.hadoop.hive.ql.parse.ASTNode;
import org.apache.hadoop.hive.ql.parse.AbstractSemanticAnalyzerHook;
import org.apache.hadoop.hive.ql.parse.HiveParser;
import org.apache.hadoop.hive.ql.parse.HiveSemanticAnalyzerHookContext;
import org.apache.hadoop.hive.ql.parse.SemanticException;
import org.apache.hadoop.hive.ql.session.SessionState;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class AuthHook extends AbstractSemanticAnalyzerHook {
static final private Log LOG = LogFactory.getLog(AuthHook.class.getName());
private static HashSet<String> adminlist = new HashSet<String>() {
{add("hdfs");}
};
private static String adminstr = "hdfs";
@Override
public ASTNode preAnalyze(HiveSemanticAnalyzerHookContext context,
ASTNode ast) throws SemanticException {
switch (ast.getToken().getType()) {
case HiveParser.TOK_CREATEDATABASE:
case HiveParser.TOK_DROPDATABASE:
case HiveParser.TOK_CREATEROLE:
case HiveParser.TOK_DROPROLE:
case HiveParser.TOK_GRANT:
case HiveParser.TOK_REVOKE:
case HiveParser.TOK_GRANT_ROLE:
case HiveParser.TOK_REVOKE_ROLE:
String userName = null;
if (SessionState.get() != null && SessionState.get().getAuthenticator() != null) {
userName = SessionState.get().getAuthenticator().getUserName();
}
LOG.debug("authhook username = "+userName);
if (!adminlist.contains(userName.toLowerCase())) {
throw new SemanticException("User:"+userName
+ " isn't ADMIN, please ask for " + adminstr + ".");
}
break;
default:
LOG.debug("AST type = "+ast.getToken().getType());
break;
}
return ast;
}
}

其中获取当前传入的用户名是通过 SessionState.get().getAuthenticator().getUserName();集成了kerberos之后,在实际使用中会报 FAILED: SemanticException User:hdfs/xxxxx@KERBEROS_HADOOP isn't ADMIN, please ask for hdfs.的错误。
这两个问题的解决,借鉴了点评的patch:https://github.com/dianping/hive/commit/aefaafd708138048fb52d4a857a1bdcca34d2bb1即把ql/src/java/org/apache/hadoop/hive/ql/security/HadoopDefaultAuthenticator.java 中的this.userName = ugi.getUserName();改为this.userName = ShimLoader.getHadoopShims().getShortUserName(ugi);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  hivecli kerberos问题