一、实现原理
ActiveMQ 的层次结构图如图1.1所示。
图1.1 ActiveMQ 结构层次图
由上图可知,ActiveMQ 主要由Connectors、Broker和Message Store三部分组成,在此重点关注Broker部分。Broker 在 ActiveMQ 中的表现形式为“Interface(接口)”,该接口封装了 ActiveMQ 的连接管理、Session管理、消息的发送和接收以及其它的一些功能方法;而 BrokerFilte r实现了这个接口,并提供链式结构支持,其可以拦截所有Broker方法的实现并传递结果给链式结构的下一个节点,从而形成一个完整的“职责链”模式。
Broker 部分最下面的 Region 是核心组件,在其之上的都是 Broker 的各类插件,这些插件继承于 BrokerFilter,与 Broker 接口保持兼容但扩展了 Broker 的功能,各类插件的具体功能如下:
1)“System Plugin”是指 AciveMQ 内部使用 Plugin 机制实现的一些系统功能,用户不能定制;
2)“AMQ Plugin”指的是 ActiveMQ 已经实现好了,可以在配置文件中自由选择的一些插件,例如简单的安全插件和 JAAS 安全插件;
3)“USER Plugin”是指用户自己实现的 ActiveMQ 插件,需要用户把相关 jar 包放入到 ActiveMQ 的启动 classpath 中,并在配置文件中进行配置才能正确加载。
ActiveMQ 的插件实际上是基于 Broke r的一个 Filter 链,整个设计类似于 Server Applet 的 Filter 结构,所有的 Plugin 构成一个链式结构,每个插件实际上都是一个 “Interceptor”,类结构如图1.2所示:
图1.2 Broker 类结构图
由于 ActiveMQ 允许用户自己实现个性化插件,因此,基于 IP 的验证和授权插件可依此原理实现。
二、实现源码
1、IPAuthenticationPlugin
package tewa.apache.activemq.security;
import java.util.List;
import org.apache.activemq.broker.Broker;
import org.apache.activemq.broker.BrokerPlugin;
public class IPAuthenticationPlugin implements BrokerPlugin {
List<String> allowedIPAddresses;
public Broker installPlugin(Broker broker) throws Exception {
return new IPAuthenticationBroker(broker, allowedIPAddresses);
}
public List<String> getAllowedIPAddresses() {
return allowedIPAddresses;
}
public void setAllowedIPAddresses(List<String> allowedIPAddresses) {
this.allowedIPAddresses = allowedIPAddresses;
}
}
2、IPAuthenticationBroker
package tewa.apache.activemq.security;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.activemq.advisory.AdvisoryBroker;
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;
public class IPAuthenticationBroker extends BrokerFilter {
List<String> allowedIPAddresses;
Pattern pattern = Pattern.compile("^([0-9\\.]*):(.*)");
private static final Logger log = LoggerFactory.getLogger(AdvisoryBroker.class);
public IPAuthenticationBroker(Broker next, List<String> allowedIPAddresses) {
super(next);
this.allowedIPAddresses = allowedIPAddresses;
}
public String getSubAddress(String remoteAddress) {
String subAddress = null;
for (int i = 0; i < remoteAddress.length(); i++) {
char ch = remoteAddress.charAt(i);
if (ch >= '0' && ch <= '9') {
subAddress = remoteAddress.substring(i);
break;
}
}
return subAddress;
}
@Override
public void addConnection(ConnectionContext context,
ConnectionInfo info) throws Exception {
String remoteAddress = context.getConnection().getRemoteAddress();
//remoteAddress的形式如:tcp://127.0.0.1: 6572,由于正则表达式用得不好,在此截取127.0.0.1: 6572来判断
//这个正则表达式怎么用,欢迎赐教
Matcher matcher = pattern.matcher(getSubAddress(remoteAddress));
if (matcher.matches()) {
String ip = matcher.group(1);
if (!allowedIPAddresses.contains(ip)) {
throw new SecurityException("Connecting from IP address " + ip + " is not allowed");
} else {
log.info("Connecting from address {}", remoteAddress);
}
} else {
throw new SecurityException("Invalid remote address " + remoteAddress + "subAddress " + getSubAddress(remoteAddress));
}
super.addConnection(context, info);
}
}
三、安装插件
1、将代码导出 jar:IPAuthenticationPlugin.jar;
2、将 jar 包拷贝至 activemq 目录下的 lib 目录下;
3、打开activemq\conf\activemq.xml,在 broker 节点中加入:
<plugins>
<bean xmlns="http://www.springframework.org/schema/beans" id="ipAuthenticationPlugin" class="tewa.apache.activemq.security.IPAuthenticationPlugin">
<property name="allowedIPAddresses">
<list>
<value>127.0.0.1</value>
<value>192.168.168.1</value>
</list>
</property>
</bean>
</plugins>
4、重启 activemq 服务。
备注:
测试插件的 activemq 服务版本:V5.14.5;
插件源码下载路径:ActiveMQ 基于IP验证和授权插件的源码及jar
参考资料:
1、http://blog.youkuaiyun.com/scorpio3k/article/details/48159839
2、《ActiveMQ in Action》 6.3小节
---------------------
版权声明:本文为优快云博主「寒风飘絮」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/xust_psy/article/details/69943705