探索ActiveMQ之安全机制

标签: activeMQ

       上一篇博文(点击打开链接)主要介绍了在第一次使用ActiveMQ进行调测过程中遇到的一些问题、问题产生的原因以及解决方案,但是上次测试通了之后发现一个问题:不论在生产者配置文件还是消费者配置文件中,尽管配置了用户名跟密码,但却并没有真正用到:

<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
              <!-- ActiveMQ服务地址 -->
              <property name="brokerURL" value="failover:tcp://127.0.0.1:61616" />
              <property name="userName" value="system"/>          <!--配置但未使用到的用户名-->
              <property name="password" value="manager"/>         <!--配置但未使用到的密码-->
              <!-- 消息传输监听器 处理网络及服务器异常 -->
              <property name="transportListener">
                     <bean class="com.sts.listener.ActiveMQTransportListener" />
              </property>
</bean>

那么问题来了,这个用户名跟密码是干啥用的?按理说应该起到访问认证作用,但为什么没有找到拦截校验的地方呢?

通过进一步学习发现,并非用户名与密码没有用,而是因为在ActiveMQ的配置文件中并未设置用户名密码的拦截校验,导致所有的用户名密码均可不校验通过。如何设置拦截规则?

进入activemq的bin目录下,可以看到有很多配置文件:

[[email protected] /usr/local/drp/activemq/apache-activemq-5.15.4/conf]# ll
total 80
-rw-r--r-- 1 root root 6162 Jul  5 09:41 activemq.xml
-rw-r--r-- 1 root root 1370 May 18 01:59 broker.ks
-rw-r--r-- 1 root root  592 May 18 01:59 broker-localhost.cert
-rw-r--r-- 1 root root  665 May 18 01:59 broker.ts
-rw-r--r-- 1 root root 1357 May 18 01:59 client.ks
-rw-r--r-- 1 root root  665 May 18 01:59 client.ts
-rw-r--r-- 1 root root 1172 May 18 02:05 credentials-enc.properties
-rw-r--r-- 1 root root 1162 Jul  5 09:42 credentials.properties
-rw-r--r-- 1 root root  962 May 18 02:05 groups.properties
-rw-r--r-- 1 root root 1011 May 18 02:05 java.security
-rw-r--r-- 1 root root 1087 May 18 02:05 jetty-realm.properties
-rw-r--r-- 1 root root 7795 May 18 02:05 jetty.xml
-rw-r--r-- 1 root root  965 May 18 02:05 jmx.access
-rw-r--r-- 1 root root  964 May 18 02:05 jmx.password
-rw-r--r-- 1 root root 3071 May 18 02:05 log4j.properties
-rw-r--r-- 1 root root 1207 May 18 02:05 logging.properties
-rw-r--r-- 1 root root 1016 May 18 02:05 login.config
-rw-r--r-- 1 root root  961 May 18 02:05 users.properties

其中jetty-realm.properties中配置的是访问web也就是控制台的用户名密码:

admin: admin, admin
user: user, user

在jetty.xml中有个id为securityConstraint的bean:

<bean id="adminSecurityConstraint" class="org.eclipse.jetty.util.security.Constraint">
        <property name="name" value="BASIC" />
        <property name="roles" value="admin" />
         <!-- set authenticate=false to disable login -->
        <property name="authenticate" value="true" />
</bean>

将property name为authenticate的属性value="false" 改为"true",高版本的已经默认为true了。

authenticate属性是是否开启用户认证,true:开启,false:关闭

上一步执行之后,进入activemq.xml,在<broker>节点内增加一个插件:

 <plugins>
                <simpleAuthenticationPlugin>
                <users>
                         <authenticationUser username="sts" password="123456" groups="admins"/>
                </users>
                </simpleAuthenticationPlugin>
  </plugins>

注:username/password即用户名与密码,groups为该用户所属用户组(不可缺),若不配置会报错:

