ActiveMQ 基于JAAS的安全机制

ActiveMQ版本 :5.9

 

ActiveMQ支持可插拔的安全机制,用以在不同的provider之间切换。

 

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文件的例子:

 

[html]  view plain  copy
 
  1. activemq {  
  2.     org.apache.activemq.jaas.PropertiesLoginModule required  
  3.         org.apache.activemq.jaas.properties.user="users.properties"  
  4.         org.apache.activemq.jaas.properties.group="groups.properties";  
  5. };  

 

 

users.properties

 

[plain]  view plain  copy
 
  1. admin=admin  
  2. user=sky  
  3. guest=sky  

 

 

group.properties

[plain]  view plain  copy
 
  1. admins=admin  
  2. users=user  
  3. guests=guest  

 

这个login.config文件中设置了两个属性:

 

  • org.apache.activemq.jaas.properties.user
  • org.apache.activemq.jaas.properties.group

 

分别用来指向user.properties和group.properties文件。需要注意的是,PropertiesLoginModule使用本地文件的查找方式,而且查找时采用的base directory是login.config文件所在的目录。因此这个login.config说明user.properties和group.properties文件存放在跟login.config文件相同的目录里。(activemq 5.9 默认提供了以上的配置文件)以下是activemq.xml配置的一个例子:

 

[html]  view plain  copy
 
  1. <!-- sky -->  
  2. <plugins>  <!--  Lets configure a destination based authorization mechanism     
  3.             采用JAAS的管理机制来配置各种角色的权限    
  4.       -->    
  5.         <!--  use JAAS to authenticate using the login.config file on the classpath to configure JAAS . -->  
  6.        <jaasAuthenticationPlugin configuration="activemq" />  
  7.       <authorizationPlugin>    
  8.         <map>    
  9.           <authorizationMap>    
  10.             <authorizationEntries>    
  11.               <authorizationEntry queue=">" read="admins" write="admins" admin="admins" />    
  12.               <authorizationEntry queue="USERS.>" read="users" write="admins" admin="admins" />    
  13.               <authorizationEntry queue="GUEST.>" read="guests" write="guests,users" admin="guests,users" />    
  14.                   
  15.               <authorizationEntry queue="TEST.*" read="guests" write="guests" />    
  16.                   
  17.               <authorizationEntry topic=">" read="admins" write="admins" admin="admins" />    
  18.               <!-- 表示通配符,例如USERS.>表示以USERS.开头的主题,>表示所有主题,read表示读的权限,write表示写的权限,admin表示角色组   
  19.                -->    
  20.               <authorizationEntry topic="USERS.>" read="users" write="users" admin="users" />    
  21.               <authorizationEntry topic="GUEST.>" read="guests" write="guests,users" admin="guests,users" />    
  22.                   
  23.               <authorizationEntry topic="ActiveMQ.Advisory.>" read="guests,users" write="guests,users" admin="guests,users"/>    
  24.             </authorizationEntries>    
  25.             <!-- let's assign roles to temporary destinations. comment this entry if we don't want any roles assigned to temp destinations  -->    
  26.              <tempDestinationAuthorizationEntry>    
  27.               <tempDestinationAuthorizationEntry    
  28.                     read="tempDestinationAdmins" write="tempDestinationAdmins"    
  29.                     admin="tempDestinationAdmins" />    
  30.              </tempDestinationAuthorizationEntry>    
  31.         </authorizationMap>    
  32.      </map>    
  33.             
  34.       </authorizationPlugin>    
  35.     </plugins>    

 



 

基于以上的配置,在JAAS的LoginContext中会使用login.config中activemq中配置的PropertiesLoginModule来进行登陆。


针对不同的queue或者topic设置了可以进行操作的组。里面主要涉及三种操作:read, write, admin

  • read:可以从queue或者topic里面接收消息
  • write:可以向queue或者topic发送消息
  • admin:可以创建queue或者topic(可能还有别的功能)

