本文的目的是通过开发定制化的插件来实现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保持一致。
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中还有一些其它的方式,可供挖掘扩展,比如消息拦截、日志等。