
# 配置Spark应用安全认证
#### 场景说明
在安全集群环境下，各个组件之间的相互通信不能够简单地互通，而需要在通信之前进行相互认证，以确保通信的安全性。
用户在开发Spark应用程序时，某些场景下，需要Spark与Hadoop、HBase等之间进行通信。那么Spark应用程序中需要写入安全认证代码，确保Spark程序能够正常运行。
安全认证有三种方式：
- 命令认证： 提交Spark应用程序运行前，或者在使用CLI连接SparkSQL前，在Spark客户端执行如下命令获得认证。
  kinit*组件业务用户*
  
- 配置认证： 可以通过以下3种方式的任意一种指定安全认证信息。
  - 在客户端的"spark-defaults.conf"配置文件中，配置"spark.kerberos.keytab"和"spark.kerberos.principal"参数指定认证信息。
  
  - 执行bin/spark-submit的命令中添加如下参数来指定认证信息。
    --conf spark.kerberos.keytab=*\<keytab文件路径\>* --conf spark.kerberos.principal=*\<Principal账号\>*
    
  
  - 执行bin/spark-submit的命令中添加如下参数来指定认证信息。
    --keytab*\<keytab文件路径\>* --principal*\<Principal账号\>*
    
   
- 代码认证： 通过获取客户端的principal和keytab文件在应用程序中进行认证。
  
在安全集群环境下，样例代码需要使用的认证方式如[表1]所示：
 表1安全认证方式 
| 样例代码                                                                                  | 模式           | 安全认证方式                 |
|:---|:---|:---|
| sparknormal-examples                                                                  | yarn-client  | 命令认证、配置认证或代码认证，三种任选一种。 |
| sparknormal-examples                                                                  | yarn-cluster | 命令认证或者配置认证，两种任选一种。     |
| sparksecurity-examples （已包含安全认证代码） | yarn-client  | 代码认证。                  |
| sparksecurity-examples （已包含安全认证代码） | yarn-cluster | 不支持。                   |
   
