目前的hive版本是支持authentication和authorization的(再加上计费就是3A了,哈哈),
在hive的java.org.apache.hadoop.hive.conf.HiveConf类中定义的权限相关的设置项有:
HIVE_AUTHORIZATION_ENABLED("hive.security.authorization.enabled", false), //是否开启权限验证 HIVE_AUTHORIZATION_MANAGER("hive.security.authorization.manager", "org.apache.hadoop.hive.ql.security.authorization.DefaultHiveAuthorizationProvider"), //默认的授权实现类 HIVE_AUTHENTICATOR_MANAGER("hive.security.authenticator.manager", // 默认的认证实现类 "org.apache.hadoop.hive.ql.security.HadoopDefaultAuthenticator"), HIVE_METASTORE_AUTHORIZATION_MANAGER("hive.security.metastore.authorization.manager", //metasotre服务的权限验证 "org.apache.hadoop.hive.ql.security.authorization." + "DefaultHiveMetastoreAuthorizationProvider"), HIVE_METASTORE_AUTHENTICATOR_MANAGER("hive.security.metastore.authenticator.manager", "org.apache.hadoop.hive.ql.security.HadoopDefaultMetastoreAuthenticator"), HIVE_AUTHORIZATION_TABLE_USER_GRANTS("hive.security.authorization.createtable.user.grants", ""), //下面4项会对创建表的权限的定义,这里有个bug,之前已经fix HIVE_AUTHORIZATION_TABLE_GROUP_GRANTS("hive.security.authorization.createtable.group.grants", ""), HIVE_AUTHORIZATION_TABLE_ROLE_GRANTS("hive.security.authorization.createtable.role.grants", ""), HIVE_AUTHORIZATION_TABLE_OWNER_GRANTS("hive.security.authorization.createtable.owner.grants", ""),
authenticator相关代码在org.apache.hadoop.hive.ql.security包
简单说明如下
1.HiveAuthenticationProvider 是一个扩展了Configurable的接口,实现类主要需要实现getUserName和getUserName方法
2.SessionStateConfigUserAuthenticator 实现了HiveAuthenticationProvider接口,用来做测试和debug的,主要是getUserName方法:
public String getUserName() { String newUserName = sessionState.getConf().get("user.name" , "" ).trim(); // 是根据user.name的设置获取user if (newUserName.isEmpty()) { return System. getProperty("user.name"); // 如果为空,根据System.getProperty( "user.name")设置user, 可以获取通过-D<name>=<value>设置,没有设置时为当前登录用户 } else { return newUserName; } }
3.SessionStateUserAuthenticator实现了HiveAuthenticationProvider接口,是hiveserver2 用来做验证的类
4.ProxyUserAuthenticator 扩展了HadoopDefaultAuthenticator ,重写了setConf方法,主要调用了UserGroupInformation类的createRemoteUser方法,可以做代理用户类(根据proxy.user.name的设置获取username)
5.因为默认hive.security.authenticator.manager的设置时org.apache.hadoop.hive.ql.security.HadoopDefaultAuthenticator,因此我们主要看的还是在HadoopDefaultAuthenticator类中,主要的方法时setConf方法
public void setConf(Configuration conf) { this. conf = conf; UserGroupInformation ugi = null; try { ugi = ShimLoader.getHadoopShims().getUGIForConf(conf); } catch (Exception e) { throw new RuntimeException(e); } if (ugi == null) { throw new RuntimeException( "Can not initialize HadoopDefaultAuthenticator." ); } this. userName = ShimLoader.getHadoopShims().getShortUserName(ugi); if (ugi.getGroupNames() != null) { this. groupNames = Arrays.asList(ugi.getGroupNames()); } }
根据分析代码,hive用来做认证的用户是在第一个命令运行时进行初始化的(后面即使通过设置也不会生效)因为在hive cli启动时,会读取.hiverc文件运行CREATE TEMPORARY FUNCTION xxxx,在第一个create xxx运行时,在命令的compile阶段(即Driver.compile()方法):
if (HiveConf.getBoolVar(conf, HiveConf.ConfVars.HIVE_AUTHORIZATION_ENABLED)) { // 判断hive.security.authorization.enabled是否设置为true try { perfLogger.PerfLogBegin(CLASS_NAME, PerfLogger.DO_AUTHORIZATION); doAuthorization(sem); // 如果开启了验证,则调用doAuthorization方法 } catch (AuthorizationException authExp) { console.printError("Authorization failed:" + authExp.getMessage() + ". Use SHOW GRANT to get more details."); errorMessage = authExp.getMessage(); SQLState = "42000"; return 403; } finally { perfLogger.PerfLogEnd(CLASS_NAME, PerfLogger.DO_AUTHORIZATION); } }
doAuthorization方法
private void doAuthorization(BaseSemanticAnalyzer sem) throws HiveException, AuthorizationException { HashSet<ReadEntity> inputs = sem.getInputs(); HashSet<WriteEntity> outputs = sem.getOutputs(); SessionState ss = SessionState.get(); HiveOperation op = ss.getHiveOperation(); // 判断操作类型 Hive db = sem.getDb(); if (ss.isAuthorizationModeV2()) { // 如果为v2时,调用doAuthorizationV2方法,而SessionState.isAuthorizationModeV2方法调用了SessiontState.getAuthorizationMode方法 doAuthorizationV2(ss, op, inputs, outputs); return; } if (op == null) { throw new HiveException("Operation should not be null"); } if (op.equals(HiveOperation.CREATEDATABASE)) { //下面的代码是做具体的验证操作,涉及到authorizator类 ss.getAuthorizer().authorize( ...
SessionState.isAuthorizationModeV2和SessiontState.getAuthorizationMode方法:
public AuthorizationMode getAuthorizationMode(){ //判断Authorization的类型(v1 or v2) setupAuth(); //调用SessiontState.setupAuth方法 if(authorizer != null){ return AuthorizationMode. V1; }else if(authorizerV2 != null){ return AuthorizationMode. V2; } //should not happen - this should not get called before this.start() is called throw new AssertionError("Authorization plugins not initialized!" ); } public boolean isAuthorizationModeV2(){ return getAuthorizationMode() == AuthorizationMode. V2; }
SessiontState的setupAuth方法:
private void setupAuth() { if (authenticator != null) { // 如果已经初始化过就直接返回,这里导致后面即使手动设置用户也不会生效 // auth has been initialized return; } try { authenticator = HiveUtils.getAuthenticator(conf, HiveConf.ConfVars.HIVE_AUTHENTICATOR_MANAGER);// 调用HiveUtils.getAuthenticator方法生成一个对应类的实例 authenticator.setSessionState(this); authorizer = HiveUtils.getAuthorizeProviderManager(conf, HiveConf.ConfVars.HIVE_AUTHORIZATION_MANAGER, authenticator, true);
.....
HiveUtils的getAuthenticator方法是用ReflectionUtils.newInstance生成org.apache.hadoop.hive.ql.security.HadoopDefaultAuthenticator类的实例,然后调用实例的setConf方法,设置hive的用户和组信息.
整个的调用顺序:
Driver.compile--->Driver.doAuthorization--->SessionState.isAuthorizationModeV2----> SessiontState.getAuthorizationMode--->SessionState.setupAuth --->HiveUtils.getAuthenticator+HiveUtils--->HadoopDefaultAuthenticator.setConf
需要注意的是:
1)这个账号控制的是hive的权限,和hdfs的权限无关,这两个需要区别开
2)在第一个命令的时候初始化,后面不再初始化
3)具体的验证操作是由HiveAuthorizationProvider的具体实现类的authorize完成