activemq自定义安全验证插件,集成mysql

一.下载插件代码所需jar包,我是在maven中引入,然后再copy到activemq的指定目录:

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.apache.activemq/activemq-broker -->
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-broker</artifactId>
            <version>5.15.8</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.activemq/activemq-jaas -->
        <dependency>
            <groupId>org.apache.activemq</groupId>
            <artifactId>activemq-jaas</artifactId>
            <version>5.15.8</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>4.3.18.RELEASE</version>
        </dependency>
    </dependencies>

将mysql-connector-java-5.1.47.jar包copy到C:\apache-activemq-5.15.8\lib目录下,将spring-jdbc-4.3.18.RELEASE.jar包copy到C:\apache-activemq-5.15.8\lib\optional目录下。注意:1.spring-jdbc版本要和C:\apache-activemq-5.15.8\lib\optional目录下的spring版本相同。2.mysql版本建议5.1.47,因为6.0+版本的连接驱动包有所改变,不是com.mysql.jdbc.Driver。

二.编辑C:\apache-activemq-5.15.8\conf下的activemq.xml,<bean>节点配置改为:

<!-- Allows us to use system properties as variables in this configuration file -->
    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
			<list>
                <value>file:${activemq.conf}/credentials.properties</value>
                <value>file:${activemq.conf}/db.properties</value>
            </list>      
        </property>		
    </bean>

   <!-- Allows accessing the server log -->
    <bean id="logQuery" class="io.fabric8.insight.log.log4j.Log4jLogQuery"
          lazy-init="false" scope="singleton"
          init-method="start" destroy-method="stop">
    </bean>

	<!-- mysql数据库数据源-->  
    <bean id="mySqlDataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">  
            <property name="driverClassName" value="${jdbc.driverClassName}" />  
            <property name="url" value="${jdbc.url}" />  
            <property name="username" value="${jdbc.username}" />  
            <property name="password" value="${jdbc.password}" />  
    </bean>  
    <!-- 增加jdbcTemplate-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" abstract="false"
        lazy-init="false" autowire="default" >
        <property name="dataSource">
            <ref bean="mySqlDataSource" />
        </property>
    </bean>

然后在<broker>节点中的最后添加配置:

		<plugins>
            <bean xmlns="http://www.springframework.org/schema/beans" id="myPlugin" class="my.plugin.MyAuthenticationPlugin">						
                <constructor-arg>
                    <ref bean="jdbcTemplate"/>
                </constructor-arg>
            </bean>
        </plugins>

		
    </broker>

其中db.properties是自己新建的配置文件,内容如下:

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/yzh?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false
jdbc.username=root
jdbc.password=123456

创建好后copy到C:\apache-activemq-5.15.8\conf目录下。

这样服务端的配置就完成了,下面是自定义插件的代码。

三.认证插件的编码:

package my.plugin;

import org.apache.activemq.broker.Broker;
import org.apache.activemq.broker.BrokerPlugin;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.List;

/**
 * description:
 * author: 
 * date: 2018-12-07 09:54
 **/
public class MyAuthenticationPlugin implements BrokerPlugin {

    JdbcTemplate jdbcTemplate;//注入JdbcTemplate

    public MyAuthenticationPlugin(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public Broker installPlugin(Broker broker) throws Exception {
        return new MyAuthenticationBroker(broker,jdbcTemplate);
    }

}

其中MyAuthenticationBroker的编码:

package my.plugin;

import org.apache.activemq.broker.Broker;
import org.apache.activemq.broker.ConnectionContext;
import org.apache.activemq.command.ConnectionInfo;
import org.apache.activemq.security.AbstractAuthenticationBroker;
import org.apache.activemq.security.SecurityContext;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.apache.activemq.jaas.GroupPrincipal;

import java.security.Principal;
import java.security.cert.X509Certificate;
import java.util.*;

/**
 * description:  broker的实现,附带方法过滤
 * author: yangzihe
 * date: 2018-12-07 09:50
 **/
public class MyAuthenticationBroker extends AbstractAuthenticationBroker {

    private JdbcTemplate jdbcTemplate;

    public MyAuthenticationBroker(Broker next, JdbcTemplate jdbcTemplate) {
        super(next);
        this.jdbcTemplate = jdbcTemplate;
    }

    /**
     * 创建连接的时候拦截
     *
     * @param context
     * @param info
     * @throws Exception
     */
    @Override
    public void addConnection(ConnectionContext context, ConnectionInfo info) throws Exception {
        SecurityContext securityContext = context.getSecurityContext();
        if (securityContext == null) {
            System.out.println("=======securityContext=" + securityContext);
            System.out.println("=======username=" + info.getUserName() + ",password=" + info.getPassword());
            securityContext = authenticate(info.getUserName(), info.getPassword(), null);
            System.out.println("=======auth end,securityContext=" + securityContext);
            context.setSecurityContext(securityContext);
            securityContexts.add(securityContext);
        }

        try {
            super.addConnection(context, info);
        } catch (Exception e) {
            securityContexts.remove(securityContext);
            context.setSecurityContext(null);
            throw e;
        }
    }

