ActiveMQ中判断用户是否有权限发送消息

上一篇介绍了用户连接时的认证,在我的设计方案中,消息发送者统一调用server,server会与ActiveMQ建立长连接,这样便于对消息进行维护。这里就需要对用户发送权限进行控制,避免客户端直接通过长连接发送消息

关于权限控制可以自己维护,这里给出我的方案:
流程主要是在上一篇的用户登陆后,查询用户的权限,存储到Redis中,修改ActiveMQ,使其在发送前通过查询Redis判断用户是否有发送权限

1.MySQL

在activemq数据库中新建表tb_topic_power

-- ----------------------------
-- Table structure for tb_topic_power
-- ----------------------------
DROP TABLE IF EXISTS `tb_topic_power`;
CREATE TABLE `tb_topic_power` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `userid` int(11) DEFAULT NULL,
  `username` varchar(255) DEFAULT NULL,
  `topic` varchar(255) DEFAULT NULL,
  `send` bit(1) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;

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

2.修改源码

修改org.apache.activemq.broker.region.Topic
在363行,send方法中添加

if (producerExchange != null && producerExchange.getConnectionContext() != null && producerExchange.getConnectionContext().getClientId() != null && message != null) {
    String clientId = producerExchange.getConnectionContext().getUserName();
    String topic = message.getDestination().getDestinationPaths()[message.getDestination().getDestinationPaths().length - 1];

    {
        Object topics = RedisPlugin.getListByKey("TopicOf" + clientId);
        boolean b = true;
        if (topics == null) {
            b = false;
        } else {
            List<String> topicList = (List<String>) topics;
            if (!topicList.contains(topic)) {
                b = false;
            }
        }
        if (!b) {
            LOG.error("{}无权限发送至{}", clientId, topic);
            return;
        }
    }
}

源码方面即修改完成

3.server中插入数据

List<String> topics = topicPowerService.getTopics(loginParam.getUserName());
if (topics != null && !topics.isEmpty()) {
    stringRedisTemplate.opsForList().rightPushAll("TopicOf" + loginParam.getUserName(), topics);
}

添加新评论