如何在权限受限的情况下连接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);
问题复现步骤
- 创建带admin用户的ActiveMQ Artemis实例:
artemis.cmd create --user admin --password admin --require-login /path/to/instance - 启动实例:
artemis run - 创建只读用户(如"view"),分配角色"view"
- 为地址匹配
activemq.management#添加角色"view"的安全配置 - 使用admin用户从JMSToolBox连接(成功)
- 使用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
相关产品推荐
相关产品推荐

