54

博客园Logo
首页
新闻
博问
专区
闪存
班级

代码改变世界
搜索
注册
登录
返回主页
zzzzMing -大数据技术
蟹六跪而二螯,非蛇鳝之,无可寄托者,用心躁也
博客园 首页 新随笔 联系 订阅 管理随笔 - 84 文章 - 0 评论 - 89
kafka SASL认证介绍及自定义SASL PLAIN认证功能
目录
kafka 2.x用户认证方式小结
SASL/PLAIN实例(配置及客户端)
broker配置
客户端配置
自定义SASL/PLAIN认证(二次开发)
kafka2新的callback接口介绍
自定义sasl/plain功能
用户认证功能,是一个成熟组件不可或缺的功能。在0.9版本以前kafka是没有用户认证模块的(或者说只有SSL),好在kafka0.9版本以后逐渐发布了多种用户认证功能,弥补了这一缺陷(这里仅介绍SASL)。

本篇会先介绍当前kafka的四种认证方式,然后过一遍部署SASL/PLAIN认证功能的流程。最后再介绍如如何使用kafka2.x新推出的callback api,对SASL/PLAIN功能进行二次开发。

kafka 2.x用户认证方式小结
需要先明确的一点是,用户认证和权限控制是两码事。用户认证是确认这个用户能否访问当前的系统,而权限控制是控制用户对当前系统中各种资源的访问权限。用户认证就是今天要讲的内容,而kafka的权限控制,则是对应bin/kafka-acls.sh工具所提供的一系列功能,这里不详细展开。

标题特地说明kafka2.x是因为kafka2.0的时候推出一种新的用户认证方式,SASL/OAUTHBEARER,在此前的版本是不存在这个东西的。那么加上这个之后,kafka目前共有4种常见的认证方式。

SASL/GSSAPI(kerberos):kafka0.9版本推出,即借助kerberos实现用户认证,如果公司恰好有kerberos环境,那么用这个是比较合适的。
SASL/PLAIN:kafka0.10推出,非常简单,简单得有些鸡肋,不建议生产环境使用,除非对这个功能二次开发,这也是我后面要讲的。
SASL/SCRAM:kafka0.10推出,全名Salted Challenge Response Authentication Mechanism,为解决SASL/PLAIN的不足而生,缺点可能是某些客户端并不支持这种方式认证登陆(使用比较复杂)。
SASL/OAUTHBEARER:kafka2.0推出,实现较为复杂,目前业内应该较少实践。
其实除了上述四种用户认证功能之外,还有一个叫Delegation Token的东西。这个东西说一个轻量级的工具,是对现有SASL的一个补充,能够提高用户认证的性能(主要针对Kerberos的认证方式)。算是比较高级的用法,一般也用不到,所以也不会多介绍,有兴趣可以看这里Authentication using Delegation Tokens。

SASL/GSSAPI

如果已经有kerberos的环境,那么会比较适合使用这种方式,只需要让管理员分配好principal和对应的keytab,然后在配置中添加对应的选项就可以了。需要注意的是,一般采用这种方案的话,zookeeper也需要配置kerberos认证。

SASL/PLAIN

这种方式其实就是一个用户名/密码的认证方式,不过它有很多缺陷,比如用户名密码是存储在文件中,不能动态添加,明文等等!这些特性决定了它比较鸡肋,但好处是足够简单,这使得我们可以方便地对它进行二次开发。本篇文章后续会介绍SASL/PLAIN的部署方式和二次开发的例子(基于kafka2.x)。

SASL/SCRAM

针对PLAIN方式的不足而提供的另一种认证方式。这种方式的用户名/密码是存储中zookeeper的,因此能够支持动态添加用户。该种认证方式还会使用sha256或sha512对密码加密,安全性相对会高一些。

而且配置起来和SASL/PLAIN差不多同样简单,添加用户/密码的命令官网也有提供,个人比较推荐使用这种方式。不过有些客户端是不支持这个方式认证登陆的,比如python的kafka客户端,这点需要提前调研好。

具体的部署方法官网或网上有很多,这里不多介绍,贴下官网的Authentication using SASL/SCRAM。

SASL/OAUTHBEARER

SASL/OAUTHBEARER是基于OAUTH2.0的一个新的认证框架,这里先说下什么是OAUTH吧,引用维基百科。

