ActiveMq mqtt自定义连接认证

ActiveMq可以通过在配置文件中设置用户、密码对连接做简单的鉴权认证。
对于复杂的验证逻辑,默认是没有办法处理,只能通过自定义插件处理。

使用场景

  • 每个mqtt客户端使用独立的用户、密码
  • 连接用户的黑名单管理
  • 用户和密码存在第三方的库中(数据库、redis等)

如果上万或者百万的用户需要连接broker,在activemq的配置文件中更新配置这些用户、密码,这种方式工作量大,容易出错,不容易管理,没有办法动态变更。

那有没有一种方案,将需访问的用户、密码保存在在第三方的库中(数据库、redis等)中,然后通过查询的方式做连接认证呢?

答案是肯定的,有!

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

创建maven工程

创建一个maven的工程,用于自定义认证处理。

引入activemq-brokerjar包,需要注意这里版本号需要和activemq版本一致

1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-broker</artifactId>
<version>5.15.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.20.RELEASE</version>
</dependency>

创建认证拦截器

创建一个自定义的BrokerFilter,重写addConnection方法,加入用户密码验证,如果验证失败,则抛出SecurityException异常,这样会导致mqtt client端连接失败,从而达到认证的目的。

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package com.wueasy.mqtt.auth;

import org.apache.activemq.broker.Broker;
import org.apache.activemq.broker.BrokerFilter;
import org.apache.activemq.broker.ConnectionContext;
import org.apache.activemq.command.ConnectionInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;


/**
* @Description: 认证拦截器
* @Copyright: 2018 wueasy.com Inc. All rights reserved.
* @author: fallsea
* @version 1.0
* @date: 2018年11月23日 下午12:19:27
*/
public class AuthFilter extends BrokerFilter{

private static Logger log = LoggerFactory.getLogger(AuthFilter.class);

public AuthFilter(Broker next) {
super(next);
}

@Override
public void addConnection(ConnectionContext context, ConnectionInfo info) throws Exception {

if(StringUtils.isEmpty(info.getUserName()) || StringUtils.isEmpty(info.getPassword())) {
throw new SecurityException("账号或密码不能为空!");
}

//为了方便演示,这里写死了要验证的用户和密码,实际根据自己的需求做处理
if(!"admin".equals(info.getUserName()) || !"123456".equals(info.getPassword()))
{
throw new SecurityException("账号或密码不正确!");
}

if(log.isInfoEnabled()) {
log.info("创建连接,ClientId:{},RemoteAddress:{}",context.getClientId(),context.getConnection().getRemoteAddress());
}

super.addConnection(context, info);
}

}

创建认证插件

拆个那就一个BrokerPlugin认证插件,使自定义的验证拦截器AuthFilter生效

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.wueasy.mqtt.auth;

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

/**
* @Description: 认证插件
* @Copyright: 2018 wueasy.com Inc. All rights reserved.
* @author: fallsea
* @version 1.0
* @date: 2018年11月23日 下午12:19:20
*/
public class AuthPlugin implements BrokerPlugin{

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

}

ActiveMq配置

  1. 把自定义认证插件,通过maven生成jar包。

  2. jar包,拷贝到ActiveMq安装目录,lib文件夹中。

  3. activemq.xml配置文件,broker段加入自定义的插件配置

    1
    2
    3
    4
    5
    6
    7
    8
    <broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}">

    <!-- 插件配置 -->
    <plugins>
    <bean xmlns="http://www.springframework.org/schema/beans" id="AuthPlugin" class="com.wueasy.mqtt.auth.AuthPlugin"></bean>
    </plugins>

    </broker>

配置成功后,重启ActiveMq

源码下载

https://github.com/fallsea/mqtt

mqtt客户端下载

mqtt客户端测试工具下载地址:http://www.jensd.de/apps/mqttfx/