ActiveMQ的安全配置(九)

安全权限有三种
read    You can browse and consume from the destination

write   You can send messages to the destination

admin   You can lazily create the destination if it does not yet exist. 
This allows you fine grained control over which new destinations can 
be dynamically created in what part of the queue/topic hierarchy

admin是我们在写我们自己客户端程序访问activeMQ时候,如果队列/主题不存在.则admin就可指定该”角色”是否有权限建立这个队列(没错,不像weblogic的jms那样,队列/主题没有从后台建立,则客户端无法访问

第一种方式:Simple Authentication(简单的身份验证)

在conf/activemq.xml文件中加入以下内容即可(如配置了systemUsage,应该放到systemUsage前,否则出bug):

<plugins>    
<!-- Configure authentication; Username, passwords and groups -->    
    <simpleAuthenticationPlugin>    
        <users>    
            <authenticationUser username="system" password="${activemq.password}"   groups="users,admins"/>    
            <authenticationUser username="user" password="${guest.password}"  groups="users"/>    
            <authenticationUser username="guest" password="${guest.password}" groups="guests"/>    
        </users>    
    </simpleAuthenticationPlugin>    
</plugins>

引用在conf/credential.properties中配置

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

创建1个简单的生产者消费者

package com.tgb.activemq;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
/**
 * 消息的消费者(接受者)
 * @author liang
 *
 */
public class JMSConsumer {

    private static final String USERNAME = "system";
    private static final String PASSWORD = "manager";
    private static final String BROKEURL = ActiveMQConnection.DEFAULT_BROKER_URL;//默认连接地址,一般是localhost:61616,也是在activemq.xml中配置

    public static void main(String[] args) {
        ConnectionFactory connectionFactory;//连接工厂
        Connection connection = null;//连接

        Session session;//会话 接受或者发送消息的线程
        Destination destination;//消息的目的地

        MessageConsumer messageConsumer;//消息的消费者

        //实例化连接工厂
        connectionFactory = new ActiveMQConnectionFactory(JMSConsumer.USERNAME, JMSConsumer.PASSWORD, JMSConsumer.BROKEURL);

        try {
            //通过连接工厂获取连接
            connection = connectionFactory.createConnection();
            //启动连接
            connection.start();
            //创建session
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            //创建一个连接HelloWorld的消息队列
            destination = session.createQueue("HelloWorld");
            //创建消息消费者 
            messageConsumer = session.createConsumer(destination);

            while (true) {
                TextMessage textMessage = (TextMessage) messageConsumer.receive(100000);
                if(textMessage != null){
                    System.out.println("收到的消息:" + textMessage.getText());
                }else {
                    break;
                }
            }


        } catch (JMSException e) {
            e.printStackTrace();
        }

    }
}
package com.tgb.activemq;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
/**
 * 消息的生产者(发送者) 
 * @author liang
 *
 */
public class JMSProducer {

    //默认连接用户名
    private static final String USERNAME = "system";
    //默认连接密码
    private static final String PASSWORD = "manager";
    //默认连接地址
    private static final String BROKEURL = ActiveMQConnection.DEFAULT_BROKER_URL;
    //发送的消息数量
    private static final int SENDNUM = 10;

    public static void main(String[] args) {
        //连接工厂
        ConnectionFactory connectionFactory;
        //连接
        Connection connection = null;
        //会话 接受或者发送消息的线程
        Session session;
        //消息的目的地
        Destination destination;
        //消息生产者
        MessageProducer messageProducer;
        //实例化连接工厂
        connectionFactory = new ActiveMQConnectionFactory(JMSProducer.USERNAME, JMSProducer.PASSWORD, JMSProducer.BROKEURL);

        try {
            //通过连接工厂获取连接
            connection = connectionFactory.createConnection();
            //启动连接
            connection.start();
            //创建session
            session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
            //创建一个名称为HelloWorld的消息队列
            destination = session.createQueue("HelloWorld");
            //创建消息生产者
            messageProducer = session.createProducer(destination);
            //发送消息
            sendMessage(session, messageProducer);

            session.commit();

        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            if(connection != null){
                try {
                    connection.close();
                } catch (JMSException e) {
                    e.printStackTrace();
                }
            }
        }

    }
    /**
     * 发送消息
     * @param session
     * @param messageProducer  消息生产者
     * @throws Exception
     */
    public static void sendMessage(Session session,MessageProducer messageProducer) throws Exception{
        for (int i = 0; i < JMSProducer.SENDNUM; i++) {
            //创建一条文本消息 
            TextMessage message = session.createTextMessage("ActiveMQ 发送消息" +i);
            System.out.println("发送消息:Activemq 发送消息" + i);
            //通过消息生产者发出消息 
            messageProducer.send(message);
        }

    }
}
结果
 INFO | Successfully connected to tcp://localhost:61616
收到的消息:ActiveMQ 发送消息0
收到的消息:ActiveMQ 发送消息1
收到的消息:ActiveMQ 发送消息2
收到的消息:ActiveMQ 发送消息3
收到的消息:ActiveMQ 发送消息4
收到的消息:ActiveMQ 发送消息5
收到的消息:ActiveMQ 发送消息6
收到的消息:ActiveMQ 发送消息7
如果用户名或密码不正确
INFO | Successfully connected to tcp://localhost:61616
javax.jms.JMSSecurityException: User name [system] or password is invalid.
    at 
。。。。。。。。。。

第二种方式:JAAS authentication(JAAS身份验证)

- 在conf/activemq.xml文件中加上
<plugins>    
    <!--use JAAS to authenticate using the login.config file on the classpath to configure JAAS -->    
    <jaasAuthenticationPlugin configuration="activemq-domain" />    
    <!--  lets configure a destination based authorization mechanism -->    
    <authorizationPlugin>    
        <map>    
            <authorizationMap>    
                <authorizationEntries>    

                <!--  USERS.>表示以USERS.开头的主题;>表示所有主题,read表示读的权限,write表示写的权限,admin表示角色组 -->    
                    <authorizationEntry queue=">" read="admins" write="admins" admin="admins" />    
                    <authorizationEntry topic=">" read="admins" write="admins" admin="admins" />    
                    <authorizationEntry queue="ActiveMQ.Advisory.>" read="admins" write="admins" admin="admins" />    
                    <authorizationEntry topic="ActiveMQ.Advisory.>" read="admins" write="admins" admin="admins" />    
                </authorizationEntries>    
            </authorizationMap>    
        </map>    
    </authorizationPlugin>    
</plugins> 
- 在conf目录下的login.config,groups.properties,users.properties

login.config

activemq {
    org.apache.activemq.jaas.PropertiesLoginModule required
        org.apache.activemq.jaas.properties.user="users.properties"
        org.apache.activemq.jaas.properties.group="groups.properties";
};

groups.properties

#group=userName  
admins=system  

users.properties

#userName=password  
system=manager
使用方式与简单身份验证相似。

但是这只是broker-level的验证和授权,即只有在客户端对broker发起连接时才会发挥做用,但是有的时候我们授权特定的message才能到达destination,这个时候我们就需要Message-level身份验证

下面这个例子实现了消费者和broker在同一个主机上message才能到达destination的例子

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());
        String remoteAddress = context.getConnection().getRemoteAddress();
          if (remoteAddress.startsWith("/127.0.0.1")) {
          LOG.info("Permission to consume granted");
          return true;
        } else {
          LOG.info("Permission to consume denied");
          return false;
    }}
}
很简单,只需要实现isAllowedToConsume方法,然后把AuthorizationPolicy用类似spring的方式写入到配置文件中
<messageAuthorizationPolicy>
  <bean
    class="org.apache.activemq.book.ch6.AuthorizationPolicy"
    xmlns="http://www.springframework.org/schema/beans" />
</messageAuthorizationPolicy>

注意,要想注入成功必须用mvn clean install把项目打包,然后在class中写上正确的路径,不然很容易启动失败。activemq有时候很坑爹,写着activemq is running at pid:XXXX实际上运行失败。。

查看activemq是否成功启动的方法:
1####.查看data/log文件,从日志查看启动结果最稳妥
2.在终端查看端口 16161是否被占用
3.直接在网页访问 http://localhost:8161/
推荐第一种方法

上面介绍了两种安全插件还有配置message-level的像过滤器一样的bean,下面一节将介绍自定义插件和ssl方式的安全配置。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值