OAuth是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用。而 OAUTH2.0算是OAUTH的一个加强版。

说白了,SASL/OAUTHBEARER就是一套让用户使用第三方认证工具认证的标准,通常是需要自己实现一些token认证和创建的接口,所以会比较繁琐。

详情可以通过这个kip了解KIP-255

说了这么多,接下来就说实战了,先介绍下如何配置SASL/PLAIN。

SASL/PLAIN实例(配置及客户端)
broker配置

kafka_server_jaas.conf

这里简单介绍下SASL/PLAIN的部署方式,另外除了SASL/OAUTHBEARER,其他几种应该也是类似的部署方式,基本都是大同小异。

PS:本配置版本适用于kafka2.x,且无需配置zk认证

kafka的用户认证,是基于java的jaas。所以我们需要先添加jaas服务端的配置文件。在kafka_home/config/kafka_server_jaas.conf中添加以下配置信息:

KafkaServer {
org.apache.kafka.common.security.plain.PlainLoginModule required
username=“admin”
password=“admin-secret”
user_admin=“admin-secret”
user_alice=“alice-secret”;
};
注意最后一个属性后面需要加封号!配置是不难理解的,第一行指定PlainLoginModule,算是声明这是一个SASL/PLAIN的认证类型,如果是其他的,那么就需要reqired其他的类。username和password则是用于集群内部broker的认证用的。

这里会让人疑惑的,应该是user_admin和user_alice这两个属性了。这个其实是用来定义用户名和密码的,形式是这样:user_userName=password。所以这里其实是定义了用户admin和用户alice到密码。

这一点可以在源码的PlainServerCallbackHandler类中找到对应的信息,kafka源码中显示,对用户认证的时候,就会到jaas配置文件中,通过user_username属性获取对应username用户的密码,再进行校验。当然这样也导致了该配置文件只有重启才会生效,即无法动态添加用户。

说回来,写完配置后,需要在kafka的配置中添加jaas文件的路径。在kafka_home/bin/kafka-run-class.sh中,找到下面的配置,修改KAFKA_OPTS到配置信息。

Generic jvm settings you want to add

if [ -z “$KAFKA_OPTS” ]; then
KAFKA_OPTS=""
fi
将上述到KAFKA_OPTS修改为

KAFKA_OPTS="-Djava.security.auth.login.config=kafka_home/config/kafka_server_jaas.conf"

server.properties

然后修改kafka_home/config/server.properties:

listeners=SASL_PLAINTEXT://host.name:port
security.inter.broker.protocol=SASL_PLAINTEXT
sasl.mechanism.inter.broker.protocol=PLAIN
sasl.enabled.mechanisms=PLAIN
其中SASL_PLAINTEXT的意思,是明文传输的意思,如果是SSL,那么应该是SASL_SSL。

这样就算是配置好kafka broker了,接下来启动kafka,观察输出日志,没有错误一般就没问题了。

客户端配置

以producer为例,只需要在kafka_home/config/producer.properties中添加jaas认证信息,以及用户名密码:

sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required
username=“alice”
password=“alice-secret”;

security.protocol=SASL_SSL
sasl.mechanism=PLAIN

然后使用console producer验证:

bin/kafka-console-producer.sh --broker-list kafka:9092 --topic test --producer.config config/producer.properties

一般能够发送数据就说明部署完成了~

自定义SASL/PLAIN认证(二次开发)
前面小节介绍了kafka sasl_plain的部署方式,但这种方式的诸多弊病决定了它并不适合用于生产环境。这里我们先介绍kafka2的新认证接口,然后演示下如何使用新的api自定义。

kafka2新的callback接口介绍

这一api提出的背景,是因为最开始的api(即SaslServer),不方便对用户认证进行拓展。这个问题在开发SASL/SCRAM功能的时候尤其突出。按官方的说法,要添加SASL/SCRAM功能,需要重写SaslServer类。

所以官方重写了这方面的功能,使用回调的方式实现了这部分的功能模块。使得开发者可以方便得对用户认证模块进行拓展或修改。

并且新增加了四个自定义认证的配置,分别是:

sasl客户端类:sasl.client.callback.handler.class
sasl服务端类:sasl.server.callback.handler.class
login类:sasl.login.class
login回调类:sasl.login.callback.handler.class
这几个配置默认都是null,需要填写的内容是自定义的类的路径+名称。我们这次只需要关注sasl服务端类的配置,即sasl.server.callback.handler.class。

