ActiveMQ现在无疑成为JMS领域开源产品的龙头,基于开源框架的J2EE开发者大多用它来进行异步数据的传递工作。
比较搞的是截至ActiveMQ4.1.1版本的缺省配置仍然没有做任何的安全性配置,也就是说如果没有在软硬件防火墙层面上做限制的话,任何客户
端都可以连接上JMS提供者发送和接收消息!估计大部分开发者用的都是缺省设置吧,呵呵。
当然,ActiveMQ的开发者还不至于弱智到这种程度,连最起码的权限验证都不支持。在org.apache.activemq.security包下面是提供了两种可选验证机制的:用户名/密码Map和JAAS。
无疑,基于JAAS的验证是J2EE规范之一,能实现最大的灵活性配置,不过一般情况下异步发个邮件什么的应用没有必要搞这么复杂。这里关注的是最
简单的用户名/密码验证方法,就像JDBC数据源一样。
ActiveMQ服务broker是在activemq.xml
中配置的,其本质上也是
一个spring bean配置文件。4.0版本以后支持xbean配置方式,典型的配置文件如下:
代码
- <
broker
brokerName
=
"localhost"
useJmx
=
"true"
>
-
<
persistenceAdapter
>
-
<
journaledJDBC
journalLogFiles
=
"5"
dataDirectory
=
"${webapp.root.cn.com.reachway}/WEB-INF/activemq-data"
-
dataSource
=
"#derby-ds"
/>
- </
persistenceAdapter
>
-
<
transportConnectors
>
-
<
transportConnector
name
=
"openwire"
uri
=
"tcp://localhost:61616"
discoveryUri
=
"multicast://default"
/>
- </
transportConnectors
>
-
<
networkConnectors
>
-
<
networkConnector
name
=
"default-nc"
uri
=
"multicast://default"
/>
- </
networkConnectors
>
- </broker
>
broker实质上就是一个org.apache.activemq.broker.
BrokerService实例,可以扩展之以提供简单验证,如下:
- public
class
ConfigurableAuthenticationBroker
extends
XBeanBrokerService {
-
private
String userName =
"jms"
;
-
private
String password =
"password"
;
-
public
String getUserName() {
-
return
userName;
- }
-
public
void
setUserName(String userName) {
-
this
.userName = userName;
- }
-
public
String getPassword() {
-
return
password;
- }
-
public
void
setPassword(String password) {
-
this
.password = password;
- }
-
protected
Broker addInterceptors(Broker broker)
throws
Exception {
- broker =
super
.addInterceptors(broker);
- Map userPasswordMap =
new
HashMap();
- userPasswordMap.put(userName, password);
- broker =
new
SimpleAuthenticationBroker(broker, userPasswordMap,
new
HashMap());
-
return
broker;
- }
- }
由于这里采用xbean方式配置,所以扩展的是XBeanBrokerService
类。
相应的activemq.xml
中的broker配置改为:
代码
- <
c:ConfigurableAuthenticationBroker
brokerName
=
"localhost"
useJmx
=
"true"
userName
=
"jms"
password
=
"password"
-
xml
ns:c
=
"java://cn.com.xxx.framework.common.jms"
>
-
<
persistenceAdapter
>
-
<
journaledJDBC
journalLogFiles
=
"5"
dataDirectory
=
"${webapp.root.cn.com.xxx}/WEB-INF/activemq-data"
-
dataSource
=
"#derby-ds"
/>
- </
persistenceAdapter
>
-
<
transportConnectors
>
-
<
transportConnector
name
=
"openwire"
uri
=
"tcp://localhost:61616"
discoveryUri
=
"multicast://default"
/>
- </
transportConnectors
>
-
<
networkConnectors
>
-
<
networkConnector
name
=
"default-nc"
uri
=
"multicast://default"
/>
- </
networkConnectors
>
- </c:ConfigurableAuthenticationBroker
>
可以看到在bean c:ConfigurableAuthenticationBroker
的属性中多了userName和password,于是可配置性便有了。如果想要配置更多的用户可以改成map型了,道理都是一样的。
相应的,JMS客户端在连接时就需要加上用户名和密码属性了,否则就会返回错误:
- javax.jms.JMSException: User name or password is invalid.
- at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:
46
) - at org.apache.activemq.ActiveMQConnection.syncSendPacket(ActiveMQConnection.java:
1181
) - at org.apache.activemq.ActiveMQConnection.ensureConnectionInfoSent(ActiveMQConnection.java:
1263
)
若是采用的spring管理的JMS资源适配器方式,给适配器bean加上用户名、密码属性即可:
代码
- <
bean
id
=
"jmsResourceAdapter"
class
=
"org.apache.activemq.ra.ActiveMQResourceAdapter"
>
-
<
property
name
=
"serverUrl"
value
=
"tcp://localhost:61616"
/>
-
<
property
name
=
"userName"
value
=
"jms"
/>
-
<
property
name
=
"password"
value
=
"password"
/>
- </bean
>
其实很简单,但也够用了。回头有空再研究下JAAS方式吧:)