Java连接Kerberos认证的Kafak
Java:甲。Kafka:乙。
一、一般需要三个文件。xxx.keytab ,xxkrb5.conf , 创建的 jaas.conf,并配置hosts。
1、连谁让谁提供 xxx.keytab文件,进行身份验证(该文件由乙提供)。
2、添加krb5.conf文件,可直接从kdc所在服务器复制(内容由乙提供)。
#配置片段也可以放在此目录中 /etc/krb5.conf.d/
[logging]
default = FILE:/var/log/krb5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log
[libdefaults]
default_realm = ABC.COM # 指定默认领域名
dns_lookup_realm = false # 指定无需DNS解析领域请求包
dns_lookup_kdc = ture # 指定允许DNS解析kdc请求包
ticket_lifetime = 24h # 指定Kerberos认证票证有效期
forwardable = yes # 允许转发解析请求
[realms]
ABC.COM = {
kdc = 192.168.67.130:88 # 指定KDC服务器和KDC服务端口
admin_server = 192.168.67.129 # 指定域控制器和管理端口
default_domain = abc.com # 指定默认域
}
[domain_realm]
.abc.com = ABC.COM
abc.com = ABC.COM
# 以上两条其实是设置一个领域搜索范围,并通过这两个语句可以使得领域名与大小写无关。
3、创建 jaas.conf文件,并添加内容
KafkaServer {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
keyTab="D:/kafka/xxx.keytab" #指定”乙“已经给的xxx.keytab文件。
storeKey=true
useTicketCache=false
principal="uname@ABC.COM"; #uname是berberos认证的用户名。ABC.COM 是认领域名。
};
KafkaClient {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
keyTab="D:/kafka/xxx.keytab"
storeKey=true
useTicketCache=false
principal="uname@ABC.COM";
};
Client {
com.sun.security.auth.module.Krb5LoginModule required
useKeyTab=true
storeKey=true
useTicketCache=false
keyTab="D:/kafk/xxx.keytab"
principal="uname@ABC.COM";
};
4、本地配置hosts
hosts位置一般都是在C:\Windows\System32\drivers\etc 目录下。
编辑hosts,把连接用到的ip和hostname都配置上。
二、生产者连接Kerberos认证的kafka
认证主要看代码注释的 “一”和“二”。
import java.util.Properties;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.producer.Callback;
import org.apache.kafka.clients.producer.RecordMetadata;
public class CallBackProducer {
public static void main(String[] args) {
//一、*****添加认证
System.setProperty("java.security.auth.login.config","D:\\kafka\\jaas.conf");
System.setProperty("java.security.krb5.conf","D:\\kafka\\krb5.conf");
System.setProperty("javax.security.auth.useSubjectCredsOnly", "true");
//1、创建kafka集群配置信息
Properties properties = new Properties();
//连接kafka集群
//properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,"192.168.67.128:9092,192.168.67.129:9092,192.168.67.130:9092");
//序列号key和value(必须有)
properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,"org.apache.kafka.common.serialization.StringSerializer");
properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,"org.apache.kafka.common.serialization.StringSerializer");
//二、*****配置安全协议security.protocol和sasl.kerberos.service.name
//这俩行如果丢了的话,日志会一直打印,消息也没有发送出去。
properties.put("security.protocol", "SASL_PLAINTEXT");//安全协议
properties.put("sasl.kerberos.service.name", "kafka");
//2、创建生产者对象
KafkaProducer<String,String> producer = new KafkaProducer<String,String>(properties);
//3、发送消息
for (int i = 0; i <7; i++) {
//通过send方法,初始化ProducerRecord()。
producer.send(new ProducerRecord<String, String>("topicName","发送消息"+i),new Callback() {
public void onCompletion(RecordMetadata arg0, Exception arg1) {
if(arg1==null){
System.err.println("发送成功:"+arg0.topic()+":"+arg0.partition()+":"+arg0.offset());
}else{
System.err.println("发送失败");
}
}
});
}
//4、关闭资源
producer.close();
}
}
如果能正常发送消息,说明生产者已经连接成功。否则检查一下文件配置是否有问题。
注意:Java代码认证连接kafka 不可丢掉的代码:
//一、*****添加认证
System.setProperty("java.security.auth.login.config","D:\\kafka\\jaas.conf");
System.setProperty("java.security.krb5.conf","D:\\kafka\\krb5.conf");
//二、*****配置安全协议security.protocol和sasl.kerberos.service.name
//这俩行如果丢了的话,日志会一直打印,消息也没有发送出去。
properties.put("security.protocol", "SASL_PLAINTEXT");//安全协议
properties.put("sasl.kerberos.service.name", "kafka");
三、消费者连接Kerberos认证的kafka
与生产者一样认证主要看代码注释的 “一”和“二”。不能丢掉。
注意:代码中测试消费者消费之前最好先执行一下生产者代码。先生产消息再消费,否则可能消费者会一直打印日志而且消费不到消息。
import java.util.Arrays;
import java.util.Properties;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
public class MyConsumer {
public static void main(String[] args) {
//一、*****添加认证
System.setProperty("java.security.krb5.conf", "D:\\WorkOffice\\JBK\\kerberosKafka\\dev_krb5.conf");
System.setProperty("java.security.auth.login.config", "D:\\WorkOffice\\JBK\\kerberosKafka\\jaas.conf");
//System.setProperty("javax.security.auth.useSubjectCredsOnly", "false");
//1、创建配置信息
Properties properties = new Properties();
//连接集群(必须有)
//properties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,"kafka01:9092,kafka02:9092,kafka03:9092");
//开启自动提交。如果不开启自动提交,需要设置手动提交。
properties.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG,true);
//设置自动提交时间,默认1000毫秒,也就是1秒。当不开启自动提交ENABLE_AUTO_COMMIT_CONFIG=false时,该配置无效。
properties.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG,1000);
//key和value的反序列号(必须有)
properties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");
properties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");
//二、*****配置安全协议security.protocol和sasl.kerberos.service.name
properties.put("security.protocol", "SASL_PLAINTEXT");
properties.put("sasl.kerberos.service.name", "kafka");
//消费者组,必填
properties.put(ConsumerConfig.GROUP_ID_CONFIG," group01");
//2、创建consumer对象
KafkaConsumer<String,String> consumer = new KafkaConsumer<String,String>(properties);
//3、订阅主题,因为每个消费者可以订阅多个主题,所以传的list。
consumer.subscribe(Arrays.asList("topicName"));
while(true){
//4、拉取消息,并设置等待时间 ,单位ms。因为一次可以拉取多条数据,所以是ConsumerRecords,后边加了 s。
ConsumerRecords<String, String> poll = consumer.poll(1000);
//5、遍历ConsumerRecords获取对象信息
for (ConsumerRecord<String, String> consumerRecord : poll) {
System.err.println("消费者:"+consumerRecord.topic()+",分区:"+consumerRecord.partition()+",key:"+consumerRecord.key()+",value:"+consumerRecord.value()+",offset:"+consumerRecord.offset());
}
}
}
}
注意:Java代码认证连接kafka 不可丢掉的代码:
//一、*****添加认证
System.setProperty("java.security.auth.login.config","D:\\kafka\\jaas.conf");
System.setProperty("java.security.krb5.conf","D:\\kafka\\krb5.conf");
//二、*****配置安全协议security.protocol和sasl.kerberos.service.name
//这俩行如果丢了的话,日志会一直打印,消息也没有发送出去。
properties.put("security.protocol", "SASL_PLAINTEXT");//安全协议
properties.put("sasl.kerberos.service.name", "kafka");