WARN | Failed to connect to [tcp://127.0.0.1:61616] after: 10 attempt(s) continuing to retry.

groups中的组名可以是不存在的,系统会默认是新的组,也可以在配置文件中配置。用户组在groups.properties配置:

## ---------------------------------------------------------------------------
## Licensed to the Apache Software Foundation (ASF) under one or more
## contributor license agreements.  See the NOTICE file distributed with
## this work for additional information regarding copyright ownership.
## The ASF licenses this file to You under the Apache License, Version 2.0
## (the "License"); you may not use this file except in compliance with
## the License.  You may obtain a copy of the License at
##
## http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
## ---------------------------------------------------------------------------

admins=admin

默认有个admins,也可在里面添加其他的用户组或将用户添加在admins组内,组内的用户之间用逗号隔开。

在activemq.xml中配置客户端的访问用户名密码之后,进行测试:

在客户端的配置文件中修改用户名密码为上面设置的用户名密码:

<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
              <!-- ActiveMQ服务地址 -->
              <property name="brokerURL" value="failover:tcp://127.0.0.1:61616" />
              <property name="userName" value="sts"/>
              <property name="password" value="123456"/>
              <!-- 消息传输监听器 处理网络及服务器异常 -->
              <property name="transportListener">
                     <bean class="com.sts.listener.ActiveMQTransportListener" />
              </property>
       </bean>

运行生产消息测试类,测试结果为:


修改用户名或密码与配置不一致,运行生产消息测试类:

RROR | 发送消息失败
org.springframework.jms.IllegalStateException: javax.jms.JMSSecurityException: User name [sts] or password is invalid.; nested exception is javax.jms.IllegalStateException: javax.jms.JMSSecurityException: User name [sts] or password is invalid.
	at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:279)
	at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:169)
	at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:497)
	at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:580)
	at com.sts.testPro.MessageSender.send(MessageSender.java:54)
	at com.sts.testPro.MessageSender.integraMessage(MessageSender.java:43)
	at com.sts.testCustomer.MQProducerTest.main(MQProducerTest.java:24)
Caused by: javax.jms.IllegalStateException: javax.jms.JMSSecurityException: User name [sts] or password is invalid.
	at org.apache.activemq.jms.pool.ConnectionPool.createSession(ConnectionPool.java:154)
	at org.apache.activemq.jms.pool.PooledConnection.createSession(PooledConnection.java:167)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.springframework.jms.connection.SingleConnectionFactory$SharedConnectionInvocationHandler.invoke(SingleConnectionFactory.java:620)
	at com.sun.proxy.$Proxy1.createSession(Unknown Source)
	at org.springframework.jms.support.JmsAccessor.createSession(JmsAccessor.java:192)
	at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:485)
	... 4 more
Caused by: javax.jms.JMSSecurityException: User name [sts] or password is invalid.
	at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:52)
	at org.apache.activemq.ActiveMQConnection.syncSendPacket(ActiveMQConnection.java:1392)
	at org.apache.activemq.ActiveMQConnection.ensureConnectionInfoSent(ActiveMQConnection.java:1495)
	at org.apache.activemq.ActiveMQConnection.createSession(ActiveMQConnection.java:323)
	at org.apache.activemq.jms.pool.ConnectionPool.makeSession(ConnectionPool.java:107)
	at org.apache.activemq.jms.pool.ConnectionPool$1.makeObject(ConnectionPool.java:77)
	at org.apache.activemq.jms.pool.ConnectionPool$1.makeObject(ConnectionPool.java:73)
	at org.apache.commons.pool2.impl.GenericKeyedObjectPool.create(GenericKeyedObjectPool.java:1041)
	at org.apache.commons.pool2.impl.GenericKeyedObjectPool.borrowObject(GenericKeyedObjectPool.java:357)
	at org.apache.commons.pool2.impl.GenericKeyedObjectPool.borrowObject(GenericKeyedObjectPool.java:279)
	at org.apache.activemq.jms.pool.ConnectionPool.createSession(ConnectionPool.java:136)
	... 13 more
