You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在权限受限的情况下连接JMSToolBox与ActiveMQ Artemis

问题:JMSToolBox连接ActiveMQ Artemis 2.x时的临时队列权限问题

使用JMSToolBox连接ActiveMQ Artemis 2.x broker时,它会自动创建UUID命名的非持久临时队列及对应地址,但broker的安全策略不允许创建任意名称的地址和队列,触发安全异常。

目前临时解决方案是给所有地址(match="#")授予createAddress、createNonDurableQueue、send、consume权限,也可添加manage权限(实际未用到),但这种权限范围过宽,不想给仅需查看/读写特定队列的用户开放。

错误信息

org.apache.activemq.artemis.api.core.ActiveMQSecurityException: AMQ229213: User: amq_user does not have permission='CREATE_NON_DURABLE_QUEUE' for queue 2a092c7c-c335-4f16-867e-c0253d34a3e6 on address 2a092c7c-c335-4f16-867e-c0253d34a3e6

疑问点

  • 能否为所有临时队列单独设置安全配置?broker.xml中的temporary-queue-namespace配置似乎仅对地址设置生效。
  • 针对match="activemq.management#"设置的安全配置为何不起作用?
  • 能否在应用端指定具体的临时队列名称或地址前缀?修改应用配置使其使用预定义或带前缀的地址?

JMSToolBox相关配置与代码

JMSToolBox帮助文档提到的连接要求配置(使用jms.queue前缀,实际无效):

The following configuration is required in broker.xml for JMSToolBox :
 <security-setting match="jms.queue.activemq.management">
 <permission type="manage" roles="<admin role>" />
 </security-setting>

JMSToolBox中创建管理会话的代码片段:

Session sessionJMS = jmsConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue managementQueue = ((ActiveMQSession) sessionJMS).createQueue("activemq.management");
QueueRequestor requestorJMS = new QueueRequestor((QueueSession) sessionJMS, managementQueue);

问题复现步骤

  1. 创建带admin用户的ActiveMQ Artemis实例:artemis.cmd create --user admin --password admin --require-login /path/to/instance
  2. 启动实例:artemis run
  3. 创建只读用户(如"view"),分配角色"view"
  4. 为地址匹配activemq.management#添加角色"view"的安全配置
  5. 使用admin用户从JMSToolBox连接(成功)
  6. 使用view用户从JMSToolBox连接(触发错误)

示例安全配置

<security-settings>
         <security-setting match="#">
            <permission type="createNonDurableQueue" roles="amq"/>
            <permission type="deleteNonDurableQueue" roles="amq"/>
            <permission type="createDurableQueue" roles="amq"/>
            <permission type="deleteDurableQueue" roles="amq"/>
            <permission type="createAddress" roles="amq"/>
            <permission type="deleteAddress" roles="amq"/>
            <permission type="consume" roles="amq"/>
            <permission type="browse" roles="amq"/>
            <permission type="send" roles="amq"/>
            <!-- we need this otherwise ./artemis data imp wouldn't work -->
            <permission type="manage" roles="amq"/>
         </security-setting>
         <security-setting match="activemq.management#">
             <permission type="createNonDurableQueue" roles="amq,view"/>
             <permission type="deleteNonDurableQueue" roles="amq,view"/>
             <permission type="createDurableQueue" roles="amq,view"/>
             <permission type="deleteDurableQueue" roles="amq,view"/>
             <permission type="createAddress" roles="amq,view"/>
             <permission type="deleteAddress" roles="amq,view"/>
             <permission type="consume" roles="amq,view"/>
             <permission type="browse" roles="amq,view"/>
             <permission type="send" roles="amq,view"/>
             <permission type="manage" roles="amq,view"/>
         </security-setting>
      </security-settings>

完整栈追踪

