
# 配置HDFS应用安全认证
#### 场景说明
访问安全集群环境中的服务，需要先通过Kerberos安全认证。所以HDFS应用程序中需要写入安全认证代码，确保HDFS程序能够正常运行。
安全认证有两种方式：
- 命令行认证： 提交HDFS应用程序运行前，在HDFS客户端执行如下命令进行认证。
  **kinit** *组件业务用户*
  ![](https://support.huaweicloud.com/devg3-mrs/public_sys-resources/note_3.0-zh-cn.png)
  该方式仅适用于Linux操作系统，且安装了HDFS的客户端。
  
- 代码认证： 通过获取客户端的principal和keytab文件进行认证。
  注意修改代码中的***PRINCIPAL_NAME***变量为实际使用的值。
  ```
  private static final String PRINCIPAL_NAME = "hdfsDeveloper";
  ```
  
 
#### 安全认证代码
目前样例代码统一调用LoginUtil类进行安全认证。
在HDFS样例工程代码中，不同的样例工程，使用的认证代码不同，包括基本安全认证和带ZooKeeper认证。
- 基本安全认证：
  com.huawei.bigdata.hdfs.examples包的HdfsExample类样例程序不需要访问HBase或ZooKeeper，所以使用基本的安全认证代码即可。示例代码如下：
  ```
  ...
      private static final String PATH_TO_HDFS_SITE_XML = HdfsExample.class.getClassLoader().getResource("hdfs-site.xml").getPath();
      private static final String PATH_TO_CORE_SITE_XML = HdfsExample.class.getClassLoader().getResource("core-site.xml").getPath();
      private static final String PRINCIPAL_NAME = "hdfsDeveloper";
      private static final String PATH_TO_KEYTAB = HdfsExample.class.getClassLoader().getResource("user.keytab").getPath();
      private static final String PATH_TO_KRB5_CONF = HdfsExample.class.getClassLoader().getResource("krb5.conf").getPath();
      private static Configuration conf = null;
      //private static String PATH_TO_SMALL_SITE_XML = HdfsExample.class.getClassLoader().getResource("smallfs-site.xml").getPath();
  ...
      private static void confLoad() throws IOException {
          System.setProperty("java.security.krb5.conf", PATH_TO_KRB5_CONF);
          conf = new Configuration();
          // conf file
          conf.addResource(new Path(PATH_TO_HDFS_SITE_XML));
          conf.addResource(new Path(PATH_TO_CORE_SITE_XML));
          // conf.addResource(new Path(PATH_TO_SMALL_SITE_XML));
      }
  ...
      private static void authentication() throws IOException {
          // security mode
          if ("kerberos".equalsIgnoreCase(conf.get("hadoop.security.authentication"))) {
              System.setProperty("java.security.krb5.conf", PATH_TO_KRB5_CONF);
              LoginUtil.login(PRINCIPAL_NAME, PATH_TO_KEYTAB, PATH_TO_KRB5_CONF, conf);
          }
      }
  ```
  
- 带ZooKeeper认证： com.huawei.bigdata.hdfs.examples包的"ColocationExample"类样例程序不仅需要基础安全认证，还需要添加ZooKeeper服务端Principal才能完成安全认证。示例代码如下：
  ```
  ...
      private static final String ZOOKEEPER_SERVER_PRINCIPAL_KEY = "zookeeper.server.principal";
      private static final String PRINCIPAL = "username.client.kerberos.principal";
      private static final String KEYTAB = "username.client.keytab.file";
      private static final String PRINCIPAL_NAME = "hdfsDeveloper";
      private static final String LOGIN_CONTEXT_NAME = "Client";
      private static final String PATH_TO_KEYTAB = System.getProperty("user.dir") + File.separator + "conf" + File.separator + "user.keytab";
      private static final String PATH_TO_KRB5_CONF = ColocationExample.class.getClassLoader().getResource("krb5.conf") .getPath();
      private static String zookeeperDefaultServerPrincipal = null;
      private static Configuration conf = new Configuration();
      private static DFSColocationAdmin dfsAdmin;
      private static DFSColocationClient dfs;
      private static void init() throws IOException {
          LoginUtil.login(PRINCIPAL_NAME, PATH_TO_KEYTAB, PATH_TO_KRB5_CONF, conf);
          LoginUtil.setJaasConf(LOGIN_CONTEXT_NAME, PRINCIPAL_NAME, PATH_TO_KEYTAB);
          zookeeperDefaultServerPrincipal = "zookeeper/hadoop." + KerberosUtil.getKrb5DomainRealm().toLowerCase();
          LoginUtil.setZookeeperServerPrincipal(ZOOKEEPER_SERVER_PRINCIPAL_KEY, zookeeperDefaultServerPrincipal);
      }
  ...
  ```
  
 
![](https://support.huaweicloud.com/devg3-mrs/public_sys-resources/note_3.0-zh-cn.png)
- 以上安全认证代码中的hdfsDeveloper用户及该用户的user.keytab、krb5.conf为示例，实际操作时请联系管理员获取相应权限的账号以及对应该账号的keytab文件和krb5文件。
- 用户可登录FusionInsight Manager，单击"系统 \> 权限 \> 域和互信"，查看"本端域"参数，即为当前系统域名。
- "zookeeper/hadoop.*\<系统域名\>*"为用户名，用户的用户名所包含的系统域名所有字母为小写。例如"本端域"参数为"9427068F-6EFA-4833-B43E-60CB641E5B6C.COM"，用户名为"zookeeper/hadoop.9427068f-6efa-4833-b43e-60cb641e5b6c.com"。
 