![](https://support.huaweicloud.com/devg3-mrs/public_sys-resources/note_3.0-zh-cn.png)
- 如上表所示，yarn-cluster模式中不支持在Spark工程代码中进行安全认证，因为需要在应用启动前已完成认证。
- 未提供Python样例工程的安全认证代码，推荐在运行应用程序命令中设置安全认证参数。
 
#### 安全认证代码（Java版）
目前样例代码统一调用LoginUtil类进行安全认证。安全登录流程请参见安全认证接口章节。
在Spark样例工程代码中，不同的样例工程，使用的认证代码不同，基本安全认证或带ZooKeeper认证。样例工程中使用的示例认证参数如[表2]所示，请根据实际情况修改对应参数值。
 表2参数描述 
| **参数**            | **示例参数值**                   | **描述**                                                                                                                                      |
|:---|:---|:---|
| userPrincipal     | sparkuser                   | 用户用于认证的账号Principal，使用[准备集群认证用户信息](https://support.huaweicloud.com/devg3-mrs/mrs_07_200190.html#mrs_07_200190__section10916205214313)中创建的用户。 |
| userKeytabPath    | /opt/FIclient/user.keytab   | 用户用于认证的Keytab文件，将准备的开发用户的user.keytab文件复制到示例参数值的路径下。                                                                                         |
| ZKServerPrincipal | zookeeper/hadoop.*\<系统域名\>* | ZooKeeper服务端principal。请联系管理员获取对应账号。                                                                                                         |
   
下列代码片段在样例工程中com.huawei.bigdata.spark.examples包的FemaleInfoCollection类的main方法中。
- 基本安全认证：
  Spark Core和Spark SQL程序不需要访问HBase或ZooKeeper，所以使用基本的安全认证代码即可。请在程序中添加如下代码，并根据实际情况设置安全认证相关参数：
  ```
  String userPrincipal = "sparkuser";
  String userKeytabPath = "/opt/FIclient/user.keytab";
  String krb5ConfPath = "/opt/FIclient/KrbClient/kerberos/var/krb5kdc/krb5.conf";
  Configuration hadoopConf = new Configuration();
  LoginUtil.login(userPrincipal, userKeytabPath, krb5ConfPath, hadoopConf);
  ```
  
- 带ZooKeeper认证： 由于"Spark Streaming"、"通过JDBC访问Spark SQL"和"Spark on HBase"样例程序，不仅需要基础安全认证，还需要添加ZooKeeper服务端Principal才能完成安全认证。请在程序中添加如下代码，并根据实际情况设置安全认证相关参数：
  ```
  String userPrincipal = "sparkuser";
  String userKeytabPath = "/opt/FIclient/user.keytab";
  String krb5ConfPath = "/opt/FIclient/KrbClient/kerberos/var/krb5kdc/krb5.conf";
  String ZKServerPrincipal = "zookeeper/hadoop.<系统域名>";
  String ZOOKEEPER_DEFAULT_LOGIN_CONTEXT_NAME = "Client";
  String ZOOKEEPER_SERVER_PRINCIPAL_KEY = "zookeeper.server.principal";
  Configuration hadoopConf = new Configuration();
  LoginUtil.setJaasConf(ZOOKEEPER_DEFAULT_LOGIN_CONTEXT_NAME, userPrincipal, userKeytabPath);
  LoginUtil.setZookeeperServerPrincipal(ZOOKEEPER_SERVER_PRINCIPAL_KEY, ZKServerPrincipal);
  LoginUtil.login(userPrincipal, userKeytabPath, krb5ConfPath, hadoopConf);
  ```
  
 
#### 安全认证代码（Scala版）
目前样例代码统一调用LoginUtil类进行安全认证，安全登录流程请参见统一认证章节。
在Spark样例工程代码中，不同的样例工程，使用的认证代码不同，基本安全认证或带ZooKeeper认证。样例工程中使用的示例认证参数如[表3]所示，请根据实际情况修改对应参数值。
 表3参数描述 
| **参数**            | **示例参数值**                   | **描述**                                                                                                                                        |
|:---|:---|:---|
| userPrincipal     | sparkuser                   | 用户用于认证的账号Principal，使用[准备集群认证用户信息](https://support.huaweicloud.com/devg3-mrs/mrs_07_200190.html#mrs_07_200190__section10916205214313)章节中创建的用户。 |
| userKeytabPath    | /opt/FIclient/user.keytab   | 用户用于认证的Keytab文件，将准备的开发用户的user.keytab文件复制到示例参数值的路径下。                                                                                           |
| ZKServerPrincipal | zookeeper/hadoop.*\<系统域名\>* | ZooKeeper服务端principal。请联系管理员获取对应账号。                                                                                                           |
   
- 基本安全认证：
  Spark Core和Spark SQL程序不需要访问HBase或ZooKeeper，所以使用基本的安全认证代码即可。请在程序中添加如下代码，并根据实际情况设置安全认证相关参数：
  ```
  val userPrincipal = "sparkuser"
  val userKeytabPath = "/opt/FIclient/user.keytab"
  val krb5ConfPath = "/opt/FIclient/KrbClient/kerberos/var/krb5kdc/krb5.conf"
  val hadoopConf: Configuration  = new Configuration()
  LoginUtil.login(userPrincipal, userKeytabPath, krb5ConfPath, hadoopConf);
  ```
  
- 带ZooKeeper认证： 由于"Spark Streaming"、"通过JDBC访问Spark SQL"和"Spark on HBase"样例程序，不仅需要基础安全认证，还需要添加ZooKeeper服务端Principal才能完成安全认证。请在程序中添加如下代码，并根据实际情况设置安全认证相关参数：
  ```
  val userPrincipal = "sparkuser"
  val userKeytabPath = "/opt/FIclient/user.keytab"
  val krb5ConfPath = "/opt/FIclient/KrbClient/kerberos/var/krb5kdc/krb5.conf"
  val ZKServerPrincipal = "zookeeper/hadoop.<系统域名>"
  val ZOOKEEPER_DEFAULT_LOGIN_CONTEXT_NAME: String = "Client"
  val ZOOKEEPER_SERVER_PRINCIPAL_KEY: String = "zookeeper.server.principal"
  val hadoopConf: Configuration  = new Configuration();
  LoginUtil.setJaasConf(ZOOKEEPER_DEFAULT_LOGIN_CONTEXT_NAME, userPrincipal, userKeytabPath)
  LoginUtil.setZookeeperServerPrincipal(ZOOKEEPER_SERVER_PRINCIPAL_KEY, ZKServerPrincipal)
  LoginUtil.login(userPrincipal, userKeytabPath, krb5ConfPath, hadoopConf);
  ```
  
 