    /**
     * 查询数据库获取user
     *
     * @param username
     * @return
     */
    private User getUser(String username) {
        String sql = "select * from db_user where user_name=? limit 1";
        try {
            User user = jdbcTemplate.queryForObject(sql, new Object[]{username}, new BeanPropertyRowMapper<User>(User.class));
            System.out.println("===========mysql user = " + user);
            return user;
        } catch (EmptyResultDataAccessException e) {
            return null;
        }
    }

//    public static Map<String, User> map = null;
//
//    public void getAllUser() {
//        String sql = "select * from db_user";
//        List<User> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<User>(User.class));
//        map = new LinkedHashMap<String, User>();
//        for (User user : list) {
//            System.err.println(user);//debug
//            map.put(user.getUser_name(), user);
//        }
//    }

    /**
     * 认证
     *
     * @param username
     * @param password
     * @param peerCertificates
     * @return
     * @throws SecurityException
     */
    public SecurityContext authenticate(String username, String password, X509Certificate[] peerCertificates) throws SecurityException {
        SecurityContext securityContext = null;
        User user = getUser(username);
        //验证用户信息
        if (user != null && user.getPass_word().equals(password)) {
            securityContext = new SecurityContext(username) {
                @Override
                public Set<Principal> getPrincipals() {
                    Set<Principal> groups = new HashSet<Principal>();
                    groups.add(new GroupPrincipal("users"));//默认加入了users的组
                    return groups;
                }
            };
        } else {
            throw new SecurityException("my auth plugin authenticate failed");
        }
        return securityContext;
    }
}

其中User是数据库表db_user的映射实体类:

package my.plugin;

/**
 * description:
 * author: yangzihe
 * date: 2018-12-07 16:25
 **/
public class User {

    private String user_name;

    private String pass_word;

    @Override
    public String toString() {
        return "User{" +
                "user_name='" + user_name + '\'' +
                ", pass_word='" + pass_word + '\'' +
                '}';
    }

    public User() {
    }

    public User(String user_name, String pass_word) {
        this.user_name = user_name;
        this.pass_word = pass_word;
    }

    public String getUser_name() {
        return user_name;
    }

    public void setUser_name(String user_name) {
        this.user_name = user_name;
    }

    public String getPass_word() {
        return pass_word;
    }

    public void setPass_word(String pass_word) {
        this.pass_word = pass_word;
    }
}

最后,数据库表的sql:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for db_user
-- ----------------------------
DROP TABLE IF EXISTS `db_user`;
CREATE TABLE `db_user`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL,
  `pass_word` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of db_user
-- ----------------------------
INSERT INTO `db_user` VALUES (1, 'admin', 'admin');

SET FOREIGN_KEY_CHECKS = 1;

四.activemq broker服务端配置修改和插件代码的编写都已完成,最后就是启动activemq,cmd进入C:\apache-activemq-5.15.8\bin,执行activemq start,或者直接找对应的64位的activemq.bat执行文件双击。服务启动后,客户端再次连接的时候,username=admin password=admin,如果不是将连接失败。(在插件代码中可自定义自己的验证逻辑)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
要在IntelliJ IDEA中集成ActiveMQ,可以按照以下步骤进行操作: 1. 首先,确保已经安装了Apache ActiveMQ,并启动了ActiveMQ服务。 2. 打开IntelliJ IDEA,创建一个新的Java项目。 3. 在项目的依赖项中添加ActiveMQ的JAR文件。可以通过手动下载JAR文件并添加到项目路径中,或者使用构建工具(如Maven或Gradle)来管理依赖项。以下是使用Maven的示例: 在项目的pom.xml文件中,添加以下依赖项: ```xml <dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-all</artifactId> <version>5.16.3</version> </dependency> ``` 4. 创建一个Java类,用于发送和接收消息。以下是一个简单的示例代码: ```java import org.apache.activemq.ActiveMQConnectionFactory; import javax.jms.*; public class ActiveMQIntegration { public static void main(String[] args) { try { // 创建连接工厂 ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616"); // 创建连接 Connection connection = connectionFactory.createConnection(); connection.start(); // 创建会话 Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); // 创建队列 Destination destination = session.createQueue("myQueue"); // 创建生产者 MessageProducer producer = session.createProducer(destination); // 创建消息 TextMessage message = session.createTextMessage("Hello, ActiveMQ!"); // 发送消息 producer.send(message); System.out.println("Message sent: " + message.getText()); // 创建消费者 MessageConsumer consumer = session.createConsumer(destination); // 接收消息 Message receivedMessage = consumer.receive(); if (receivedMessage instanceof TextMessage) { TextMessage textMessage = (TextMessage) receivedMessage; System.out.println("Message received: " + textMessage.getText()); } // 关闭资源 session.close();

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值