Mybatis-plus + kerberos+hikari+impala实现客户端身份认证

一、 各组件简介:

       Mybatis-plus 基于轻量级持久层框架mybatis的增强,易于使用,支持lamda方式查询、多数据源动态配置等;

       HikariCP目前流行的数据库链接池,springboot2.0默认使用;

       Impala是Cloudera公司主导开发的新型查询系统,它提供SQL语义,能查询存储在Hadoop的HDFS和HBase中的PB级大数据。

        Kerberos是一种计算机网络认证协议,他能够为网络中通信的双方提供严格的身份验证服务,确保通信双方身份的真实性和安全性

二、存在问题

        项目为已部署项目, impala新增Kerberos认证,因原有项目架构体系, 引入了多数据源, 新增认证只针对impala链接的升级,需要适配当前框架增加Kerberos客户端用户验证

三、解决思路

      思路一: 做切面, 每次获取connection时做增强方法

      思路二: 重写连接池getConnection方法, 将自定义连接池整合入mybatis-plus动态数据源框架

      本文主要采用思路二,重写了数据连接池

二、主要步骤如下

        pom文件引入

<dependency>
    <groupId>org.apache.hadoop</groupId>
    <artifactId>hadoop-common</artifactId>
    <version>2.10.0</version>
</dependency>

        1、Impala Kerberos身份验证

       验证配置是否正确,数据链路是否打通, 如果存在问题, 请依据服务端配置调整参数。

public static void main(String[] args){

        // kerberos认证的代码块
        // 1. login use
            Configuration conf = initConfiguration();
            System.setProperty("java.security.krb5.conf", "/../krb5.conf");
            System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
            System.setProperty("sun.security.krb5.debug", "true");
            System.setProperty("java.security.auth.login.config","/../jaas.conf");
            String keyPath = "/../user.keytab";
            try {
                UserGroupInformation.setConfiguration(conf);
                UserGroupInformation.loginUserFromKeytab("name", keyPath);
                UserGroupInformation loginUser = UserGroupInformation.getLoginUser();
                Connection conn = loginUser.doAs(new PrivilegedExceptionAction<Connection>() {
                    public Connection run() {
                        Connection tcon = null;
                        try {
                            // 父类的getConnection(long)方法
                            Class.forName("com.cloudera.impala.jdbc41.Driver");
                            Connection connection = DriverManager.getConnection("jdbc:impala://host:port/dbname;AuthMech=1;KrbRealm=XXXX;KrbHostFQDN=host;KrbServiceName=impala");
                            Statement statement = connection.createStatement();
                            ResultSet resultSet = statement.executeQuery("select count(1) from users");
                            System.out.println(resultSet);
                            log.info("resultSet: "+resultSet);
                        } catch (Exception e) {
                            log.error("获取数据源链接失败",e);
                        }
                        return tcon;
                    }
                });
            } catch (Exception e){
                log.error("获取数据源链接失败..",e);
            }

        return "";
    }

2 重写HikariCP数据连接池 getConnection方法

     继承HikariDataSource 重写getConnection方法,在获取链接时做认证操作

public class DataSourceConfig extends HikariDataSource{

    // 创建一个函数,指向父类的getConnection(long)方法
    public Connection superGetConnection() throws SQLException {
        return super.getConnection();
    }

    @Override
    public Connection getConnection() throws SQLException{
        // kerberos认证的代码块
        // 1. login use
            Configuration conf = initConfiguration();
            System.setProperty("java.security.krb5.conf", "/../krb5.conf");
            System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
            System.setProperty("sun.security.krb5.debug", "true");
            System.setProperty("java.security.auth.login.config","/../jaas.conf");
            String keyPath = "/../user.keytab";
            try {
                UserGroupInformation.setConfiguration(conf);
                UserGroupInformation.loginUserFromKeytab("name", keyPath);
                UserGroupInformation loginUser = UserGroupInformation.getLoginUser();
                Connection conn = loginUser.doAs(new PrivilegedExceptionAction<Connection>() {
                    public Connection run() {
                        Connection tcon = null;
                        try {
                            // 父类的getConnection(long)方法
                            Class.forName("com.cloudera.impala.jdbc41.Driver");
                            tcon  = DriverManager.getConnection("jdbc:impala://host:port/dbname;AuthMech=1;KrbRealm=XXXX;KrbHostFQDN=host;KrbServiceName=impala");
                        } catch (Exception e) {
                            log.error("获取数据源链接失败",e);
                        }
                        return tcon;
                    }
                });
            } catch (Exception e){
                log.error("获取数据源链接失败..",e);
            }

        return null;
    }
}

3 注册当前连接池到mybatis-plus动态数据源

 
        dataSourceProperties.setDriverClassName(kerberoProperties.getDriverClassName());
        dataSourceProperties.setUrl(kerberoProperties.getUrl());
        dataSourceProperties.setUsername(kerberoProperties.getUsername());
        dataSourceProperties.setPassword(kerberoProperties.getPassword());
        //创建自定义数据连接池
        DataSourceConfig targetDataSource = dataSourceProperties.initializeDataSourceBuilder().type(DataSourceConfig.class).build();
        if (StringUtils.hasText(dataSourceProperties.getName())) {
            targetDataSource.setPoolName(dataSourceProperties.getName());
        }
        targetDataSource.setMaxLifetime(0);//设置最长生命周期为无限长,https://www.jianshu.com/p/fa9e0bff4cd9/
        //获取动态数据源
        DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
        //包装自定义数据连接池
        ItemDataSource itemDataSource = new ItemDataSource(kerberoProperties.getId(),targetDataSource,targetDataSource,false,false, SeataMode.AT);
        //添加自定义数据连接池
        ds.addDataSource(kerberoProperties.getId(), itemDataSource);

参考文章:

1、基于mybatis plus实现数据源动态添加、删除、切换,自定义数据源的示例代码
2、kerberos+druid+impala_laolvbig的博客-CSDN博客

3、Simba Impala JDBC Driver with SQL Connector

4、springboot 集成impala连接池问题


 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值