tlmqtt:如何基于责任链模式的高效认证

tlmqtt 是一款基于Java开发的轻量级高并发MQTT Broker,采用NettyProject Reactor实现异步通信,完整支持MQTT 3.1.1 协议,包括QoS 消息分级、主题通配符、消息持久化等核心功能。项目采用模块化设计,提供认证(文件/数据库/HTTP)数据桥接(Kafka/MySQL )和存储(内存/Redis)等可扩展组件,支持MQTTWebSocket 双协议接入。具备生产级特性如SSL加密、会话恢复及高并发处理能力,适用于物联网和实时通信场景。

认证

mqtt协议规定了CONNECT 包含有UsernamePassword字段。实现可以选择如何使用这些字段的内容。他们也可能提供自己的认证机制,使用额外的认证系统。 而tlmqtt 实现了基本文件mysqlhttp接口的3种认证方式,并且提供了扩展让用户自行去实现认证方式并添加到认证链中,其中只要有任何一个认证通过了,那么此次客户端连接就是通过的

tlmqtt 认证原理

tlmqtt 存在一个抽象类AbstractTlAuthentication它定义了认证相关的抽象方法,有具体的认证器去实现

php 复制代码
  /**
     * 认证接口
     * @author hszhou
     * @datetime: 2025-05-10 10:51:55
     * @param username 用户名
     * @param password 密码
     * @return boolean 是否成功
     **/
    abstract public boolean authenticate(String username, String password);

    /**
     * 是否启用了该认证器
     * @author hszhou
     * @datetime: 2025-05-12 10:11:26
     * @return boolean 是否启用
     **/
    abstract public boolean enabled();


    /**
     * 添加新的认证主体
     * @author hszhou
     * @datetime: 2025-05-15 17:53:17
     * @param object 添加的认证实体
     **/
    abstract public void add(Object object);

NoneAuthenticationService

tlmqtt 是可以通过一个配置来进行关闭客户端的认证的。

yml 复制代码
auth:
 enabled: true #是否开启认证 false就是关闭认证

其实现原理就是通过NoneAuthenticationService这个认证器。也是认证链中的第一个认证器。

typescript 复制代码
   @Override
   public boolean authenticate(String username, String password) {
       return true;
   }

其主要实现了authenticate方法返回的是trueNoneAuthenticationService并不关心客户端的用户名和密码,也就是无论用户名和密码是什么,他都不会在意,只会返回true。表示认证通过,而enabled方法返回的就是是否开启,一旦开启了,那么这个authenticate就会执行。由于处于认证链的首位。只要通过了就不会执行其他的认证了。

FixTlAuthentication

FixTlAuthentication是基于固定用户的认证方式。其固定的用户的配置方式有2种, 第一种是基于文件的,这种方式是提前将用户写入到配置文件中

yml 复制代码
auth:
  enabled: true #是否开启认证 false就是关闭认证
  user: #开启认证后fix的认证信息
    - username: watson
      password: 12345
    - username: zhouhs
      password: 12345

第二种方式是基于编程的tlmqtt启动引导类支持动态添加用户

java 复制代码
tlBootstrap.setFixUser(Collections.singletonList(new TlUser("admin","12345")))

FixTlAuthentication的内部维护了一个用户列表,authenticate方法就是将客户端的用户名与密码将内部的用户列表继续依次匹配。只要有任何一个匹配成功就返回。

java 复制代码
    public boolean authenticate(String username, String password) {
        if(users.isEmpty()){
            return false;
        }
        for (TlUser user : users) {
            if (user.getUsername().equals(username) && user.getPassword().equals(password)) {
                log.debug("username = 【{}】,password = 【{}】 pass",username,password);
                return true;
            }
        }
        return false;
    }

而编程式的添加用户就是往内部的用户列表中添加用户

java 复制代码
    @Override
    public void add(Object object) {

        if( object instanceof TlUser){
            log.debug("join fix authentication user 【{}】",object);
            this.users.add((TlUser) object);
        }
    }

HttpTlAuthentication

HttpTlAuthentication认证器是基于http请求的认证器。也是tlmqtt 的内置认证器之一。通过将用户名与密码当做参数请求第三方的API进行认证。只要API返回的状态码为200 ,注意的是这里的状态码200HTTP的状态码,而不是第三方系统自己定义的200 . tmqtthttp请求封装成一个对象HttpEntityInfo。里面有API的地址,参数等等信息

java 复制代码
public class HttpEntityInfo {

    /**请求的地址*/
    private String url;
    /**方法类型 post或者get*/
    private String method;
    /**请求头*/
    private HashMap<String, String> headers;
    /**用户的参数 例如 参数是uname 与pwd 那么这个params的参数就是("username","uname") ("password","pwd")*/
    private HashMap<String,String> params;

}

HttpTlAuthentication将认证接口大致分为3类,

  • POST请求的form表单提交
  • POST请求的json数据提交
  • GET请求

