连接池连接kerberos权限认证的impala+kudu数据库

啥都不说,先吐槽,吐槽技术中心,吐槽部门,能不能让我安安全全的使用,不要扔个个东西来就让我用,在开发环境没有kerberos,来了上正式,直接给布上,你让我这连kerberos都不知道是啥的java开发人员咋搞,完,写一下自己通过连接池连接存在kerberos认证的impala+kudu数据库。

先说啥是kerberos:

“Kerberos 服务”是一种客户机/服务器体系结构,用于在网络上提供安全事务。该服务可提供功能强大的用户验证以及完整性和保密性。通过验证,可保证网络事务的发送者和接收者的身份真实。该服务还可以检验来回传递的数据的有效性(完整性),并在传输过程中对数据进行加密(保密性)。使用 Kerberos 服务,可以安全登录到其他计算机、执行命令、交换数据以及传输文件。此外,该服务还提供授权服务,这样,管理员便可限制对服务和计算机的访问。而且,作为 Kerberos 用户,您还可以控制其他用户对您帐户的访问。

解决方式及途径:

当时先在网上找资料,发现网上没有连接池连接的,只有通过JDBC直连的,代码如下:

public class App4 {
    public static void main(String[] args) throws ClassNotFoundException {
        String driverName="org.apache.hive.jdbc.HiveDriver";
        Class.forName("org.apache.hive.jdbc.HiveDriver");
        String url = "jdbc:hive2://135.12.70.35:21055/;principal=impala/[email protected]";
        
        Configuration conf = new Configuration();
        conf.set("hadoop.security.authentication", "Kerberos");
        try {
            System.setProperty("java.security.krb5.conf", "resource/krb5.conf");
            UserGroupInformation.setConfiguration(conf);
            UserGroupInformation.loginUserFromKeytab("impala/[email protected]", "resource/impala.haproxy.keytab");
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            Class.forName(driverName);
            Connection conn = DriverManager.getConnection(url);
            Statement stmt = conn.createStatement();
            String sql = "select * from test1";
            ResultSet rs = stmt.executeQuery(sql);
            while (rs.next()) {
                System.out.println(rs.getInt(1));
            }
            stmt.close();
            rs.close();
            conn.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

通过上面发现,咋的,连接前先验证,但是连接池的init方法根本不用我写,这个咋搞,这时候我的思维进入了误区,想是不是需要修改连接池的源码,所以我写了了类继承DruidDataSource,重写了init方法在这上面加上kerberos验证,但是这种方法能实现,其实很错误,这可能我受了传统数据库的影响,以为每次建立连接都得验证,其实kerberos是单点登陆的,是服务器之间的通信,后来在领导的指导下,我采用了listener在项目启动时,对项目启动时验证,监听器如下:

public class GetConnListener implements ServletContextListener{
	private static Logger log = LoggerFactory.getLogger(GetConnListener.class) ;
	private static final  Configuration kuduconf = new Configuration();
	public static void initkerberos() throws IOException
	{
		 File directory = new File("");// 参数为空
	     String courseFile = directory.getCanonicalPath();
		 Configuration	conf = getKuduConf();
	     try {
	            System.setProperty("java.security.krb5.conf", courseFile+"/WebRoot/krb5.conf");
	            UserGroupInformation.setConfiguration(conf);
	            UserGroupInformation.loginUserFromKeytab("[email protected]", courseFile+"/WebRoot/impala.haproxy.keytab");
	        } catch (IOException e) {
	            e.printStackTrace();
	        }
	       log.info("Kerberos验证程序") ;
	}
	@Override
	public void contextDestroyed(ServletContextEvent arg0) {
		
	}
	@Override
	public void contextInitialized(ServletContextEvent arg0) {
		try {
			initkerberos();
		} catch (IOException e) {
			e.printStackTrace();
		}
		log.info("Kerberos初始化完成") ;
	}
	public static Configuration getKuduConf(){
		kuduconf.set("hadoop.security.authentication", "Kerberos");
		return kuduconf;
	}
}

值得注意的是监听器的顺序,认证的这个监听器放在最上面,如下:

	
     			sjgl.system.GetConnListener
  	
	
	
		org.springframework.web.context.ContextLoaderListener
	

但是不知道我看kerberos好像24小时失效,然后写了个定时任务及时认证,但是好像认证一次就不需要重复认证,他自己刷新,我也没管,保险起见,调度如下:

@Service
public class reloadkbs {
	private static Logger log = LoggerFactory.getLogger(reloadkbs.class) ;
	@Scheduled(fixedRate = 1000*60*60*23)  
	public void reloadkerberos() throws IOException{
		GetConnListener.initkerberos();
		log.info("Kerberos重新验证完成") ;
	}
}

但是在使用连接池时也遇到过连接池的问题例如,连接池隔一天断开,重启服务正常,错误提示:[Request processing failed; nested exception is org.hibernate.exception.GenericJDBCException: could not inspect JDBC autocommit mode] with root cause

java.net.SocketException: Software caused connection abort: socket write error

我按照druid的示例配置了最小连接数,以及检测连接打开,但是没用的?请问怎么看druid的保持连接池最小连接的检测日志输出???我看看有没有检测连接。

解决方案:首先更改wait_timeout是不好的。

用如下配置可以解决:


  
  
  
  

testWhileIdle:建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于

timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。

testOnBorrow:申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。

testOnReturn:归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能

 

另外:大家七夕快乐,今年七夕我还是一个人。

你可能感兴趣的:(web开发)