一.下载插件代码所需jar包,我是在maven中引入,然后再copy到activemq的指定目录:
org.apache.activemq
activemq-broker
5.15.8
org.apache.activemq
activemq-jaas
5.15.8
mysql
mysql-connector-java
5.1.47
org.springframework
spring-jdbc
4.3.18.RELEASE
将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,
file:${activemq.conf}/credentials.properties
file:${activemq.conf}/db.properties
然后在
其中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.class));
System.out.println("===========mysql user = " + user);
return user;
} catch (EmptyResultDataAccessException e) {
return null;
}
}
// public static Map map = null;
//
// public void getAllUser() {
// String sql = "select * from db_user";
// List list = jdbcTemplate.query(sql, new BeanPropertyRowMapper(User.class));
// map = new LinkedHashMap();
// 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 getPrincipals() {
Set groups = new HashSet();
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,如果不是将连接失败。(在插件代码中可自定义自己的验证逻辑)