最终只要请求返回的是200就认证认证成功

HttpTlAuthentication认证过滤器不单单可以设置一个API。可以通过多个API接口组成的集合进行认证。其内部维护了一个HttpEntityInfo的集合。只要任何一个API通过,及认证通过

java 复制代码
   private final List<HttpEntityInfo> httpEntityInfos;

HttpTlAuthentication提供了动态添加http接口的方式

java 复制代码
    @Override
    public void add(Object object) {
        if (object instanceof HttpEntityInfo) {
            this.httpEntityInfos.add((HttpEntityInfo) object);
        }
    }

使用方式

java 复制代码
  HttpEntityInfo entityInfo = AuthenticationHttpProvider.formLogin();
  HttpEntityInfo login = AuthenticationHttpProvider.getLogin();
  tlBootstrap.addAuthEntity(entityInfo)
              .addAuthEntity(login)

SqlTlAuthentication

SqlTlAuthentication认证器是基于mysql数据库的认证,tlmqttSqlTlAuthentication的数据封装成了一个SQL对象SqlEntityInfo

java 复制代码
  /**地址*/
    private String host;

    /**端口号*/
    private String port;

    /**用户名*/
    private String username;

    /**密码*/
    private String password;

    /**数据库名*/
    private String  database;

    /**表名*/
    private String table;

    /**用户名字段*/
    private String usernameColumn;

    /**密码字段*/
    private String passwordColumn;

    private String driverClassName;

如果需要使用到SqlTlAuthentication认证过滤器,就需要添加相应的SqlEntityInfoSqlEntityInfo设置数据库的地址,表名和用户名和密码的字段。然后其内部维护了一个SqlEntityInfo集合,与http认证器一致,只要有任何一个认证通过即可,当用户设置成功后,tlmqtt 会执行内部的sql语句并替换相应的参数

sql 复制代码
 private static final String SQL = "SELECT COUNT(*) FROM %s WHERE %s = ? AND %s = ?";

SqlTlAuthentication提供动态方法新增SqlEntityInfo的方式。使用方法

java 复制代码
SqlEntityInfo sqlEntityInfo = AuthenticationMysqlProvider.providerDemo();
tlBootstrap .addAuthEntity(sqlEntityInfo)    

可扩展的认证链

当上述认证器不满足系统的认证方式,tlmqtt 提供了可扩展的认证器。是需要用户继承AbstractTlAuthentication类即可。然后实现authenticate方法。然后通过辅助引导类TlBootstrapaddAuthentication方法即可。

实现AbstractTlAuthentication类

java 复制代码
@Slf4j
public class NoneA extends AbstractTlAuthentication {
    @Override
    public boolean authenticate(String username, String password) {
        return true;
    }

    @Override
    public boolean enabled() {
        return true;
    }

    @Override
    public void add(Object object) {

    }
}

添加认证器

java 复制代码
 tlBootstrap.addAuthentication(new NoneA())

这样就可以将自定义的认证器添加到tlmqtt的整个认证体系中。

结语

欢迎通过以下方式参与项目共建:

  1. 提交 Issue:反馈 Bug 或提出功能建议
  2. 提交 PR:优化代码或新增功能(建议先创建 Issue 沟通方案)
  3. Star/Fork:支持项目持续发展

联系方式:

tlmqtt致力于为物联网开发者提供轻量、高效的 MQTT 消息服务,期待您的加入! 🚀

本文由博客一文多发平台 OpenWrite 发布!

相关推荐
TDengine (老段)5 小时前
TDengine 与开源可视化编程工具 Node-RED 集成
大数据·物联网·开源·node.js·时序数据库·tdengine·涛思数据
TDengine (老段)12 小时前
Kafka 向 TDengine 写入数据
数据库·物联网·kafka·linq·时序数据库·tdengine·涛思数据
国科安芯14 小时前
AS32A601与ASM1042芯片在电力系统自动化监控中的应用效能分析
单片机·物联网·自动化
深圳市尚想信息技术有限公司17 小时前
LTC3130EMSE#TRPBF ADI电子元器件深度解析 物联网/工业传感器首选!
物联网·转换器·adi
TGC达成共识17 小时前
解锁身心密码:从“心”拥抱健康生活
科技·物联网·程序人生·百度·生活·新浪微博·高考
咕噜企业签名分发-淼淼1 天前
蓝牙物联网多个核心应用场景开发与应用细化分析
物联网
QiYueFangBeiJing1 天前
内网运行控制四百来个海康威视硬件物联网定员管控软件(华为平板电脑版)
物联网·华为·电脑
华普微HOPERF1 天前
让温度“说话”,数字温度传感器如何智能感知温度?
科技·单片机·嵌入式硬件·物联网·智能家居
乐鑫科技 Espressif1 天前
EchoEar(喵伴):乐鑫发布与火山引擎扣子联名 AI 智能体开发板
人工智能·物联网·火山引擎·乐鑫科技