org.apache.activemq.artemis.api.core.ActiveMQSecurityException: AMQ229213: User: amq_user does not have permission='CREATE_NON_DURABLE_QUEUE' for queue 2a092c7c-c335-4f16-867e-c0253d34a3e6 on address 2a092c7c-c335-4f16-867e-c0253d34a3e6
    at org.apache.activemq.artemis.core.protocol.core.impl.ChannelImpl.sendBlocking(ChannelImpl.java:558)
    at org.apache.activemq.artemis.core.protocol.core.impl.ChannelImpl.sendBlocking(ChannelImpl.java:450)
    at org.apache.activemq.artemis.core.protocol.core.impl.ActiveMQSessionContext.createQueue(ActiveMQSessionContext.java:829)
    at org.apache.activemq.artemis.core.client.impl.ClientSessionImpl.internalCreateQueue(ClientSessionImpl.java:2054)
    at org.apache.activemq.artemis.core.client.impl.ClientSessionImpl.createQueue(ClientSessionImpl.java:309)
    at org.apache.activemq.artemis.jms.client.ActiveMQSession.createTemporaryQueue(ActiveMQSession.java:1007)
    at javax.jms.QueueRequestor.<init>(QueueRequestor.java:93)
    at org.titou10.jtb.qm.artemis2.ActiveMQArtemis2QManager.connect(ActiveMQArtemis2QManager.java:221)
    at org.titou10.jtb.jms.model.JTBConnection.connect(JTBConnection.java:267)
    at org.titou10.jtb.handler.SessionConnectHandler$1.run(SessionConnectHandler.java:111)
    at org.eclipse.swt.custom.BusyIndicator.showWhile(BusyIndicator.java:74)
    at org.titou10.jtb.handler.SessionConnectHandler.execute(SessionConnectHandler.java:106)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.base/java.lang.reflect.Method.invoke(Unknown Source)
    at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:58)
    at org.eclipse.e4.core.internal.di.InjectorImpl.invokeUsingClass(InjectorImpl.java:317)
    at org.eclipse.e4.core.internal.di.InjectorImpl.invoke(InjectorImpl.java:251)
    at org.eclipse.e4.core.contexts.ContextInjectionFactory.invoke(ContextInjectionFactory.java:173)
    at org.eclipse.e4.core.commands.internal.HandlerServiceHandler.execute(HandlerServiceHandler.java:156)
    at org.eclipse.core.commands.Command.executeWithChecks(Command.java:488)
    at org.eclipse.core.commands.ParameterizedCommand.executeWithChecks(ParameterizedCommand.java:485)
    at org.eclipse.e4.core.commands.internal.HandlerServiceImpl.executeHandler(HandlerServiceImpl.java:213)
    at org.eclipse.e4.ui.workbench.renderers.swt.HandledContributionItem.executeItem(HandledContributionItem.java:438)
    at org.eclipse.e4.ui.workbench.renderers.swt.AbstractContributionItem.handleWidgetSelection(AbstractContributionItem.java:449)
    at org.eclipse.e4.ui.workbench.renderers.swt.AbstractContributionItem.lambda$2(AbstractContributionItem.java:475)
    at org.eclipse.swt.widgets.EventTable.sendEvent(EventTable.java:89)
    at org.eclipse.swt.widgets.Display.sendEvent(Display.java:4256)
    at org.eclipse.swt.widgets.Widget.sendEvent(Widget.java:1066)
    at org.eclipse.swt.widgets.Display.runDeferredEvents(Display.java:4054)
    at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3642)
    at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$5.run(PartRenderingEngine.java:1155)
    at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:338)
    at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1046)
    at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:155)
    at org.eclipse.e4.ui.internal.workbench.swt.E4Application.start(E4Application.java:168)
    at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:203)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:136)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:402)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:255)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.base/java.lang.reflect.Method.invoke(Unknown Source)
    at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:659)
    at org.eclipse.equinox.launcher.Main.basicRun(Main.java:596)
    at org.eclipse.equinox.launcher.Main.run(Main.java:1467)

内容的提问来源于stack exchange,提问作者Aleksandr Milovidov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 10:01:44