HIVE 身份验证

简介

hive 默认状况下访问hiveserver2 是不须要身份验证的。html

hive用户登陆身份验证方式

默认是NONE
具备 KERBEROS LDAP PAM NOSASL CUSTOM 五中验证
java

hive-0.14 对应代码处: org.apache.hive.service.auth.HiveAuthFactorymysql



本文主要针对CUSTOM 方式(方便,有效)
sql


继承接口 (PasswdAuthenticationProvider)


接口实现

 
package com.bfd.dw.plugin.hive;
import org.apache.hadoop.conf.Configurable;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hive.conf.HiveConf;
import org.apache.hive.service.auth.PasswdAuthenticationProvider;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import javax.security.sasl.AuthenticationException;import java.sql.*;
import java.util.Map;import java.util.HashMap;
/** * Hive CUSTOM 受权 
* <p> 
* * @author : wenting.wang 
* @date : 2016年10月12日 
*/
public class AuthLogin implements PasswdAuthenticationProvider, Configurable
 {
       private Configuration conf = null;
       private static Logger LOG = LoggerFactory.getLogger(AuthLogin.class); 
       private String url; 
       private String user; 
       private String pwd; 
       private final static String driver = "com.mysql.jdbc.Driver";
       private Connection conn; //查询dw 数据库中hive的db用户 
       private String query = "SELECT * FROM db_user"; 

       public AuthLogin() { 
           LOG.info("AuthLogin init"); //从hive-site.xml 获取dw 的数据库信息 
           url = getConf().get("hive.dw.mysql.url"); 
           user = getConf().get("hive.dw.mysql.user");
           pwd = getConf().get("hive.dw.mysql.pwd"); 
           LOG.info(String.format("hive dw url:%s, user:%s, pwd:%s", url, user, pwd)); 
        } 

        @Override 
        public Configuration getConf() {
            if (this.conf == null) { 
                HiveConf conf = new HiveConf(); 
                this.conf = new Configuration(conf); 
           } 
           return this.conf;
        } 

        public Connection getConnection() throws SQLException {
            try { 
                 Class.forName(driver); 
                 if (conn == null) { 
                    conn = DriverManager.getConnection(url, user, pwd);//获取链接对象 
                    conn.setAutoCommit(false); 
                } 
                return conn; 
               } catch (Exception e) { 
                   LOG.error("get dw mysql connection failed", e); 
                   throw new SQLException("Connect error!");
                } 
          } 

         private Map<String, String> queryUser() { 
             Map<String, String> userPass = new HashMap<>(); 
             try { 
                 getConnection();
                 Statement st = conn.createStatement();
                 ResultSet rs = st.executeQuery(query); 
                 while (rs.next()) { 
                     String name = rs.getString("name"); 
                     String password = rs.getString("password");             
                     userPass.put(name, password);
                 }
                 st.close(); 
                 } catch (Exception e) {
                     LOG.error("get dw mysql user failed", e); //若是出现异常,设置为null,下次从新获取链接 
                     conn = null; 
                 } 
                 return userPass; 
            } 
           @Override 
           public void setConf(Configuration arg0) { this.conf = arg0; }
          @Override 
          public void Authenticate(String username, String password) throws AuthenticationException { 
              if (username == null || password == null) {
                  throw new AuthenticationException("error.");
              } 
              LOG.info("user: " + username + " try login.");
              Map<String, String> userPass = queryUser();
              if (!userPass.containsKey(username)) { 
                  String message = "user name not exist:"; 
                  throw new AuthenticationException(message); 
              } else {
                 if (!password.equals(userPass.get(username))){ 
                      String message = "user name and password is mismatch. user:" + username; throw new AuthenticationException(message); 
                 } 
              } 
              LOG.info("user " + username + " login system successfully."); 
      }
 }

配置文件hive-site.xml

<property>
    <name>hive.server2.authentication</name>
    <value>CUSTOM</value>
  </property>
    <property>
    <name>hive.server2.custom.authentication.class</name>
    <value>com.bfd.auth.hive.AuthLogin</value>
  </property>
  <property>
    <name>hive.dw.mysql.url</name>
    <value>jdbc:mysql://172.18.1.22:3306/data_warehouse</value>
  </property>
    <property>
    <name>hive.dw.mysql.user</name>
    <value>admin</value>
  </property>
    <property>
    <name>hive.dw.mysql.pwd</name>
    <value>admin@daydayup</value>
  </property>


测试验证:

首先将编译的包上传到 $HIVE_HOME/lib/ 中
验证:数据库

注意点:hive0.14 版本的时候mvn 报错(0.9.2-incubating-SNAPSHOT is missing), 处理方法见下面pom.xml 更改calcite 版本
<dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-common</artifactId>
            <version>2.6.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hive</groupId>
            <artifactId>hive-cli</artifactId>
            <version>${hive.version}</version>
        </dependency>

        <dependency>
            <groupId>org.apache.calcite</groupId>
            <artifactId>calcite-core</artifactId>
            <version>1.0.0-incubating</version>
        </dependency>
        <dependency>
            <groupId>org.apache.calcite</groupId>
            <artifactId>calcite-avatica</artifactId>
            <version>1.0.0-incubating</version>
        </dependency>

参考文档:

https://cwiki.apache.org/confluence/display/Hive/Setting+Up+HiveServer2apache