
# 配置Spark应用安全认证
#### 前提条件
MRS服务集群开启了Kerberos认证。
#### 场景说明
在集群开启Kerberos认证的环境下，各个组件之间的相互通信不能够简单地互通，而需要在通信之前进行相互认证，以确保通信的安全性。
用户在开发Spark应用程序时，某些场景下，需要Spark与Hadoop、HBase等之间进行通信。那么Spark应用程序中需要写入安全认证代码，确保Spark程序能够正常运行。
安全认证有三种方式：
- 命令认证： 提交Spark应用程序运行前，或者在使用CLI连接SparkSQL前，在Spark客户端执行如下命令获得认证。
  **kinit** 组件业务用户
  
- 配置认证： 可以通过以下3种方式的任意一种指定安全认证信息。
  1. 在客户端的"spark-default.conf"配置文件中，配置"spark.yarn.keytab"和"spark.yarn.principal"参数指定认证信息。
  
  2. 执行**bin/spark-submit** 的命令中添加如下参数来指定认证信息。
     **--conf spark.yarn.keytab** =\<keytab文件路径\> **--conf spark.yarn.principal**=\<Principal账号\>
     
  
  3. 执行**bin/spark-submit** 的命令中添加如下参数来指定认证信息。
     **--keytab** \<keytab文件路径\> **--principal** \<Principal账号\>
     
   
- 代码认证： 通过获取客户端的principal和keytab文件在应用程序中进行认证。
  在集群开启Kerberos认证环境下，样例代码需要使用的认证方式如表1所示：
  表1安全认证方式 
  | 样例代码                                                               | 模式           | 安全认证方式                 |
  |:---|:---|:---|
  | spark-examples-normal                                              | yarn-client  | 命令认证、配置认证或代码认证，三种任选一种。 |
  | spark-examples-normal                                              | yarn-cluster | 命令认证或者配置认证，两种任选一种。     |
  | spark-examples-security （已包含安全认证代码） | yarn-client  | 代码认证。                  |
  | spark-examples-security （已包含安全认证代码） | yarn-cluster | 不支持。                   |
     
  
![](https://support.huaweicloud.com/devg-mrs/public_sys-resources/note_3.0-zh-cn.png)
- 如上表所示，yarn-cluster模式中不支持在Spark工程代码中进行安全认证，因为需要在应用启动前已完成认证。
- 未提供Python样例工程的安全认证代码，推荐在运行应用程序命令中设置安全认证参数。
 
#### 安全认证代码（Java版）
目前样例代码统一调用LoginUtil类进行安全认证。
在Spark样例工程代码中，不同的样例工程，使用的认证代码不同，基本安全认证或带ZooKeeper认证。样例工程中使用的示例认证参数如表2所示，请根据实际情况修改对应参数值。
表2参数描述 
| 参数                | 示例参数值                                                  | 描述                                  |
|:---|:---|:---|
| userPrincipal     | sparkuser                                              | 用户用于认证的账号Principal，您可以联系管理员获取此账号。   |
| userKeytabPath    | /opt/FIclient/user.keytab                              | 用户用于认证的Keytab文件，您可以联系管理员获取文件。       |
| krb5ConfPath      | /opt/FIclient/KrbClient/kerberos/var/krb5kdc/krb5.conf | krb5.conf文件路径和文件名称。                 |
| ZKServerPrincipal | zookeeper/hadoop.hadoop.com                            | ZooKeeper服务端principal。请联系管理员获取对应账号。 |
   
- 基本安全认证： 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.hadoop.com";
  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，您可以联系管理员获取此账号。   |
| userKeytabPath    | /opt/FIclient/user.keytab                              | 用户用于认证的Keytab文件，您可以联系管理员获取文件。       |
| krb5ConfPath      | /opt/FIclient/KrbClient/kerberos/var/krb5kdc/krb5.conf | krb5.conf文件路径和文件名称。                 |
| ZKServerPrincipal | zookeeper/hadoop.hadoop.com                            | 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.hadoop.com"
  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);
  ```
  
 
