概述:涉及消息传输,都会涉及安全问题
本章涉及:
- 基础安全概念
- 通过XML或JAAS授权
- 授权技术
- 消息级别授权
- 构建一个自定义安全插件
6.1、介绍基础安全概念
介绍目前安全有,直接用户名密码、JAAS进行授权,ACL(权限控制列表)
6.2、授权
分为两种,一种为Xml配置,一种JAAS授权插件
6.2.1、配置简单授权插件(xml格式)
<?xml version="1.0" encoding="utf-8"?>
<broker xmlns="http://activemq.org/config/1.0" brokerName="localhost" dataDirectory="${activemq.base}/data">
<transportConnectors>
<transportConnector name="openwire" uri="tcp://localhost:61616"/>
</transportConnectors>
<plugins>
<simpleAuthenticationPlugin>
<users>
<authenticationUser username="admin" password="password" groups="admins,publishers,consumers"/>
<authenticationUser username="publisher" password="password" groups="publishers,consumers"/>
<authenticationUser username="consumer" password="password" groups="consumers"/>
<authenticationUser username="guest" password="password" groups="guests"/>
</users>¶
</simpleAuthenticationPlugin>
</plugins>
</broker>
6.2.2.配置JAAS插件
JAAS官方文档:http://www.oracle.com/technetwork/java/javase/jaas/index.html
它验证文件可以简单的文本文件、关系型数据库,LDAP等等,它必须要实现javax.security.auth.spi.LoginModule接口
创建一个login.config
activemq-domain {
org.apache.activemq.jaas.PropertiesLoginModule required
debug=true
org.apache.activemq.jaas.properties.user="users.properties"
org.apache.activemq.jaas.properties.group="groups.properties";
};
users.properties
admin=password
publisher=password
consumer=password
guest=password
groups.properties
admins=admin
publishers=admin,publisher
consumers=admin,publisher,consumer
guests=guest
最后配置
...
<plugins>
<jaasAuthenticationPlugin configuration="activemq-domain" />
</plugins>
...
6.3、授权
分为两种级别:一种操作级别和消息级别
6.3.1. 操作级别授权
有三种,读、写、Admin(读/写)
<plugins>
<jaasAuthenticationPlugin configuration="activemq-domain"/>
<authorizationPlugin>
<map>
<authorizationMap>
<authorizationEntries>
<authorizationEntry topic=">" read="admins" write="admins" admin="admins"/>
<authorizationEntry topic="STOCKS.>" read="consumers" write="publishers" admin="publishers"/>#
<authorizationEntry topic="STOCKS.ORCL" read="guests"/>
<authorizationEntry topic="ActiveMQ.Advisory.>" read="admins,publishers,consumers,guests" write="admins,publishers,consumers,guests" admin="admins,publishers,consumers,guests"/>
</authorizationEntries>
</authorizationMap>
</map>
</authorizationPlugin>
</plugins>
6.3.2.消息级别授权
需要实现org.apache.activemq.security.MessageAuthorizationPolicy接口
public class AuthorizationPolicy implements MessageAuthorizationPolicy {
private static final Log LOG = LogFactory.getLog(AuthorizationPolicy.class);
public boolean isAllowedToConsume (ConnectionContext context, Message message) {
LOG.info(context.getConnection().getRemoteAddress());
if (context.getConnection().getRemoteAddress().startsWith("/127.0.0.1")) {
return true;
} else {
return false;
}
}
}
然后配置:
<messageAuthorizationPolicy>
<bean class="org.apache.activemq.book.ch5.AuthorizationPolicy" xmlns="" />
</messageAuthorizationPolicy>
6.4、代理商级别操作
BrokerFilter类提供很多有用的操作
一种实现JAAS登录模块
一种实现自定义插件去处理安全问题
6.4.1 构建自定义安全插件
基于IP地址限制,IPAuthenticationBroker类,重写它BrokerFilter.addConnection();方法
public class IPAuthenticationBroker extends BrokerFilter {
List<String> allowedIPAddresses;
Pattern pattern = Pattern.compile("^/([0-9\\.]*):(.*)");
public IPAuthenticationBroker(Broker next, List<String> allowedIPAddresses) {
super(next);
this.allowedIPAddresses = allowedIPAddresses;
}
public void addConnection(ConnectionContext context, ConnectionInfo info)
throws Exception {
String remoteAddress = context.getConnection().getRemoteAddress();
Matcher matcher = pattern.matcher(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 {
throw new SecurityException("Invalid remote address " + remoteAddress);
}
super.addConnection(context, info);
}
}
实现自己的插件
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;
}
}
然后配置这个插件
<broker xmlns="http://activemq.org/config/1.0" brokerName="localhost" dataDirectory="${activemq.base}/data"plugins="#ipAuthenticationPlugin">
<transportConnectors>
<transportConnector name="openwire" uri="tcp://localhost:61616" />
</transportConnectors>
</broker>
<bean id="ipAuthenticationPlugin" class="org.apache.activemq.book.ch5.IPAuthenticationPlugin">
<property name="allowedIPAddresses">
<list>
<value>127.0.0.1</value>
</list>
</property>
</bean>