能否在ActiveMQ(Classic/Artemis)配置仅订阅的acceptor端口?
Apache ActiveMQ Classic 实现方案
- 定义专用外部Acceptor:在
activemq.xml的transportConnectors节点下,新增一个专供外部WebSocket客户端连接的STOMP acceptor,示例配置:
<transportConnectors> <transportConnector name="stomp-ws-external" uri="stomp+ws://0.0.0.0:61614?maximumConnections=1000&wireFormat.maxFrameSize=10485760"/> </transportConnector> </transportConnectors>
- 通过授权插件锁死发布权限:在broker的
plugins节点下配置AuthorizationPlugin,给外部用户组设置仅订阅指定主题的权限,完全禁止发布操作:
<plugins> <authorizationPlugin> <map> <authorizationMap> <authorizationEntries> <!-- 全局规则:只有内部用户能发布、管理所有地址 --> <authorizationEntry queue=">" read="internal-users" write="internal-users" admin="internal-users"/> <authorizationEntry topic=">" read="internal-users" write="internal-users" admin="internal-users"/> <!-- 开放指定主题的订阅权限给外部用户 --> <authorizationEntry topic="external/notify/*" read="external-users" write="internal-users" admin="internal-users"/> </authorizationEntries> <!-- 临时队列/主题也只开放给内部用户 --> <tempDestinationAuthorizationEntry> <tempDestinationAuthorizationEntry read="internal-users" write="internal-users" admin="internal-users"/> </tempDestinationAuthorizationEntry> </authorizationMap> </map> </authorizationPlugin> </plugins>
这里external-users是外部WebSocket客户端使用的用户组,external/notify/*是允许订阅的主题前缀。外部用户完全没有write权限,自然无法发布任何消息。
- 确保非永久订阅:STOMP客户端默认就是非持久订阅,只需要求外部客户端不要在订阅时携带
persistent:true参数即可;如果要强制拦截,可以自定义插件过滤持久化订阅请求。
Apache ActiveMQ Artemis 实现方案
- 配置外部专用Acceptor:在
broker.xml的acceptors节点下新增STOMP WebSocket acceptor,示例:
<acceptors> <acceptor name="stomp-ws-external">stomp+ws://0.0.0.0:61614?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=STOMP</acceptor> </acceptors>
- 通过安全设置限制权限:利用Artemis的地址级安全控制,直接锁死外部用户的发布权限,仅开放指定主题的订阅权:
<security-settings> <!-- 全局规则:只有内部用户拥有发布、创建队列/地址等权限 --> <security-setting match="#"> <permission type="createNonDurableQueue" roles="internal-users"/> <permission type="createDurableQueue" roles="internal-users"/> <permission type="deleteNonDurableQueue" roles="internal-users"/> <permission type="deleteDurableQueue" roles="internal-users"/> <permission type="createAddress" roles="internal-users"/> <permission type="deleteAddress" roles="internal-users"/> <permission type="send" roles="internal-users"/> <!-- 外部用户无发送权限 --> <permission type="consume" roles="internal-users,external-users"/> <permission type="browse" roles="internal-users"/> <permission type="manage" roles="internal-users"/> </security-setting> <!-- 仅允许外部用户订阅指定主题地址 --> <security-setting match="external.notify.#"> <permission type="consume" roles="external-users"/> </security-setting> </security-settings>
- 强制禁用永久订阅:如果要确保外部用户无法创建持久化订阅,在
address-settings节点添加配置:
<address-settings> <address-setting match="external.notify.#"> <max-durable-subscriptions>0</max-durable-subscriptions> <!-- 禁止持久化订阅 --> </address-setting> </address-settings>
通过send权限的限制,外部用户无法通过这个acceptor发送任何消息;max-durable-subscriptions则彻底阻止了永久订阅的创建。
内容的提问来源于stack exchange,提问作者Piotr Sulecki
相关产品推荐
相关产品推荐

