
# HBase数据读写示例安全认证（单集群场景）
#### 场景说明
在安全集群环境下，各个组件之间的相互通信不能够简单地互通，而需要在通信之前进行相互认证，以确保通信的安全性。HBase应用开发需要进行ZooKeeper和Kerberos安全认证。用于ZooKeeper认证的文件为"jaas.conf"，用于Kerberos安全认证文件为keytab文件和krb5.conf文件。具体使用方法在样例代码的"README.md"中会有详细说明。
![](https://support.huaweicloud.com/devg-lts-mrs/public_sys-resources/note_3.0-zh-cn.png)
- jaas.conf文件请参考[获取MRS应用开发样例工程](https://support.huaweicloud.com/devg-lts-mrs/mrs_07_010002.html)，进入"src/hbase-examples/hbase-zk-example/src/main/resources/"路径下获取。
- keytab和krb5.conf文件获取方法请参考[准备MRS应用开发用户](https://support.huaweicloud.com/devg-lts-mrs/mrs_07_020002.html)。
 
安全认证主要采用代码认证方式。支持Oracle JAVA平台和IBM JAVA平台。
- 代码认证，以下代码在"com.huawei.bigdata.hbase.examples"包的"TestMain"类中：
  MRS 3.2.0-LTS.1版本：
  ```
  try {
     init();
     login();
     } 
  catch (IOException e) {
     LOG.error("Failed to login because ", e);
     return;
  }
  ```
  MRS 3.5.0-LTS及之后版本：
  ```
  try {
  // keytab authentication (default authentication)
  login();
  // basic authentication
  // basicLogin();
  } catch (IOException e) {
  LOG.error("Failed to login because ", e);
  return;
  }
  ```
  
- 初始化配置
  - MRS 3.2.0-LTS.1版本，以下代码在"com.huawei.bigdata.hbase.examples"包的"TestMain"类中
    ```
    private static void init() throws IOException {
            // Default load from conf directory
            conf = HBaseConfiguration.create();
            //In Windows environment
            String userdir = TestMain.class.getClassLoader().getResource("conf").getPath() + File.separator;[1]
            //In Linux environment
            //String userdir = System.getProperty("user.dir") + File.separator + "conf" + File.separator;
            conf.addResource(new Path(userdir + "core-site.xml"), false);
            conf.addResource(new Path(userdir + "hdfs-site.xml"), false);
            conf.addResource(new Path(userdir + "hbase-site.xml"), false);
    }
    ```
    \[1\]**userdir**获取的是编译后资源路径下conf目录的路径。将初始化需要的配置文件"core-site.xml"、"hdfs-site.xml"、"hbase-site.xml"和用于安全认证的用户凭证文件放置到"src/main/resources"的目录下。
    
  
  - MRS 3.5.0-LTS及之后版本，以下代码在"com.huawei.hadoop.security"包的"Utils.java"类中。
    在login()或basicLogin()方法中，通过conf = Utils.createClientConf();进行调用以初始化配置。
    ```
    public static Configuration createClientConf() {
    // In Windows environment
    String userDir = Utils.class.getClassLoader().getResource(CONF_DIRECTORY).getPath() + File.separator;
    // In Linux environment
    // String userDir = System.getProperty("user.dir") + File.separator + CONF_DIRECTORY + File.separator;
    return createConfByUserDir(userDir);
    }
    public static Configuration createConfByUserDir(String userDir) {
    // Default load from conf directory
    Configuration conf = HBaseConfiguration.create();
    if (userDir == null || userDir.isEmpty()) {
    return conf;
    }
    conf.addResource(new Path(userDir + CLIENT_CORE_FILE), false);
    conf.addResource(new Path(userDir + CLIENT_HDFS_FILE), false);
    conf.addResource(new Path(userDir + CLIENT_HBASE_FILE), false);
    return conf;
    }
    ```
    **userDir**获取的是编译后资源路径下conf目录的路径。
    
   
- 安全登录
  - 使用keytab进行安全认证登录
    - MRS 3.2.0-LTS.1版本 请根据实际情况，修改"userName"为实际用户名，例如"developuser"。
      在Windows环境下和Linux环境下请使用对应的路径获取方式。
      ```
      private static void login() throws IOException {
              if (User.isHBaseSecurityEnabled(conf)) {
                  userName = "hbaseuser1";
                 
                  //In Windows environment
                  String userdir = TestMain.class.getClassLoader().getResource("conf").getPath() + File.separator;
                  //In Linux environment
                  //String userdir = System.getProperty("user.dir") + File.separator + "conf" + File.separator;
       
                  /*
                   * if need to connect zk, please provide jaas info about zk. of course,
                   * you can do it as below:
                   * System.setProperty("java.security.auth.login.config", confDirPath +
                   * "jaas.conf"); but the demo can help you more : Note: if this process
                   * will connect more than one zk cluster, the demo may be not proper. you
                   * can contact us for more help
                   */
                  LoginUtil.setJaasConf(ZOOKEEPER_DEFAULT_LOGIN_CONTEXT_NAME, userName, userKeytabFile);
                  LoginUtil.login(userName, userKeytabFile, krb5File, conf);
              }
      }
      ```
      
    
    - MRS 3.5.0-LTS及之后版本
      请根据实际情况，在"com.huawei.bigdata.hbase.examples"包的"TestMain"类中修改以下参数：
      - 修改"userName"为实际用户名，例如"hbaseuser"。
      
      - 修改"ZOOKEEPER_DEFAULT_SERVER_PRINCIPAL"为"zookeeper/hadoop.*集群域名*"，集群域名可登录FusionInsight Manager，选择"系统 \> 权限 \> 域和互信"，查看"本端域"参数获取。
      
      
      ```
      private static final String USER_NAME = "hbaseuser";
      private static void login() throws IOException {
      conf = Utils.createClientConf();
      if (User.isHBaseSecurityEnabled(conf)) {
      // In Windows environment
      String userDir = TestMain.class.getClassLoader().getResource(Utils.CONF_DIRECTORY).getPath() + File.separator;
      // In Linux environment
      // String userDir = System.getProperty("user.dir") + File.separator + Utils.CONF_DIRECTORY + File.separator;
      String userKeytabFile = userDir + USER_KEYTAB_FILE;
      String krb5File = userDir + KRB5_CONF_FILE;
      /*
       * if need to connect zk, please provide jaas info about zk. of course,
       * you can do it as below:
       * System.setProperty("java.security.auth.login.config", confDirPath +
       * "jaas.conf"); but the demo can help you more : Note: if this process
       * will connect more than one zk cluster, the demo may be not proper. you
       * can contact us for more help
       */
      LoginUtil.setJaasConf(ZOOKEEPER_DEFAULT_LOGIN_CONTEXT_NAME, USER_NAME, userKeytabFile);
      LoginUtil.setZookeeperServerPrincipal(ZOOKEEPER_SERVER_PRINCIPAL_KEY, ZOOKEEPER_DEFAULT_SERVER_PRINCIPAL);
      LoginUtil.login(USER_NAME, userKeytabFile, krb5File, conf);
      }
      }
      ```
      
     
  
  - 使用Basic方式进行安全认证登录（仅适用于MRS 3.6.0-LTS及之后版本）
    - 需开启HBase Basic认证功能，具体操作请参考[开启HBase Basic认证功能](https://support.huaweicloud.com/cmpntguide-lts-mrs/mrs_01_300663.html)章节。
    
    - Thrift、Rest、Phoenix连接及开源客户端不支持Basic认证。
    
    
    ```
    private static void basicLogin() throws IOException {
    conf = Utils.createClientConf();
    if (User.isHBaseSecurityEnabled(conf)) {
    UserGroupInformation.setConfiguration(conf);
    /*
      Set basic auth configurations
     */
    conf.set("hbase.basic.auth.username", "hbaseuser");
    conf.set("hbase.basic.auth.password", "xxxxx");
    }
    }
    ```
    "hbase.basic.auth.username"为用于进行Basic认证的用户名，"hbase.basic.auth.password"为对应的用户密码。
    
   
 