这部分的内容具体是在KIP-86。

自定义sasl/plain功能

先详细介绍下sasl.server.callback.handler.class配置。这个配置在使用的时候,需要以小写方式指定SASL的类型。举个例子,如果是SASL_PLAINTEXT,那么就需要这样:

listener.name.sasl_plaintext.plain.sasl.server.callback.handler.class=com.example.CustomPlainCallbackHandler

即以listener.name.sasl_plaintext.plain.sasl开头。然后在kafka中,SASL_PLAINTEXT默认实现的callback handler是PlainServerCallbackHandler,实现了AuthenticateCallbackHandler接口。这个的逻辑其实还蛮简单的,我们可以看看它重点的方法和代码。

public class PlainServerCallbackHandler implements AuthenticateCallbackHandler {

private static final String JAAS_USER_PREFIX = "user_";
//jaas配置信息,初始化一次,这就是为什么plain无法添加用户
private List<AppConfigurationEntry> jaasConfigEntries;

@Override
public void configure(Map<String, ?> configs, String mechanism, List<AppConfigurationEntry> jaasConfigEntries) {
    this.jaasConfigEntries = jaasConfigEntries;
}

//核心类,获取用户密码后,调用authenticate方法
@Override
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
    String username = null;
    for (Callback callback: callbacks) {
        if (callback instanceof NameCallback)
            username = ((NameCallback) callback).getDefaultName();
        else if (callback instanceof PlainAuthenticateCallback) {
            PlainAuthenticateCallback plainCallback = (PlainAuthenticateCallback) callback;
            boolean authenticated = authenticate(username, plainCallback.password());
            plainCallback.authenticated(authenticated);
        } else
            throw new UnsupportedCallbackException(callback);
    }
}

//用户密码是通过获取jaas文件的属性,属性名就是JAAS_USER_PREFIX变量当前缀+username
protected boolean authenticate(String username, char[] password) throws IOException {
    if (username == null)
        return false;
    else {
        String expectedPassword = JaasContext.configEntryOption(jaasConfigEntries,
                JAAS_USER_PREFIX + username,
                PlainLoginModule.class.getName());
        return expectedPassword != null && Arrays.equals(password, expectedPassword.toCharArray());
    }
}

@Override
public void close() throws KafkaException {
}

}
前面说plain方式不支持动态添加用户,user_username验证密码,看代码就一清二楚。既然知道这个后,那要自定义校验逻辑就很简单了。

只需要继承PlainServerCallbackHandler这个类,然后重写authenticate方法实现自己的逻辑就实现自定义了。

比如我想让用户名和密码相同的就验证通过,那么可以这样:

public class MyPlainServerCallbackHandler extends PlainServerCallbackHandler{
@Override
protected boolean authenticate(String username, char[] password) throws IOException {
if (username == null)
return false;
else {
return expectedPassword != null && Arrays.equals(password, username.toCharArray());
}
}
}

然后中server.properpose中添加server callback信息,就可以了

listener.name.sasl_plaintext.plain.sasl.server.callback.handler.class=com.example.MyPlainServerCallbackHandler
对了,几得重新编译打包,替换掉kafka-client掉jar包,如果修改了一些全局信息(比如build.gradle引入新的依赖),那最好kafka全套jar包都换一下。

以上,如果觉得有用,不妨点个赞吧~

分类: java/scala
标签: sasl, kafka, java
好文要顶 关注我 收藏该文
zzzzMing
关注 - 4
粉丝 - 87
+加关注
0 0
« 上一篇: Hive使用Calcite CBO优化流程及SQL优化实战
posted @ 2020-11-23 19:44 zzzzMing 阅读(41) 评论(0) 编辑 收藏
刷新评论刷新页面返回顶部
登录后才能发表评论,立即 登录 或 注册, 访问 网站首页
博客园派送云上免费午餐,AWS注册立享12个月免费套餐
【推荐】News: 大型组态、工控、仿真、CADGIS 50万行VC++源码免费下载
【推荐】从零开始的RPG游戏制作教程,来《魔兽争霸III》共同成长
【推荐】了不起的开发者,挡不住的华为,园子里的品牌专区
【推荐】未知数的距离,毫秒间的传递,声网与你实时互动
【福利】AWS携手博客园为开发者送免费套餐与抵扣券
【推荐】 阿里云折扣价格返场,错过再等一年

