连接池连接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/nmdssc-135-12-70-35.nmds.com@NMDS.COM";
        
        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/nmdssc-135-12-70-39.nmds.com@NMDS.COM", "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("impala@NMDS.COM", 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;
	}
}

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

	<listener>
     			<listener-class>sjgl.system.GetConnListener</listener-class>
  	</listener>
	<!-- Spring监听配置,Web容器启动自动装配ApplicationContext的配置信息-->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

但是不知道我看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是不好的。

用如下配置可以解决:

<property name="validationQuery" value="select 1" />
  <property name="testWhileIdle" value="true" />
  <property name="testOnBorrow" value="false" />
  <property name="testOnReturn" value="false" />
  <property name="timeBetweenEvictionRunsMillis" value="600000" />

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

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

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

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

 

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

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
要使用Java API连接使用Kerberos认证的Elasticsearch集群,你需要遵循以下步骤: 1. 首先,你需要为你的Java应用程序配置Kerberos认证。这可以通过在你的应用程序中使用JAAS(Java Authentication and Authorization Service)框架来完成。 2. 然后,你需要在Elasticsearch集群中启用Kerberos认证。这可以通过在elasticsearch.yml配置文件中设置以下属性来完成: ``` xpack.security.authc.realms: kerberos.kerb1: type: kerberos order: 0 krb5_file_path: /path/to/krb5.conf keytab_path: /path/to/elasticsearch.keytab ``` 其中,`krb5_file_path`是指向Kerberos配置文件的路径,`keytab_path`是指向Elasticsearch服务的keytab文件路径。 3. 接下来,你需要使用Java API创建一个Elasticsearch客户端,并使用Kerberos认证进行身份验证。以下是一个示例代码: ``` public class KerberosESClient { public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); conf.setBoolean("hadoop.security.authentication", true); UserGroupInformation.setConfiguration(conf); UserGroupInformation.loginUserFromKeytab("your_principal", "/path/to/your/keytab"); Settings settings = Settings.builder() .put("cluster.name", "your_cluster_name") .put("xpack.security.user", "your_username:your_password") .put("client.transport.sniff", true) .build(); TransportClient client = new PreBuiltXPackTransportClient(settings) .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("your_es_host"), 9300)); SearchResponse response = client.prepareSearch().execute().actionGet(); client.close(); } } ``` 在上面的代码中,`UserGroupInformation`类用于从指定的keytab文件中获取Kerberos凭证,然后使用这些凭证创建一个Elasticsearch客户端。`Settings`类用于配置一些连接参数,例如集群名称、节点授权信息等。`TransportClient`类用于实现与Elasticsearch节点的通信,可以使用`prepareSearch`方法发送一个查询请求并获取结果。 希望这个回答能够帮助到你!
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值