这些文件配制好时候,ActiveMQ就具有了基本的安全机制,当Client(生产者和消费者)连接ActiveMQ需要使用账号,还可以限制具体的Client对于某个/某些Topic/Queue的操作权限.

 

例如: 

 

  1. <authorizationEntry queue=">" read="admins" write="admins" admin="admins" />。   ">"是通配符的意思,也就是admins组的角色,拥有read、write、admin的权限。
  2.  <authorizationEntry queue="USERS.>" read="users" write="admins" admin="admins" />  。queue名称以"USERS."开头的,users组只拥有读权限,即只能收消息,不能发消息。

 

 

简单认证插件

SimpleAuthentication Plugin适用于简单的认证需求,或者用于建立测试环境。它允许在XML配置文件中指定用户、用户组和密码等信息。(该文件位于:%ACTIVEMQ_HOME%\conf\activemq.xml, D:\sun_java\activemq\apache-activemq-5.9.0\conf

 

 

[html]  view plain  copy
 
  1. <plugins>    
  2.   ...    
  3.     <simpleAuthenticationPlugin>    
  4.     <users>    
  5.         <authenticationUser username="system" password="manager" groups="users,admins"/>    
  6.         <authenticationUser username="user" password="password" groups="users"/>    
  7.         <authenticationUser username="guest" password="password" groups="guests"/>    
  8.     </users>    
  9.     </simpleAuthenticationPlugin>    
  10. </plugins>    



 

下面是基于JASS认证插件的配置,首先启动activemq服务:

jsm.xml

 

[html]  view plain  copy
 
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  3.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">  
  4.   
  5.     <description>JMS高级应用配置(NON_PERSISTENT,DURIABLE,SELECTOR)</description>  
  6.   
  7.     <!-- ActiveMQ 连接工厂 -->  
  8.     <bean id="advancedConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">  
  9.         <property name="brokerURL" value="${jms.broker_url}" />  
  10.         <property name="userName" value="${jms.userName}" />  
  11.         <property name="password" value="${jms.password}" />  
  12.         <!-- 对PERSISTENT的消息进行异步发送(NON_PERSISTENT消息默认异步发送) -->  
  13.         <!-- <property name="useAsyncSend" value="true" /> -->  
  14.     </bean>  
  15.   
  16.     <!-- 持久化主题订阅者ActiveMQ 连接工厂 -->  
  17.     <bean id="advancedTopicConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">  
  18.         <property name="brokerURL" value="${jms.broker_url}" />  
  19.         <!-- Durable订阅者必须设置ClientId -->  
  20.         <property name="clientID" value="${jms.client_id}" />  
  21.         <property name="userName" value="${jms.userName}" />  
  22.         <property name="password" value="${jms.password}" />  
  23.     </bean>  
  24.   
  25.     <!-- Spring Caching 连接工厂 -->  
  26.     <bean id="advancedCachingConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">  
  27.         <property name="targetConnectionFactory" ref="advancedConnectionFactory" />  
  28.         <property name="sessionCacheSize" value="10" />  
  29.     </bean>  
  30.   
  31.     <!-- Queue定义 -->  
  32.     <bean id="advancedNotifyQueue" class="org.apache.activemq.command.ActiveMQQueue">  
  33.         <constructor-arg value="USERS.advanced.queue" />  
  34.     </bean>  
  35.   
  36.     <!-- Topic定义 -->  
  37.     <bean id="advancedNotifyTopic" class="org.apache.activemq.command.ActiveMQTopic">  
  38.         <constructor-arg value="USERS.advanced.topic" />  
  39.     </bean>  
  40.   
  41.     <!-- Spring JMS Template -->  
  42.     <bean id="advancedJmsTemplate" class="org.springframework.jms.core.JmsTemplate">  
  43.         <property name="connectionFactory" ref="advancedCachingConnectionFactory" />  
  44.         <!-- 使 deliveryMode, priority, timeToLive设置生效-->  
  45.         <property name="explicitQosEnabled" value="true" />  
  46.         <!-- 设置NON_PERSISTENT模式, 默认为PERSISTENT -->  
  47.         <property name="deliveryPersistent" value="false" />  
  48.         <!-- 设置优先级, 默认为4 -->  
  49.         <property name="priority" value="9" />  
  50.     </bean>  
  51.   
  52.     <!-- 使用Spring JmsTemplate的消息生产者 -->  
  53.     <bean id="advancedNotifyMessageProducer" class="com.goldpalm.sgyl.api.jms.AdvancedNotifyMessageProducer">  
  54.         <property name="jmsTemplate" ref="advancedJmsTemplate" />  
  55.         <property name="notifyQueue" ref="advancedNotifyQueue" />  
  56.         <property name="notifyTopic" ref="advancedNotifyTopic" />  
  57.     </bean>  
  58.   
  59.     <!-- 异步接收Queue消息Container -->  
  60.     <bean id="advancedQueueContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">  
  61.         <property name="connectionFactory" ref="advancedConnectionFactory" />  
  62.         <property name="destination" ref="advancedNotifyQueue" />  
  63.         <property name="messageListener" ref="advancedNotifyMessageListener" />  
  64.         <!-- 初始5个Consumer, 可动态扩展到10 -->  
  65.         <property name="concurrentConsumers" value="5" />  
  66.         <property name="maxConcurrentConsumers" value="10" />  
  67.         <!-- 设置消息确认模式为Client -->  
  68.         <property name="sessionAcknowledgeModeName" value="CLIENT_ACKNOWLEDGE" />  
  69.     </bean>  
  70.   
  71.     <!-- 异步接收Topic消息Container -->  
  72.     <bean id="advancedTopicContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">  
  73.         <property name="connectionFactory" ref="advancedTopicConnectionFactory" />  
  74.         <property name="destination" ref="advancedNotifyTopic" />  
  75.         <property name="messageListener" ref="advancedNotifyMessageListener" />  
  76.         <!-- JMS Selector消息过滤器 -->  
  77.         <property name="messageSelector" value="objectType='user'" />  
  78.         <!-- 持久化订阅者 -->  
  79.         <property name="subscriptionDurable" value="true" />  
  80.     </bean>  
  81.   
  82.     <!-- 异步接收消息处理类 -->  
  83.     <bean id="advancedNotifyMessageListener" class="com.goldpalm.sgyl.api.jms.AdvancedNotifyMessageListener" />  
  84. </beans>  



 

jsm.properties

 

[plain]  view plain  copy
 
  1. #activemq settings  
  2. #vm broker  
  3. #jms.broker_url=vm://showcase?broker.persistent=false&broker.useJmx=false&broker.schedulerSupport=false  
  4. #localhost broker  
  5. jms.broker_url=tcp://localhost:61616  
  6. #network of brokers  
  7. #jms.broker_url=failover://(tcp://mqremote1:61616,tcp://mqremote2:61616)?randomize=false&initialReconnectDelay=100&timeout=5000  
  8.   
  9. jms.client_id=durableTopicListenerDemo  
  10.   
  11. #jmx settings  
  12. jmx.rmi_port=2099  
  13.   
  14. #demo settings  
  15. server.node_name=default  
  16. server.addr=localhost  
  17. jms.userName=user  
  18. jms.password=sky  


当我们不使用用户名密码连接时,console控制台会打印:WARN [DefaultMessageListenerContainer.java:888] - Could not refresh JMS Connection for destination 'queue://q.notify' - retrying in 5000 ms. Cause: User name [null] or password is invalid.

 

当使用用户名为user,密码为sky的账户连接时,如果我们向topic中发送消息,就会提示报错:org.springframework.jms.JmsSecurityException: User user is not authorized to write to: queue://USERS.advanced.queue; nested exception is javax.jms.JMSSecurityException: User user is not authorized to write to: queue://USERS.advanced.queue

猜你喜欢

转载自2379692ss.iteye.com/blog/2386769