activemq mqtt基于db做连接认证

       本文的目的是通过开发定制化的插件来实现activemq的登录认证。

                                          

       当然,activemq可以通过在配置文件中设置用户、密码对连接做简单的鉴权认证。

  想想这个应用场景:

     1.每个mqtt client有独自的clientId、用户、密码

     2.随着时间的推移,原有的mqtt  client不再允许访问broker,而新的mqtt client在持续的增加

 

     如果成百上千的mqtt  client需要连接broker,在activemq的配置文件中更新配置这些用户、密码,这种方式工作量大,容易出错。

 

     那有没有一种方案,将需访问的用户、密码保存在db中,然后通过查询db的方式做连接认证呢?答案是肯定的,有!

 

     activemq提供了插件的方式让我们灵活的做连接认证,下面让我们一起看看如何实现这个方案。

 

     1. 创建一个java application,mvn文件中加入activemq的依赖包。jar包的版本与部署的activemq保持一致。

        
               org.apache.activemq
               activemq-broker
                5.15.0
            

 

      2. 创建一个broker plunin类,这类主要是在安装插件时,返回一个BrokerFilter。此例中返回AuthFilter,这个class请参考第3步

    package com.study.mqttatuh;

           import org.apache.activemq.broker.Broker;
           import org.apache.activemq.broker.BrokerFilter;
           import org.apache.activemq.broker.BrokerPlugin;

           public class LoginAuthPlugin implements BrokerPlugin {

              public Broker installPlugin(Broker broker) throws Exception {
                   return new AuthFilter(broker);
              }

           }

 

     3. 创建一个broker filter。关键地方就在于重载了addConnection这个方法,加入了用户密码验证,如果验证失败,则抛出SecurityException这样会导致mqtt client端连接失败,从而达到认证的目的。

            package com.study.mqttatuh;

import org.apache.activemq.broker.Broker;
               import org.apache.activemq.broker.BrokerFilter;

               import org.apache.activemq.broker.ConnectionContext;
               import org.apache.activemq.command.ConnectionInfo;

public class AuthFilter extends BrokerFilter {

 public AuthFilter(Broker next) {
                  super(next);
               }
 
              @Override 
               public void addConnection(ConnectionContext context, 
            ConnectionInfo info) throws Exception {
              auth(info.getUserName(),info.getPassword());
              super.addConnection(context, info);
             }
 
            private void auth(String userName,String password)
            {

//为了演示方便写死了要验证的用户密码,实际实施时查db验证
               if(!"userName1".equals(userName) || !"password1".equals(password))
               {
                   throw new SecurityException("Invalid  userName or password!");
               }
             }

}

 

     4.导出jar包。比如,此例中导出的jar包名为:mqttatuh-0.0.1-SNAPSHOT.jar

     5.上传jar包到activemq部署目录的lib目录下


[root@localhost lib]# pwd

/usr/apache-activemq-5.15.0/lib

[root@localhost lib]# ls

activemq-broker-5.15.0.jar           activemq-rar.txt                             geronimo-jta_1.0.1B_spec-1.0.1.jar

activemq-client-5.15.0.jar           activemq-spring-5.15.0.jar                   hawtbuf-1.11.jar

activemq-console-5.15.0.jar          activemq-web-5.15.0.jar                      jcl-over-slf4j-1.7.25.jar

activemq-jaas-5.15.0.jar             camel                                        mqttatuh-0.0.1-SNAPSHOT.jar

activemq-kahadb-store-5.15.0.jar     extra                                        optional

activemq-openwire-legacy-5.15.0.jar  geronimo-j2ee-management_1.1_spec-1.0.1.jar  slf4j-api-1.7.25.jar

activemq-protobuf-1.1.jar            geronimo-jms_1.1_spec-1.1.1.jar              web



     6.修改activemq的配置文件activemq.xml,broker段加入自定义的插件配置(plugins段为新增的

...(省略其它配置信息) 

          

         id="LoginAuthPlugin" class="com.study.mqttatuh.LoginAuthPlugin">

         

...(省略其它配置信息)

    7.重启activemq

    

    至此,我们的认证插件就安装配置好了。mqtt client试图建立连接时,如果提供的账号密码不匹配,则在AuthFilter中就会验证失败报SecurityException:Invalid  userName or password!


    当然此文的目的只是抛砖引玉,在AuthFilter的auth认证方法中,可以调用其它的认证接口服务来做登录认证;BrokerFilter中还有一些其它的方式,可供挖掘扩展,比如消息拦截、日志等。

   

 

 


你可能感兴趣的:(mqtt)