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 发布!

相关推荐
唐墨1234 小时前
论,物联网日志系统架构如何设计?
物联网·系统架构
速易达网络10 小时前
基于UniApp的新大陆物联网平台温湿度检测系统开发方案
物联网·uni-app
蓝蜂物联网14 小时前
蓝蜂网关在雄安新区物联网建设中的关键应用
物联网·信息可视化·边缘计算
flushddd18 小时前
GOOUUU ESP32-S3-CAM 果云科技开发板开发指南(二)(超详细!)Vscode+espidf 摄像头拍摄视频实时传输到LCD,文末附源码
vscode·科技·单片机·物联网·esp32
厦门辰迈智慧科技有限公司1 天前
现代化水库运行管理矩阵建设的要点
运维·网络·物联网·线性代数·安全·矩阵·监测
时序数据说2 天前
时序数据库为什么选IoTDB?
大数据·数据库·物联网·开源·时序数据库·iotdb
网络研究院2 天前
将黑客拒之物联网网络之外的竞赛
网络·物联网·5g·安全·趋势
欣赏你流浪^2 天前
物联网智能感知进阶:基于YOLO的琏雾系统视频分析
物联网·yolo·音视频
TDengine (老段)2 天前
TDengine IDMP 基本功能(3.数据三化处理)
大数据·数据库·物联网·ai·语言模型·时序数据库·tdengine
鸭鸭鸭进京赶烤3 天前
EI检索-学术会议 | 人工智能、虚拟现实、可视化
人工智能·物联网·5g·信息可视化·云计算·vr·信号处理