相关博文:
· kafka?kafaka!kafka…
· kafka
· kafka
· Kafka基础——Kafka架构
· SpringBoot—Kafka
» 更多推荐…
AWS免费套餐
最新 IT 新闻:
· 招股书披露Roblox选择了腾讯作为中国区市场合作伙伴
· “好奇号”发现火星曾发生过史前大洪水的证据
· 在出租屋崩溃的年轻人
· 不吹不黑,国产的游戏不香么?
· 特斯拉研发疫苗打印机的背后有什么故事?
» 更多新闻…
历史上的今天:
2018-11-23 从分治算法到 Hadoop MapReduce
公告

推广一下免费知识星球,【内推联盟】,免费提供各个公司内推汇总及内推服务

昵称: zzzzMing
园龄: 4年3个月
粉丝: 87
关注: 4
+加关注
< 2020年11月 >
日 一 二 三 四 五 六
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 1 2 3 4 5
6 7 8 9 10 11 12
搜索

找找看

谷歌搜索
常用链接

我的随笔
我的评论
我的参与
最新评论
我的标签
我的标签

java(22)
Spark(19)
大数据(15)
Python(12)
scala(11)
机器学习(11)
Hadoop(8)
kafka(6)
Spark RPC(4)
Hdfs(4)
更多
随笔分类

java/scala(26)
kafka(5)
大数据存储(10)
大数据计算(17)
读书笔记(3)
机器学习(14)
前端(1)
问题记录(1)
有意思的(4)
职场(3)
随笔档案

2020年11月(1)
2020年9月(2)
2020年8月(1)
2020年7月(3)
2020年6月(2)
2020年5月(2)
2020年4月(5)
2020年3月(3)
2020年2月(2)
2019年12月(2)
2019年11月(3)
2019年10月(2)
2019年9月(3)
2019年8月(4)
2019年7月(4)
2019年6月(1)
2019年4月(2)
2019年3月(1)
2019年2月(4)
2019年1月(4)
2018年12月(7)
2018年11月(9)
2018年10月(4)
2018年9月(1)
2018年8月(3)
2018年5月(2)
2018年3月(2)
2018年2月(2)
2016年9月(3)
最新评论

  1. Re:Python --深入浅出Apriori关联分析算法(二) Apriori关联规则实战
    列排序,axis应设置为0
    –wangker

  2. Re:python Kmeans算法解析
    到底是dataset还是datamat?
    –笑哦

  3. Re:详细解析kafka之kafka分区和副本
    我们可以通过replication-factor指定创建topic时候所创建的分区数。
    这个地方有错误吧,replication-factor不是副本数吗
    –私奔到冰岛

  4. Re:通俗地说决策树算法(二)实例解析
    非常感谢,写的很通俗易懂。对于想要快速了解算法原理而不是那么深入了解算法里的细节(包括数学)的人来说非常有帮助、友好。
    –xiaotang_sama

  5. Re:通俗地说决策树算法(三)sklearn决策树实战
    Y_train未定义
    –Judy_Han
    阅读排行榜

  6. 深入浅出KNN算法(一) KNN算法原理(46252)

  7. 深入浅出KNN算法(二) sklearn KNN实践(16069)

  8. Python --深入浅出Apriori关联分析算法(一)(15588)

  9. Java-- String源码分析(15324)

  10. kafka connect,将数据批量写到hdfs完整过程(12254)
    评论排行榜

  11. 一个故事告诉你什么才是好的程序员(35)

  12. kafka connect,将数据批量写到hdfs完整过程(8)

  13. Python --深入浅出Apriori关联分析算法(一)(4)

  14. 贝叶斯分类算法实例 --根据姓名推测男女(4)

  15. Actor模型浅析 一致性和隔离性(4)
    推荐排行榜

  16. 一个故事告诉你什么才是好的程序员(33)

  17. C,java,Python,这些名字背后的江湖!(6)

  18. 将excel文件内容存储到数据库,并可以实时在前端查看(不必生成文件)(6)

  19. 详细解析kafka之kafka分区和副本(4)

  20. Scala函数式编程指南(一) 函数式思想介绍(4)
    Copyright © 2020 zzzzMing
    Powered by .NET 5.0.0 on Kubernetes

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值