通过反射机制解决php端通过thrift传用户名密码鉴权问题

在启用了特定权限机制后,jdbc接口能够正常处理权限控制,但PHP端通过Thrift访问时遇到挑战。文章探讨了如何利用反射机制在Thrift调用中获取并验证HiveSession中的用户名和密码,以实现鉴权。
摘要由CSDN通过智能技术生成

由于启用了Hamza的权限机制,jdbc端已经可以正常控制权限,只需要按照jdbc的方式传送用户名和密码即可,但发现还有很多业务方是使用php的,他们只能通过thrift来访问hive。

jdbc方式的时候我们是将用户名和密码传到hiveconf中,服务通过sessionhook中解析出来的,但是thrift的方式最后放入的是HiveSession,我们只能通过反射访问到HiveSessionHookContext中的hiveSession私有属性,然后获取到用户名和密码:

public class HamzaSessionHook implements HiveSessionHook {
  private static final Logger LOG = LoggerFactory
      .getLogger(HamzaSessionHook.class);

  @Override
  public void run(HiveSessionHookContext sessionHookContext)
      throws HiveSQLException {
    HiveConf conf = sessionHookContext.getSessionConf();
    String usr = conf.get(HamzaConstants.HAMZA_HOOK_USR);    
    String passwd = conf.get(HamzaConstants.HAMZA_HOOK_PASSWD);
    String clientIP = conf.get(HamzaConstants.JDBC_CLIENT_IP);
    if (StringUtils.isEmpty(usr) && StringUtils.isEmpty(passwd)) {
      // 主要针对使用php客户端访问的时候获取用户名和密码: https://github.com/QwertyManiac/hive-hs2-php-thrift
      // 由于在HiveSessionHookContext私有属性中,需要通过反射来得到
      try {
        Field field = sessionHookContext.getClass().getDeclaredField("hiveSession");
        field.setAccessible(true);
        HiveSession session = (HiveSession) field.get(sessionHookContext);
        usr = session.getUsername();
        passwd = session.getPassword();
      } catch (Exception e) {
        LOG.error(e.getMessage(), e);
      } 
    }
    
    if (StringUtils.isEmpty(usr)) {
      usr = HamzaConstants.DEFAULT_EMPTY_VAL;
    }
    if (StringUtils.isEmpty(passwd)) {
      passwd = HamzaConstants.DEFAULT_EMPTY_VAL;
    }
    LOG.info(String
        .format(
            "Receiving a jdbc client request with the infomation[IP:%s, username:%s, passwd:******].",
            clientIP, usr));

    // store all the needs into the sessionState
    SessionState ss = SessionState.get();
    if (ss != null) {
      Map<String, String> hiveVars = ss.getHiveVariables();
      hiveVars.put(HamzaConstants.HAMZA_HOOK_LINK_FROM,
          HamzaConstants.DEFAULT_HOOK_LINK_FROM);
      hiveVars.put(HamzaConstants.JDBC_CLIENT_IP, clientIP);
      hiveVars.put(HamzaConstants.HAMZA_HOOK_USR, usr);
      hiveVars.put(HamzaConstants.HAMZA_HOOK_PASSWD, passwd);
    } else {
      LOG.error("SessionState is null.");
    }

  }

}


php端访问方式如下:

<?php
    require_once 'thrift/Thrift/ClassLoader/ThriftClassLoader.php';
    use Thrift\ClassLoader\ThriftClassLoader;
    $loader = new ThriftClassLoader();
    $loader->registerNamespace('Thrift', realpath(dirname(__FILE__)).'/thrift');
    $loader->registerDefinition('org\apache\hive\service\cli\thrift', realpath(dirname(__FILE__)).'/hive');
    $loader->register();
    use Thrift\Type\TType;
    use Thrift\Protocol\TBinaryProtocol;
    use Thrift\Transport\TSocket;
    use Thrift\Transport\TBufferedTransport;
    use org\apache\hive\service\cli\thrift\TCLIServiceClient;
    use org\apache\hive\service\cli\thrift\TOpenSessionReq;
    use org\apache\hive\service\cli\thrift\TCloseSessionReq;
    use org\apache\hive\service\cli\thrift\TExecuteStatementReq;
    use org\apache\hive\service\cli\thrift\TFetchResultsReq;
    try {
        $socket = new TSocket('192.169.45.4', '10000');
        $transport = new TBufferedTransport($socket);
        $protocol = new TBinaryProtocol($transport);
        // Create a HS2 client
        $client = new TCLIServiceClient($protocol);
        // Open up the connection
        $transport->open();
        echo "Opened transport\n";
        $sorq = new TOpenSessionReq();
        $sorq->username = "bigdata_hive";
        $sorq->password = "bmZY7y3smtNlRPq8";
        $rorq = $client->OpenSession($sorq);
        echo "Opened session\n";
        $sessionHandle = $rorq->sessionHandle;
        $execreq = new TExecuteStatementReq();
        $execreq->sessionHandle = $sessionHandle;
        $execreq->statement = "SHOW TABLES";
        $execresp = $client->ExecuteStatement($execreq);
        echo "Executed: ".$execreq->statement."\n";
        $opHandle = $execresp->operationHandle;
        $fetchreq = new TFetchResultsReq();
        $fetchreq->operationHandle = $opHandle;
        $fetchreq->maxRows = 10000;
        $fetchres = $client->FetchResults($fetchreq);
        echo "Results:\n";
        foreach ($fetchres->results->rows as &$row) {
            foreach ($row->colVals as $cols) {
                echo $cols->stringVal->value;
            }
            echo "\n";
        }
        $scrq = new TCloseSessionReq();
        $scrq->sessionHandle = $sessionHandle;
        $rcrq = $client->CloseSession($scrq);
        echo "Closed session\n";
        // And finally, we close connection
        $transport->close();
        echo "Closed transport\n";
    } catch (TException $tx) {
        echo "ThriftException: ".$tx->getMessage()."\r\n";
    }
?>



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值