本文介绍了使用WildFly在JMS中进行JAAS身份验证:javax.jms.JMSSecurityException:HQ119032:User:null在地址{2}上没有权限= SEND的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 使用WildFly 9.0.2 final,< hornetq-server> 部分在 standalone-full.xml 如下。 < hornetq-server> < security-domain> ProjectRealm< / security-domain> < security-enabled> true< / security-enabled> < journal-file-size> 102400< / journal-file-size> < security-settings> < security-setting match =#> < permission type =sendroles =ROLE_USER ROLE_ADMIN/> < permission type =consumeroles =ROLE_USER ROLE_ADMIN/> < permission type =createDurableQueueroles =ROLE_USER ROLE_ADMIN/> < permission type =deleteDurableQueueroles =ROLE_USER ROLE_ADMIN/> < permission type =createNonDurableQueueroles =ROLE_USER ROLE_ADMIN/> < permission type =deleteNonDurableQueueroles =ROLE_USER ROLE_ADMIN/> < / security-setting> < / security-settings> < jms-connection-factories> < connection-factory name =destinationFactory> < connectors> < connector-ref connector-name =http-connector/> < / connectors> < entries> < entry name =java:jboss / exported / jms / destinationFactory/> < / entries> < / connection-factory> < / jms-connection-factories> < jms-destinations> < jms-queue name =userStatusQueue> < entry name =jms / destination/> < entry name =java:jboss / exported / jms / destination/> < / jms-queue> < / jms-destinations> < / hornetq-server> 它定义了一个名为 destinationFactory 的连接工厂使用 http-connector 和一个名为 userStatusQueue 的队列,这些队列绑定到嵌套< entry> 元素。 它还定义了一个安全域。 < security-domain> ProjectRealm< / security-domain> 安全已启用(默认)使用, < security-enabled> true< / security-enabled> 在这种情况下,它会导致抛出以下异常。 15:49:28,093警告[javax.enterprise.resource.webcontainer.jsf.lifecycle](默认任务-2)java.lang.RuntimeException:javax.jms .JMSSecurityRuntimeException:HQ119032:User:null在地址{2}上没有权限= SEND:javax.el.E​​LException:java.lang.RuntimeException:javax.jms.JMSSecurityRuntimeException:HQ119032:User:null没有权限= SEND on address { 2} at com.sun.el.parser.AstValue.invoke(AstValue.java:296) at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304) at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40) at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50) at org .jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40) at org.jboss.weld.el.WeldMethodExpression.in voke(WeldMethodExpression.java:50) at javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:149) at javax.faces.event.ActionEvent.processListener(ActionEvent.java:88) at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:814) at javax.faces.component.UICommand.broadcast(UICommand.java:300) at javax.faces .component.UIViewRoot.broadcastEvents(UIViewRoot.java:790) at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282) at com.sun.faces.lifecycle.InvokeApplicationPhase.execute (InvokeApplicationPhase.java:81) at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java) :198) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:658) at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:86)在io.undertow.se rvlet.handlers.FilterHandler $ FilterChainImpl.doFilter(FilterHandler.java:130) at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:78) at io.undertow.servlet。 core.ManagedFilter.doFilter(ManagedFilter.java:60) at io.undertow.servlet.handlers.FilterHandler $ FilterChainImpl.doFilter(FilterHandler.java:132) at io.undertow.websockets.jsr。 JsrWebSocketFilter.doFilter(JsrWebSocketFilter.java:151) at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60) at io.undertow.servlet.handlers.FilterHandler $ FilterChainImpl。 doFilter(FilterHandler.java:132) at org.omnifaces.facesviews.FacesViewsForwardingFilter.filterExtensionLess(FacesViewsForwardingFilter.java:128) at org.omnifaces.facesviews.FacesViewsForwardingFilter.doFilter(FacesViewsForwardingFilter.java:89) at org.omnifaces.filter.HttpFilter.doFilter(HttpFilter.java:108) at io.undertow.servlet.core.ManagedFilter.doFi lter(ManagedFilter.java:60) at io.undertow.servlet.handlers.FilterHandler $ FilterChainImpl.doFilter(FilterHandler.java:132) at filter.LoginNocacheFilter.doFilter(LoginNocacheFilter.java:32) at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60) at io.undertow.servlet.handlers.FilterHandler $ FilterChainImpl.doFilter(FilterHandler.java:132) at org.omnifaces.filter.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:122) at org.omnifaces.filter.HttpFilter.doFilter(HttpFilter.java:108) at io.undertow.servlet .core.ManagedFilter.doFilter(ManagedFilter.java:60) at io.undertow.servlet.handlers.FilterHandler $ FilterChainImpl.doFilter(FilterHandler.java:132) at io.undertow.servlet.handlers .FilterHandler.handleRequest(FilterHandler.java:85) at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) at io.undertow.se rvlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78) at io.undertow.server。 handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131) at io.undertow.servlet.handlers。 security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.security.handlers.AuthenticationConstraintHandler。 handleRequest(AuthenticationConstraintHandler.java:51) at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) at io.undertow.servlet.handle rs.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) at io.undertow.servlet.handlers.security.ServletSecurityConstraintHandler.handleRequest(ServletSecurityConstraintHandler.java:56) at io.undertow.security。 handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58) at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:72) at io.undertow.security.handlers。 NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50) at io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76) at io.undertow.server.handlers.PredicateHandler.handleRequest( PredicateHandler.java:43) at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61) at io.undertow.s erver.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.servlet.handlers。 ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:282) at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:261) at io.undertow.servlet.handlers.ServletInitialHandler.access $ 000 (ServletInitialHandler.java:80) at io.undertow.servlet.handlers.ServletInitialHandler $ 1.handleRequest(ServletInitialHandler.java:172) at io.undertow.server.Connectors.executeRootHandler(Connectors.java: 199) at io.undertow.server.HttpServerExchange $ 1.run(HttpServerExchange.java:774) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread .java:745)引起:java.lang.RuntimeException:javax.jms.JMSSecurityRuntimeException:HQ119032:User:null在io.undertow.servlet上的地址{2} 上没有权限= SEND。 spec.RequestDispatcherImpl.forwardImpl(RequestDispatcherImpl.java:219) at io.undertow.servlet.spec.RequestDispatcherImpl.forward(RequestDispatcherImpl.java:108) at com.sun.faces.context.ExternalContextImpl。 dispatch(ExternalContextImpl.java:643) at admin.bean.SignInCheck.signIn(SignInCheck.java:63) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun。 reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java: 497) at com.sun.el.parser.AstValue.invoke(AstValue.java:292) ... 64 more 引起:javax.jms.JMSSecurityRuntimeException:HQ119032:User :null d oesnt在org.hornetq.jms.client.JmsExceptionUtils.convertToRuntimeException(JmsExceptionUtils.java:76) at org.hornetq.jms.client.HornetQJMSProducer.send上有地址{2} 的权限= SEND( HornetQJMSProducer.java:112) at org.hornetq.jms.client.HornetQJMSProducer.send(HornetQJMSProducer.java:135) at filter.SecurityCheck.sendMessageToDestination(SecurityCheck.java:54) at filter.SecurityCheck.doAfterProcessing(SecurityCheck.java:107) at filter.SecurityCheck.doFilter(SecurityCheck.java:161) at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java) :60) at io.undertow.servlet.handlers.FilterHandler $ FilterChainImpl.doFilter(FilterHandler.java:132) at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:85 ) at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) at io.undertow.servlet.handlers.Servlet DispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.server.handlers.PredicateHandler.handleRequest( PredicateHandler.java:43) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java: 263) at io.undertow.servlet.handlers.ServletInitialHandler.dispatchToPath(ServletInitialHandler.java:198) at io.undertow.servlet.spec.RequestDispatcherImpl.forwardImpl(RequestDispatcherImpl.java:195) ... 72更多引起:javax.jms.JMSSecurityException:HQ119032:用户:null在org.hornetq.core.protocol.core上的地址{2} 上没有权限= SEND。 impl.ChannelImpl.sendBlocking(ChannelImpl.java:399) at org.hornetq.core.client.impl.ClientProducerImpl.sendRegularMessage(ClientProd ucerImpl.java:334) at org.hornetq.core.client.impl.ClientProducerImpl.doSend(ClientProducerImpl.java:304) at org.hornetq.core.client.impl.ClientProducerImpl.send( ClientProducerImpl.java:135) at org.hornetq.jms.client.HornetQMessageProducer.doSendx(HornetQMessageProducer.java:524) at org.hornetq.jms.client.HornetQMessageProducer.send(HornetQMessageProducer.java: 210) at org.hornetq.jms.client.HornetQMessageProducer.send(HornetQMessageProducer.java:200) at org.hornetq.jms.client.HornetQJMSProducer.send(HornetQJMSProducer.java:107) ... 87更多引起:HornetQSecurityException [errorType = SECURITY_EXCEPTION消息= HQ119032:用户:null没有权限=发送地址{2}] ... 95更多 当< security-enabled> 的值为 false 。但是,我只需要具有预定义权限/角色( ROLE_ADMIN 或 ROLE_USER )的用户来创建队列并发送消息跨越。 如上所示,使用< security-domain> 的方法失败并出现上述异常。 我尝试完全按照 /standalone/configuration/application-roles.properties 中添加角色$ c> ProjectRealm.properties 文件中使用 < module -option name =rolesProperties value =file:$ {jboss.server.config.dir} /ProjectRealm.properties/> 在< login-module> 内但是它没有帮助。 admins = ROLE_ADMIN users = ROLE_USER 在队列中发送消息之前还需要做些什么来验证用户? 其他: JAAS安全管理器使用以下域来验证和授权用户使用JDBC领域(XA数据源)。这已经可以正常工作了。 < security-domain name =ProjectRealmcache-type = 默认 > < authentication> < login-module code =Databaseflag =required> < module-option name =dsJndiNamevalue =java:jboss / datasources / projectXADatasource/> < module-option name =principalsQueryvalue =SELECT password FROM user_table WHERE email_id =?/> < module-option name =rolesQueryvalue =SELECT user_role,'Roles'FROM user_roles ur INNER JOIN user_table ut ON ur.user_id = ut.user_id WHERE ut.email_id =?/> < module-option name =hashAlgorithmvalue =SHA-256/> < module-option name =hashEncodingvalue =hex/> < module-option name =hashCharsetvalue =UTF-8/> < module-option name =hashStorePasswordvalue =false/> < module-option name =unauthenticatedIdentityvalue =guest/> < / login-module> < login-module code =RoleMappingflag =required> < module-option name =rolesPropertiesvalue =file:$ {jboss.server.config.dir} /ProjectRealm.properties/> < module-option name =replaceRolevalue =false/> < / login-module> < / authentication> < / security-domain> 队列被注入一个身份验证Servlet过滤器,由 JMSContext 在用户成功通过身份验证并授权后在队列中发送消息。 @WebFilter(filterName =SecurityCheck,urlPatterns = {/ WEB-INF / jaas / *},dispatcherTypes = {DispatcherType.FORWARD}) public final class SecurityCheck实现Filter { @Resource( lookup =java:/ jms / destination)私有队列队列; @Inject @JMSConnectionFactory(java:jboss / exported / jms / destinationFactory) private JMSContext context; // jms / destinationFactory应该在这里工作,但它只能使用上面的完全限定命名空间。 public SecurityCheck(){} private void sendMessageToDestination(String message)抛出JMSException { context.createProducer()。send(queue,message); } private void doBeforeProcessing(HttpServletRequest请求,HttpServletResponse响应)抛出IOException,ServletException { String userName = request.getParameter(userName); request.login(userName.trim(),request.getParameter(password)); } private void doAfterProcessing(HttpServletRequest请求,HttpServletResponse响应)抛出IOException,ServletException,JMSException { if(request.isUserInRole(ROLE_ADMIN)){ sendMessageToDestination(Message); //重定向到安全区域。 } else if(request.isUserInRole(ROLE_USER)){ sendMessageToDestination(Message); //重定向到安全区域。 } // ... } // ... ... } 我使用自签名SSL证书进行纯测试。因此,它使用 https:// localhost:8443 / ContextPath 来访问受保护的Web资源 < transport-guarantee> CONFIDENTIAL< / transport-guarantee> in web.xml 。 更新: 消息驱动Bean使用消息: @JMSDestinationDefinition(name =destination,interfaceName =javax.jms.Queue,resourceAdapter =jmsra,destinationName =destination ) @MessageDriven(activationConfig = { @ActivationConfigProperty(propertyName =destinationLookup,propertyValue =jms / destination), @ActivationConfigProperty(propertyName =destinationType,propertyValue = javax.jms.Queue), @ActivationConfigProperty(propertyName =connectionFactoryLookup,propertyValue =java:jboss / exported / jms / destinationFactory), @ActivationConfigProperty(propertyName =messagingType,propertyValue =javax。 jms.MessageListener), @ActivationConfigProperty(propertyName =destination,propertyValue =java:/ jms / destination), @ActivationConfigProperty(propertyName =useJNDI,propertyValue =true) })公共类UserStatusMessageBean实现MessageListener { public UserStatusMessageBean(){} @Resource private MessageDrivenContext messageDrivenContext; @EJB private UserStatusService userStatusService; @Override public void onMessage(消息消息){ try { if(message instanceof TextMessage){ TextMessage textMessage = (TextMessage)消息; String text = textMessage.getText(); if(StringUtils.isNotBlank(text)){ userStatusService.addHost(text); } else { System.out.println(未找到消息。); } } else { System.out.println(消息类型错误:+ message.getClass()。getName()); } } catch(JMSException e){ messageDrivenContext.setRollbackOnly(); System.out.println(e); } catch(Throwable e){ System.out.println(e); } } } 有一个远程EJB正在注入上述MDB,需要定义权限。 @Stateless @DeclareRoles(value = {ROLE_ADMIN, ROLE_USER}) @RolesAllowed(value = {ROLE_ADMIN,ROLE_USER})公共类UserStatusBean实现UserStatusService { @PersistenceContext private EntityManager EntityManager的; @Override public void addHost(String hostName){ //通过JPA插入或更新。 } } 部署应用程序时,服务器继续投掷除非给出 false 值,否则递归地执行异常, <假<>启用安全性的/启用安全性的> 20:21: 55,343 ERROR [org.hornetq.ra](default-threads - 3)HQ154003:无法重新连接org.hornetq.ra.inflow.HornetQActivationSpec(ra =org.hornetq.ra.HornetQResourceAdapter@dc9e56 destination = java:/ jms / destination destinationType = javax.jms.Queue ack = Auto-acknowledge durable = false clientID = null user = null maxSession = 15):HornetQSecurityException [errorType = SECURITY_EXCEPTION message = HQ119032:User:null在地址{2}上没有权限= CONSUME] at org.hornetq.core.protocol.core.impl.ChannelImpl.sendBlocking(ChannelImpl.java:399) at org.hornetq.core.client.impl.ClientSessionImpl.internalCreateConsumer(ClientSessionImpl.java:2064 ) at org.hornetq.core.client.impl.ClientSessionImpl.createConsumer(ClientSessionImpl.java:527) at org.hornetq.core.client.impl.ClientSessionImpl.createConsumer(ClientSessionImpl.java:474 ) at org.hornetq.core.client.impl.DelegatingSession.createConsumer(Delegating) Session.java:206) at org.hornetq.ra.inflow.HornetQMessageHandler.setup(HornetQMessageHandler.java:184) at org.hornetq.ra.inflow.HornetQActivation.setup(HornetQActivation.java: 340) at org.hornetq.ra.inflow.HornetQActivation.handleFailure(HornetQActivation.java:768) at org.hornetq.ra.inflow.HornetQActivation $ SetupActivation.run(HornetQActivation.java:823) at org.jboss.jca.core.workmanager.WorkWrapper.run(WorkWrapper.java:226) at org.jboss.threads.SimpleDirectExecutor.execute(SimpleDirectExecutor.java:33)在org.jboss.threads.QueueExecutor.runTask(QueueExecutor.java:808) at org.jboss.threads.QueueExecutor.access $ 100(QueueExecutor.java:45) at org.jboss.threads。 QueueExecutor $ Worker.run(QueueExecutor.java:828) at java.lang.Thread.run(Thread.java:745) at org.jboss.threads.JBossThread.run(JBossThread.java: 320) 解决方案我转载了sa我在WildFly 9.0.2上的问题,(使用REST EJB资源而不是你的Servlet) 23:31:22,138 ERROR [ io.undertow.request](默认任务-7)UT005023:对/ jeeshop-admin / rs / users / administrators的异常处理请求:org.jboss.resteasy.spi.UnhandledException:javax.jms.JMSSecurityException:HQ119032:User:null没有权限= SEND在地址{2} org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:76) 为了解决这个问题,我做了以下工作: @Resource(mappedName = java:jboss / exported / jms / destinationFactory) ConnectionFactory工厂; private void sendMessageToDestination(String message,String user)抛出JMSException { try(Connection connection = factory.createConnection(user,hardcodedPassword); Session session = connection。 createSession(false,Session.AUTO_ACKNOWLEDGE); MessageProducer producer = session.createProducer(queue)){ TextMessage textMessage = session.createTextMessage(message); producer.send(textMessage); } } 因为你可以看到我提供的是有效的连接创建期间的用户名和密码。此用户与hornetq-server安全设置中配置的用户具有相同的角色。 我没有使用与您相同的安全域(我使用了自己的代码)重现你的问题)。 如果你的工作不顺利,这里是: < security -domain name =jeeshopcache-type =default> < authentication> < login-module code =Databaseflag =required> < module-option name =dsJndiNamevalue =java:/ JeeshopDS/> < module-option name =principalsQueryvalue =从用户中选择密码,其中login =?和(禁用为空或禁用= 0)并激活= 1/> < module-option name =rolesQueryvalue =选择名称,角色r中的'角色',用户角色,用户u,u.login =?和u.id = ur.userId和r.id = ur.roleId/> < module-option name =hashAlgorithmvalue =SHA-256/> < module-option name =hashEncodingvalue =base64/> < module-option name =unauthenticatedIdentityvalue =guest/> < / login-module> < / authentication> < / security-domain> 我的数据源: < xa-datasource jndi-name =java:/ JeeshopDSpool-name =JeeshopDSenabled =true> < xa-datasource-property name =ServerName> localhost < / xa-datasource-property> < xa-datasource-property name =DatabaseName> jeeshop < / xa-datasource-property> < driver> mysql< / driver> < security> < user-name> jeeshop< / user-name> < password> test< / password> < / security> < validation> < valid-connection-checker class-name =org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLValidConnectionChecker/> < exception-sorter class-name =org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLExceptionSorter/> < / validation> < / xa-datasource> 我的DDL for Roles存储的摘录: CREATE TABLE IF NOT EXISTS Role( id bigint(20)NOT NULL AUTO_INCREMENT, name varchar(255)NOT NULL, PRIMARY KEY(id), UNIQUE KEY UK_Role_name(name)); CREATE TABLE IF NOT NOT EXISTS User_Role( userId bigint(20)NOT NULL, roleId bigint(20)NOT NULL, PRIMARY KEY(userId,roleId) ); 编辑 以下MDB允许读取 sendMessageToDestination()生成消息的目的地: @MessageDriven(activationConfig = { @ActivationConfigProperty(propertyName =destinationType,propertyValue =javax.jms.Queue), @ActivationConfigProperty(propertyName =useJNDI,propertyValue = true), @ActivationConfigProperty(propertyName =destination,propertyValue =java:jboss / exported / jms / destination), @ActivationConfigProperty(propertyName =acknowledgeMode,propertyValue =Auto-确认)})公共类TestMDB实现MessageListener { @Override @PermitAll public void onMessage(消息消息){ if(message instanceof TextMessage){ try { System.out.println(((TextMessage)message).getText()); } catch(JMSException e){ //为事务回滚传播抛出新的IllegalArgumentException(e); } } } } 您最终可以更改MDB使用的Principal。请看这些链接: https://docs.jboss.org/author/display/WFLY9/jboss-ejb3.xml+Reference https://developer.jboss.org/message/836356 Using WildFly 9.0.2 final, the <hornetq-server> section is defined in standalone-full.xml as follows.<hornetq-server> <security-domain>ProjectRealm</security-domain> <security-enabled>true</security-enabled> <journal-file-size>102400</journal-file-size> <security-settings> <security-setting match="#"> <permission type="send" roles="ROLE_USER ROLE_ADMIN"/> <permission type="consume" roles="ROLE_USER ROLE_ADMIN"/> <permission type="createDurableQueue" roles="ROLE_USER ROLE_ADMIN"/> <permission type="deleteDurableQueue" roles="ROLE_USER ROLE_ADMIN"/> <permission type="createNonDurableQueue" roles="ROLE_USER ROLE_ADMIN"/> <permission type="deleteNonDurableQueue" roles="ROLE_USER ROLE_ADMIN"/> </security-setting> </security-settings> <jms-connection-factories> <connection-factory name="destinationFactory"> <connectors> <connector-ref connector-name="http-connector"/> </connectors> <entries> <entry name="java:jboss/exported/jms/destinationFactory"/> </entries> </connection-factory> </jms-connection-factories> <jms-destinations> <jms-queue name="userStatusQueue"> <entry name="jms/destination"/> <entry name="java:jboss/exported/jms/destination"/> </jms-queue> </jms-destinations></hornetq-server>It defines a connection factory named destinationFactory which uses http-connector and a queue named userStatusQueue which are bound to a JNDI name as listed in the nested <entry> element.It also defines a security domain.<security-domain>ProjectRealm</security-domain>Security is enabled (default) using,<security-enabled>true</security-enabled>In which case, it causes the following exception to be thrown.15:49:28,093 WARNING [javax.enterprise.resource.webcontainer.jsf.lifecycle] (default task-2) java.lang.RuntimeException: javax.jms.JMSSecurityRuntimeException: HQ119032: User: null doesnt have permission=SEND on address {2}: javax.el.ELException: java.lang.RuntimeException: javax.jms.JMSSecurityRuntimeException: HQ119032: User: null doesnt have permission=SEND on address {2} at com.sun.el.parser.AstValue.invoke(AstValue.java:296) at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:304) at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40) at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50) at org.jboss.weld.util.el.ForwardingMethodExpression.invoke(ForwardingMethodExpression.java:40) at org.jboss.weld.el.WeldMethodExpression.invoke(WeldMethodExpression.java:50) at javax.faces.event.MethodExpressionActionListener.processAction(MethodExpressionActionListener.java:149) at javax.faces.event.ActionEvent.processListener(ActionEvent.java:88) at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:814) at javax.faces.component.UICommand.broadcast(UICommand.java:300) at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790) at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282) at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81) at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101) at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198) at javax.faces.webapp.FacesServlet.service(FacesServlet.java:658) at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:86) at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:130) at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:78) at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60) at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132) at io.undertow.websockets.jsr.JsrWebSocketFilter.doFilter(JsrWebSocketFilter.java:151) at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60) at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132) at org.omnifaces.facesviews.FacesViewsForwardingFilter.filterExtensionLess(FacesViewsForwardingFilter.java:128) at org.omnifaces.facesviews.FacesViewsForwardingFilter.doFilter(FacesViewsForwardingFilter.java:89) at org.omnifaces.filter.HttpFilter.doFilter(HttpFilter.java:108) at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60) at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132) at filter.LoginNocacheFilter.doFilter(LoginNocacheFilter.java:32) at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60) at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132) at org.omnifaces.filter.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:122) at org.omnifaces.filter.HttpFilter.doFilter(HttpFilter.java:108) at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60) at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132) at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:85) at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131) at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.security.handlers.AuthenticationConstraintHandler.handleRequest(AuthenticationConstraintHandler.java:51) at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46) at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64) at io.undertow.servlet.handlers.security.ServletSecurityConstraintHandler.handleRequest(ServletSecurityConstraintHandler.java:56) at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58) at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:72) at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50) at io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:282) at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:261) at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:80) at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:172) at io.undertow.server.Connectors.executeRootHandler(Connectors.java:199) at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:774) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745)Caused by: java.lang.RuntimeException: javax.jms.JMSSecurityRuntimeException: HQ119032: User: null doesnt have permission=SEND on address {2} at io.undertow.servlet.spec.RequestDispatcherImpl.forwardImpl(RequestDispatcherImpl.java:219) at io.undertow.servlet.spec.RequestDispatcherImpl.forward(RequestDispatcherImpl.java:108) at com.sun.faces.context.ExternalContextImpl.dispatch(ExternalContextImpl.java:643) at admin.bean.SignInCheck.signIn(SignInCheck.java:63) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at com.sun.el.parser.AstValue.invoke(AstValue.java:292) ... 64 moreCaused by: javax.jms.JMSSecurityRuntimeException: HQ119032: User: null doesnt have permission=SEND on address {2} at org.hornetq.jms.client.JmsExceptionUtils.convertToRuntimeException(JmsExceptionUtils.java:76) at org.hornetq.jms.client.HornetQJMSProducer.send(HornetQJMSProducer.java:112) at org.hornetq.jms.client.HornetQJMSProducer.send(HornetQJMSProducer.java:135) at filter.SecurityCheck.sendMessageToDestination(SecurityCheck.java:54) at filter.SecurityCheck.doAfterProcessing(SecurityCheck.java:107) at filter.SecurityCheck.doFilter(SecurityCheck.java:161) at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60) at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:132) at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:85) at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62) at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:263) at io.undertow.servlet.handlers.ServletInitialHandler.dispatchToPath(ServletInitialHandler.java:198) at io.undertow.servlet.spec.RequestDispatcherImpl.forwardImpl(RequestDispatcherImpl.java:195) ... 72 moreCaused by: javax.jms.JMSSecurityException: HQ119032: User: null doesnt have permission=SEND on address {2} at org.hornetq.core.protocol.core.impl.ChannelImpl.sendBlocking(ChannelImpl.java:399) at org.hornetq.core.client.impl.ClientProducerImpl.sendRegularMessage(ClientProducerImpl.java:334) at org.hornetq.core.client.impl.ClientProducerImpl.doSend(ClientProducerImpl.java:304) at org.hornetq.core.client.impl.ClientProducerImpl.send(ClientProducerImpl.java:135) at org.hornetq.jms.client.HornetQMessageProducer.doSendx(HornetQMessageProducer.java:524) at org.hornetq.jms.client.HornetQMessageProducer.send(HornetQMessageProducer.java:210) at org.hornetq.jms.client.HornetQMessageProducer.send(HornetQMessageProducer.java:200) at org.hornetq.jms.client.HornetQJMSProducer.send(HornetQJMSProducer.java:107) ... 87 moreCaused by: HornetQSecurityException[errorType=SECURITY_EXCEPTION message=HQ119032: User: null doesnt have permission=SEND on address {2}] ... 95 moreMessage is sent through the defined queue (which is received by a Message Driven Bean (MDB)), when <security-enabled> is given a false value. I however need only the users who have a predefined authority/role (ROLE_ADMIN or ROLE_USER) to create the queue and send messages across.The approach using <security-domain> as shown above fails with the above exception.I tried adding roles in /standalone/configuration/application-roles.properties exactly as defined in the ProjectRealm.properties file used in<module-option name="rolesProperties" value="file:${jboss.server.config.dir}/ProjectRealm.properties"/>inside <login-module> but it did not help either.admins=ROLE_ADMINusers=ROLE_USERWhat more needs to be done to authenticate users before sending messages across the queue?Additional :The JAAS security manager uses the following domain to authenticate and authorize users using a JDBC realm (XA datasource). This already works fine.<security-domain name="ProjectRealm" cache-type="default"> <authentication> <login-module code="Database" flag="required"> <module-option name="dsJndiName" value="java:jboss/datasources/projectXADatasource"/> <module-option name="principalsQuery" value="SELECT password FROM user_table WHERE email_id=?"/> <module-option name="rolesQuery" value="SELECT user_role, 'Roles' FROM user_roles ur INNER JOIN user_table ut ON ur.user_id=ut.user_id WHERE ut.email_id=?"/> <module-option name="hashAlgorithm" value="SHA-256"/> <module-option name="hashEncoding" value="hex"/> <module-option name="hashCharset" value="UTF-8"/> <module-option name="hashStorePassword" value="false"/> <module-option name="unauthenticatedIdentity" value="guest"/> </login-module> <login-module code="RoleMapping" flag="required"> <module-option name="rolesProperties" value="file:${jboss.server.config.dir}/ProjectRealm.properties"/> <module-option name="replaceRole" value="false"/> </login-module> </authentication></security-domain>The queue is injected in an authentication Servlet filter which is used by JMSContext to send a message across the queue after a user is successfully authenticated and authorize.@WebFilter(filterName = "SecurityCheck", urlPatterns = {"/WEB-INF/jaas/*"}, dispatcherTypes = {DispatcherType.FORWARD})public final class SecurityCheck implements Filter { @Resource(lookup = "java:/jms/destination") private Queue queue; @Inject @JMSConnectionFactory("java:jboss/exported/jms/destinationFactory") private JMSContext context; // jms/destinationFactory is expected to work here but it only works using the fully qualified namespace as above. public SecurityCheck() {} private void sendMessageToDestination(String message) throws JMSException { context.createProducer().send(queue, message); } private void doBeforeProcessing(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { String userName = request.getParameter("userName"); request.login(userName.trim(), request.getParameter("password")); } private void doAfterProcessing(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException, JMSException { if (request.isUserInRole("ROLE_ADMIN")) { sendMessageToDestination("Message"); // Redirect to a secure area. } else if (request.isUserInRole("ROLE_USER")) { sendMessageToDestination("Message"); // Redirect to a secure area. } //... } //...}I am using a self-signed SSL certificate for a pure testing purpose. Thus, it uses https://localhost:8443/ContextPath for accessing secured web resources <transport-guarantee>CONFIDENTIAL</transport-guarantee> in web.xml.Update :The Message Driven Bean consuming messages : @JMSDestinationDefinition(name = "destination", interfaceName = "javax.jms.Queue", resourceAdapter = "jmsra", destinationName = "destination")@MessageDriven(activationConfig = { @ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "jms/destination"), @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"), @ActivationConfigProperty(propertyName = "connectionFactoryLookup", propertyValue = "java:jboss/exported/jms/destinationFactory"), @ActivationConfigProperty(propertyName = "messagingType", propertyValue = "javax.jms.MessageListener"), @ActivationConfigProperty(propertyName = "destination", propertyValue = "java:/jms/destination"), @ActivationConfigProperty(propertyName = "useJNDI", propertyValue = "true")})public class UserStatusMessageBean implements MessageListener { public UserStatusMessageBean() {} @Resource private MessageDrivenContext messageDrivenContext; @EJB private UserStatusService userStatusService; @Override public void onMessage(Message message) { try { if (message instanceof TextMessage) { TextMessage textMessage = (TextMessage) message; String text = textMessage.getText(); if (StringUtils.isNotBlank(text)) { userStatusService.addHost(text); } else { System.out.println("No message found."); } } else { System.out.println("Message is of wrong type : " + message.getClass().getName()); } } catch (JMSException e) { messageDrivenContext.setRollbackOnly(); System.out.println(e); } catch (Throwable e) { System.out.println(e); } }}There is a remote EJB being injected into the above MDB which requires defined authorities.@Stateless@DeclareRoles(value = {"ROLE_ADMIN", "ROLE_USER"})@RolesAllowed(value = {"ROLE_ADMIN", "ROLE_USER"})public class UserStatusBean implements UserStatusService { @PersistenceContext private EntityManager entityManager; @Override public void addHost(String hostName) { // Insert or update via JPA. }}When the application is deployed, the server keeps on throwing following exception recursively unless a false value is given in,<security-enabled>false</security-enabled>20:21:55,343 ERROR [org.hornetq.ra] (default-threads - 3) HQ154003: Unable to reconnect org.hornetq.ra.inflow.HornetQActivationSpec(ra=org.hornetq.ra.HornetQResourceAdapter@dc9e56 destination=java:/jms/destination destinationType=javax.jms.Queue ack=Auto-acknowledge durable=false clientID=null user=null maxSession=15): HornetQSecurityException[errorType=SECURITY_EXCEPTION message=HQ119032: User: null doesnt have permission=CONSUME on address {2}] at org.hornetq.core.protocol.core.impl.ChannelImpl.sendBlocking(ChannelImpl.java:399) at org.hornetq.core.client.impl.ClientSessionImpl.internalCreateConsumer(ClientSessionImpl.java:2064) at org.hornetq.core.client.impl.ClientSessionImpl.createConsumer(ClientSessionImpl.java:527) at org.hornetq.core.client.impl.ClientSessionImpl.createConsumer(ClientSessionImpl.java:474) at org.hornetq.core.client.impl.DelegatingSession.createConsumer(DelegatingSession.java:206) at org.hornetq.ra.inflow.HornetQMessageHandler.setup(HornetQMessageHandler.java:184) at org.hornetq.ra.inflow.HornetQActivation.setup(HornetQActivation.java:340) at org.hornetq.ra.inflow.HornetQActivation.handleFailure(HornetQActivation.java:768) at org.hornetq.ra.inflow.HornetQActivation$SetupActivation.run(HornetQActivation.java:823) at org.jboss.jca.core.workmanager.WorkWrapper.run(WorkWrapper.java:226) at org.jboss.threads.SimpleDirectExecutor.execute(SimpleDirectExecutor.java:33) at org.jboss.threads.QueueExecutor.runTask(QueueExecutor.java:808) at org.jboss.threads.QueueExecutor.access$100(QueueExecutor.java:45) at org.jboss.threads.QueueExecutor$Worker.run(QueueExecutor.java:828) at java.lang.Thread.run(Thread.java:745) at org.jboss.threads.JBossThread.run(JBossThread.java:320) 解决方案 I reproduced the same issue on WildFly 9.0.2, (using a REST EJB resource instead of your Servlet)23:31:22,138 ERROR [io.undertow.request] (default task-7) UT005023: Exception handling request to /jeeshop-admin/rs/users/administrators: org.jboss.resteasy.spi.UnhandledException: javax.jms.JMSSecurityException: HQ119032: User: null doesnt have permission=SEND on address {2} at org.jboss.resteasy.core.ExceptionHandler.handleApplicationException(ExceptionHandler.java:76)To fix it I did the following:@Resource(mappedName = "java:jboss/exported/jms/destinationFactory")ConnectionFactory factory;private void sendMessageToDestination(String message, String user) throws JMSException { try (Connection connection = factory.createConnection(user,"hardcodedPassword"); Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); MessageProducer producer = session.createProducer(queue)) { TextMessage textMessage = session.createTextMessage(message); producer.send(textMessage); }}So as you can see I'm providing a valid user name and password, during connection creation. This user has the same role as the one configured in hornetq-server security settings.I did not use exactly the same security domain as you then (I used my own code to reproduce your issue). In case yours does not work well, here it is:<security-domain name="jeeshop" cache-type="default"> <authentication> <login-module code="Database" flag="required"> <module-option name="dsJndiName" value="java:/JeeshopDS"/> <module-option name="principalsQuery" value="select password from User where login = ? and (disabled is null or disabled = 0) and activated = 1"/> <module-option name="rolesQuery" value="select name,'Roles' from Role r, User_Role ur, User u where u.login=? and u.id = ur.userId and r.id = ur.roleId"/> <module-option name="hashAlgorithm" value="SHA-256"/> <module-option name="hashEncoding" value="base64"/> <module-option name="unauthenticatedIdentity" value="guest"/> </login-module> </authentication></security-domain>My datasource:<xa-datasource jndi-name="java:/JeeshopDS" pool-name="JeeshopDS" enabled="true"> <xa-datasource-property name="ServerName"> localhost </xa-datasource-property> <xa-datasource-property name="DatabaseName"> jeeshop </xa-datasource-property> <driver>mysql</driver> <security> <user-name>jeeshop</user-name> <password>test</password> </security> <validation> <valid-connection-checker class-name="org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLValidConnectionChecker"/> <exception-sorter class-name="org.jboss.jca.adapters.jdbc.extensions.mysql.MySQLExceptionSorter"/> </validation></xa-datasource>Extract of my DDL for Roles storage:CREATE TABLE IF NOT EXISTS Role ( id bigint(20) NOT NULL AUTO_INCREMENT, name varchar(255) NOT NULL, PRIMARY KEY (id), UNIQUE KEY UK_Role_name (name));CREATE TABLE IF NOT EXISTS User_Role ( userId bigint(20) NOT NULL, roleId bigint(20) NOT NULL, PRIMARY KEY (userId,roleId));EDITThe following MDB allows to read the destination where sendMessageToDestination() produces messages:@MessageDriven(activationConfig = { @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"), @ActivationConfigProperty(propertyName = "useJNDI", propertyValue = "true"), @ActivationConfigProperty(propertyName = "destination", propertyValue = "java:jboss/exported/jms/destination"), @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge")})public class TestMDB implements MessageListener { @Override @PermitAll public void onMessage(Message message) { if (message instanceof TextMessage) { try { System.out.println(((TextMessage) message).getText()); } catch (JMSException e) { // propagate for transaction rollback throw new IllegalArgumentException(e); } } }}You could eventually change Principal used by MDB. See these links:https://docs.jboss.org/author/display/WFLY9/jboss-ejb3.xml+Referencehttps://developer.jboss.org/message/836356 这篇关于使用WildFly在JMS中进行JAAS身份验证:javax.jms.JMSSecurityException:HQ119032:User:null在地址{2}上没有权限= SEND的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-15 22:59