activemq作为消息中间件这样一个独立的个体存在,连通用户和服务器。如果没有一套完备的安全机制去设置用户权限设置消息分发机制可想后果是非常严重。ActiveMQ如果不加入安全机制的话,任何人只要知道消息服务的具体地址(包括ip,端口,消息地址[队列或者主题地址,),都可以肆无忌惮的发送、接收消息。今天我们就探讨一下他的安全机制。
1.安全机制介绍
我们讨论安全机制一般包括两个部分:
- 验证(Authentication):就是要验证一个用户的有效性,即用户名、密码是否正确;
- 授权(Authorization):就是授予用户某种角色,以使用户只能访问具有相应角色的资源。
activemq考虑到安全方案效率问题,他提供了可插拔的安全机制,你可以使用不同的安全插件灵活为你的系统配置安全访问方式。目前activemq提供两种安全控制插件:
- 简单认证插件(Simple authentication plugin-in)
- JAAS认证插件(Java Authentication and Authorization Service)
下面我们分别就这两种插件的使用做一个说明。
2.简单认证插件
简单认证插件的目的就是让用户简单配置。我们打开activemq服务的目录apache-activemq,在 conf目录下找到activemq.xml。进去找到:
<shutdownHooks>
<bean xmlns="http://www.springframework.org/schema/beans" class="org.apache.activemq.hooks.SpringContextHook" />
</shutdownHooks>
在他下面添加如下即可:
<plugins>
<simpleAuthenticationPlugin>
<users>
<authenticationUser username="admin" password="admin" groups="users,admins"/>
<authenticationUser username="user" password="password" groups="users"/>
</users>
</simpleAuthenticationPlugin>
</plugins>
☆注意:此处添加的用户名和密码要和你在项目中配置的activemq用户名密码是一致的,如果在项目中不是此处已经配置过的用户发送消息的话,activemq客户端不会受理该消息。这样就达到了对非命中用户拦截的目的。
比如说你有客户端使用的用户是:
<amq:connectionFactory id="amqConnectionFactory"
brokerURL="tcp://127.0.0.1:61616"
userName="admin"
password="admin" />
那你就把该用户配置到activemq的配置文件中:
<authenticationUser username="admin" password="admin" groups="users,admins"/>
上面是对用户进行限制,我们也可以对ip进行限制,还是在刚才的配置里面加上下面这一句:
<plugins>
<simpleAuthenticationPlugin>
<users>
<authenticationUser username="admin" password="admin" groups="users,admins"/>
<!-- <authenticationUser username="user" password="password" groups="users"/>
<authenticationUser username="guest" password="password" groups="guests"/>-->
</users>
<transportConnectors>
<transportConnector name="connection1" uri="tcp://0.0.0.0:61616" />
</transportConnectors>
</simpleAuthenticationPlugin>
</plugins>
0.0.0.0代表本网络中的所有主机,意味着该网段的所有主机都是可以通讯的。如果改成localhost或者127.0.0.1这种的那就只有本机了。这样我们就达到了通过IP限制的目的。
3.JAAS认证插件
JAAS(Java Authentication and Authorization Service)也就是java的验证Authentication)、授权(Authorization)服务。简单来说,验证Authentication就是要验证一个用户的有效性,即用户名、密码是否正确。授权Authorization就是授予用户某种角色,可以访问哪些资源。JAASAuthentication Plugin依赖标准的JAAS机制来实现认证。通常情况下,你需要通过设置Java.security.auth.login.config系统属性来配置login
modules的配置文件。如果没有指定这个系统属性,那么JAAS Authentication Plugin会缺省使用login.config作为文件名。
首先我们需要编写一个login.config文件:
activemq {
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=admin
user=ad1
guest=ad1
group.properties文件:
admins=admin
users=user
guests=guest
☆需要注意的是,PropertiesLoginModule使用本地文件的查找方式,而且查找时采用的base directory即login.config文件所在的目录,所以说这三个文件需要在同一个目录里才会找得到。另外,activemq 5.9 默认提供了以上的配置文件,我们来看一下文件目录:
然后我们还是在activemq.xml配置文件中添加插件。还是上面简单插件添加的位置,添加以下插件即可,只不过你的把之前添加的简单插件注释掉。
<plugins>
<jaasAuthenticationPlugin configuration="activemq-domain" />
<authorizationPlugin>
<map>
<authorizationMap>
<authorizationEntries>
<!-- .表示通配符,例如USERS.>表示以USERS.开头的主题,>表示所有主题,read表示读的权限,write表示写的权限,admin表示角色组-->
<authorizationEntry queue=">" read="admins,guests" write="guests" admin="admins,guests" />
<authorizationEntry queue="USERS.>" read="users" write="users" admin="users" />
<authorizationEntry queue="GUEST.>" read="guests" write="guests,users" admin="guests,users" />
<authorizationEntry topic=">" read="admins" write="admins" admin="admins" />
<authorizationEntry topic="USERS.>" read="users" write="users" admin="users" />
<authorizationEntry topic="GUEST.>" read="guests" write="guests,users" admin="guests,users" />
<authorizationEntry topic="ActiveMQ.Advisory.>" read="guests,users" write="guests,users" admin="guests,users"/>
</authorizationEntries>
</authorizationMap>
</map>
</authorizationPlugin>
</plugins>
添加完以上配置部分,重启avtivemq服务端,就会按照上面配置的用户进行读写的权限配置。
从上面看JAAS插件的权限分配要比简单插件的权限更加细致,不同的用户可以分别配置读写的权限,admin用户拥有创建topic或是queue的特权等等这样细致的划分,不同的用户各司其职,减少了误操作,或是刻意破换的可能性。