Caused by: java.lang.SecurityException: User name [sts] or password is invalid.
	at org.apache.activemq.security.SimpleAuthenticationBroker.authenticate(SimpleAuthenticationBroker.java:103)
	at org.apache.activemq.security.SimpleAuthenticationBroker.addConnection(SimpleAuthenticationBroker.java:71)
	at org.apache.activemq.broker.BrokerFilter.addConnection(BrokerFilter.java:99)
	at org.apache.activemq.broker.TransportConnection.processAddConnection(TransportConnection.java:843)
	at org.apache.activemq.broker.jmx.ManagedTransportConnection.processAddConnection(ManagedTransportConnection.java:77)
	at org.apache.activemq.command.ConnectionInfo.visit(ConnectionInfo.java:139)
	at org.apache.activemq.broker.TransportConnection.service(TransportConnection.java:330)
	at org.apache.activemq.broker.TransportConnection$1.onCommand(TransportConnection.java:194)
	at org.apache.activemq.transport.MutexTransport.onCommand(MutexTransport.java:50)
	at org.apache.activemq.transport.WireFormatNegotiator.onCommand(WireFormatNegotiator.java:125)
	at org.apache.activemq.transport.AbstractInactivityMonitor.onCommand(AbstractInactivityMonitor.java:301)
	at org.apache.activemq.transport.TransportSupport.doConsume(TransportSupport.java:83)
	at org.apache.activemq.transport.tcp.TcpTransport.doRun(TcpTransport.java:233)
	at org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:215)
	at java.lang.Thread.run(Thread.java:748)
ERROR | onException -> 消息服务器连接错误......
java.io.IOException: Force close due to SecurityException on connect
	at org.apache.activemq.ActiveMQConnection.forceCloseOnSecurityException(ActiveMQConnection.java:1372)
	at org.apache.activemq.ActiveMQConnection.syncSendPacket(ActiveMQConnection.java:1397)
	at org.apache.activemq.ActiveMQConnection.ensureConnectionInfoSent(ActiveMQConnection.java:1495)
	at org.apache.activemq.ActiveMQConnection.createSession(ActiveMQConnection.java:323)
	at org.apache.activemq.jms.pool.ConnectionPool.makeSession(ConnectionPool.java:107)
	at org.apache.activemq.jms.pool.ConnectionPool$1.makeObject(ConnectionPool.java:77)
	at org.apache.activemq.jms.pool.ConnectionPool$1.makeObject(ConnectionPool.java:73)
	at org.apache.commons.pool2.impl.GenericKeyedObjectPool.create(GenericKeyedObjectPool.java:1041)
	at org.apache.commons.pool2.impl.GenericKeyedObjectPool.borrowObject(GenericKeyedObjectPool.java:357)
	at org.apache.commons.pool2.impl.GenericKeyedObjectPool.borrowObject(GenericKeyedObjectPool.java:279)
	at org.apache.activemq.jms.pool.ConnectionPool.createSession(ConnectionPool.java:136)
	at org.apache.activemq.jms.pool.PooledConnection.createSession(PooledConnection.java:167)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.springframework.jms.connection.SingleConnectionFactory$SharedConnectionInvocationHandler.invoke(SingleConnectionFactory.java:620)
	at com.sun.proxy.$Proxy1.createSession(Unknown Source)
	at org.springframework.jms.support.JmsAccessor.createSession(JmsAccessor.java:192)
	at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:485)
	at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:580)
	at com.sts.testPro.MessageSender.send(MessageSender.java:54)
	at com.sts.testPro.MessageSender.integraMessage(MessageSender.java:43)
	at com.sts.testCustomer.MQProducerTest.main(MQProducerTest.java:24)
Caused by: java.lang.SecurityException: User name [sts] or password is invalid.
	at org.apache.activemq.security.SimpleAuthenticationBroker.authenticate(SimpleAuthenticationBroker.java:103)
	at org.apache.activemq.security.SimpleAuthenticationBroker.addConnection(SimpleAuthenticationBroker.java:71)
	at org.apache.activemq.broker.BrokerFilter.addConnection(BrokerFilter.java:99)
	at org.apache.activemq.broker.TransportConnection.processAddConnection(TransportConnection.java:843)
	at org.apache.activemq.broker.jmx.ManagedTransportConnection.processAddConnection(ManagedTransportConnection.java:77)
	at org.apache.activemq.command.ConnectionInfo.visit(ConnectionInfo.java:139)
	at org.apache.activemq.broker.TransportConnection.service(TransportConnection.java:330)
	at org.apache.activemq.broker.TransportConnection$1.onCommand(TransportConnection.java:194)
	at org.apache.activemq.transport.MutexTransport.onCommand(MutexTransport.java:50)
	at org.apache.activemq.transport.WireFormatNegotiator.onCommand(WireFormatNegotiator.java:125)
	at org.apache.activemq.transport.AbstractInactivityMonitor.onCommand(AbstractInactivityMonitor.java:301)
	at org.apache.activemq.transport.TransportSupport.doConsume(TransportSupport.java:83)
	at org.apache.activemq.transport.tcp.TcpTransport.doRun(TcpTransport.java:233)
	at org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:215)
	at java.lang.Thread.run(Thread.java:748)
 INFO | ===>System.exit
 INFO | Expiring connection ActiveMQConnection {id=ID:DESKTOP-HCAROEL-56035-1530758554572-1:1,clientId=ID:DESKTOP-HCAROEL-56035-1530758554572-0:1,started=false} on IOException: Force close due to SecurityException on connect

提示用户名或密码错误,用户密码拦截配置成功。

运行消费消息测试类:


并未找到消息,说明消息确实发送失败。

除了上面那种直接在activeMQ写死客户端的访问用户名密码外,还可通过配置文件来实现:

在activemq.xml中的<broker>中配置:

<plugins>
                <simpleAuthenticationPlugin>
                <users>
                         <authenticationUser username="${activemq.name}" password="${activemq.pass}" groups="musers"/>
                </users>
                </simpleAuthenticationPlugin>
        </plugins>

在activemq.xml中往上翻会看到有个文件的调用:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <value>file:${activemq.conf}/credentials.properties</value>
        </property>
    </bean>

这个credentials.properties中存放的就是关于上面配置的${activemq.name}以及${activemq.pass},使用vim进入credentials.properties:

## ---------------------------------------------------------------------------
## Licensed to the Apache Software Foundation (ASF) under one or more
## contributor license agreements.  See the NOTICE file distributed with
## this work for additional information regarding copyright ownership.
## The ASF licenses this file to You under the Apache License, Version 2.0
## (the "License"); you may not use this file except in compliance with
## the License.  You may obtain a copy of the License at
## 
## http://www.apache.org/licenses/LICENSE-2.0
## 
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
## ---------------------------------------------------------------------------

# Defines credentials that will be used by components (like web console) to access the broker

activemq.username=system
activemq.password=manager
guest.password=password

activemq.name=sts
activemq.pass=123456
~                         

需要注意的是上面两种不论使用那种方法,修改完配置文件后需要重启activemq服务才会生效!(多一嘴)


版权声明:本文为TS_10908原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/TS_10908/article/details/80922454

智能推荐

数据去重的各种方法汇总(三)

Pandas去重DataFrame 接上篇,这篇就剩最后的用Pandas对DataFrame里面的数据去重,这里也有两种方法,可以直接看官方文档(但是掌柜觉得其实就是一种方法,因为第一种只是显示哪些重复。。。): 使用duplicated方法,它会返回一个布尔向量,其长度为行数,表示行是否重复,但是并不会删除重复数据。来看实例: 然后会得到这样一个表格: 现在使用duplicated方法: 会得到...

Linux环境下RabbitMQ消息队列的安装和配置

一、什么是RabbitMQ? RabbitMQ就是一个在AMQP基础上实现的企业级消息系统,简单的说,就是一个消息队列系统。具体的介绍,可以网上去搜!目前只介绍RabbitMQ在Linux系统的安装。 二、RabbitMQ的安装 1、 RabbitMQ是基于Erlang开发,所以使用之前必须安装Erlang语言开发包。 wget http://www.erlang.org/download/otp...

train_test_split切分数据集工具

顾名思义,这是一个切分训练集与测试集的工具   如果我们不使用,而是手动进行划分,要么进行简单的操作——划去前80%为训练集,后20%为测试集,这样会带来很多的问题,因为这样做,我们切出来的会让训练集和测试集的分布很不一致,我们可以看一下简单粗暴方法切出来的分布图: 红色的训练集,蓝色是测试集(点击图片放大可以看得很清楚,直接看博客好像图片模糊)   然...

shell编程第一节 和shell

shell编程看的博客感觉写的挺好的:http://www.cnblogs.com/dongying/p/6262935.html 以及  https://www.cnblogs.com/clsn/p/8028337.html#auto_id_0 简单总结:shell编程就是对一堆Linux命令的逻辑化处理。 chmod +x hello_world.sh ./hello_world.s...

微信开发:js sdk 分享(java)

今天记录一下微信jssdk 的分享给朋友的功能,获取config接口注入。 1.需要绑定域名(注意:设置js安全域名的时候,需要设置微信ip白名单,ip白名单新出来的,非白名单内的ip无法获取access_token 更无法获取jsapi) 在设置js 安全域名在 设置–>公众号设置–>功能设置里边 appid appSercret 在开发–>...

猜你喜欢

js--HTML美术馆

前言 因为之前库房合作的时候交给我一个任务,就是在点击某一项物品的时候显示出几张相印的小图片,然后点击小图片之后显示出一张大图片,因为当时还没有接触JavaScript,所以这方面的知识不是很了解,一直拖着,大概有两天吧,是在是解决不了,于是将这个任务交给了老付和建华,今天在学习JavaScript的时候突然之后就看到了有这么一项功能,于是就有感而发。 内容 首先向大家展示代码。 这部分是HTML...

Jenkins持续集成环境部署(入门篇)

为什么要持续集成 持续集成是一种软件开发实践,即团队开发成员经常集成它们的工作,通过每个成员每天至少集成一次,也就意味着每天可能会发生多次集成。每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽早地发现集成错误。 价值: 1、减少风险 一天中进行多次的集成,并做了相应的测试,有利于检查缺陷,了解软件的健康状况,减少假定。 2、减少重复过程 节省时间、费用和工作量,通过自动化的持...

linux 下rabbitmq的安装以及设置远程用户访问

安装过程中会有提示,一路输入“y”即可。 完成后安装RabbitMQ: 3.自己建个文件夹 进行下载安装也可  直接执行也可 先下载rpm: 完成后启动服务: 可以查看服务状态: 这里可以看到log文件的位置,转到文件位置,打开文件: 这里显示的是没有找到配置文件,我们可以自己创建这个文件 编辑内容如下: 这里的意思是开放使用,rabbitmq默认创建的用户gue...

Java工程师成长修炼手册:01--Java基础特性和字符串

一.三大特性 1.封装 封装,把对象的属性封装起来(使用private修饰符),不被外部程序直接随意调用或修改成员变量。只能通过对象使用public修饰符的set 和 get 方法,来设置和获取成员变量的值。也可以把只在本类内部使用的方法使用 private。另外,还可以封装,隐藏一些方法,需要用的时候,就调用这些方法。这些就是封装。 封装的优点 良好的封装能够减少耦合,可以独立地开发、优化和修改...

android手机传感器总结

  传感器的分类 动作传感器 加速度传感器 重力传感器 陀螺仪 位置传感器 方向传感器 磁力传感器 环境传感器 温度传感器 压力传感器 亮度传感器 传感器的使用 1.获取SensorManager对象 2.执行SensorManager对象的getdefaultSensor()方法获取Sensor对象 3.获取Sensor对象的各种属性 获取安卓手机中所有传感器  输出结果 传...