【问题标题】:javax.jms.JMSSecurityException: Unable to validate user: nulljavax.jms.JMSSecurityException:无法验证用户:null
【发布时间】:2012-03-21 09:05:33
【问题描述】:

环境:

Jboss 7.1.0 操作系统窗口

我正在尝试一个简单的测试来尝试使用 Jboss 和内置 HornetQ JMS 提供程序的 JMS。在玩了很多之后,我设法用这个配置得到了回应

        final Properties env = new Properties();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
        env.put(Context.PROVIDER_URL, "remote://localhost:4447");
        env.put(Context.SECURITY_PRINCIPAL, "appuser2");
        env.put(Context.SECURITY_CREDENTIALS, "s3cr3t");        

但问题是,当我运行它时,我收到以下错误:

javax.jms.JMSSecurityException: Unable to validate user: null
    at org.hornetq.core.protocol.core.impl.ChannelImpl.sendBlocking(ChannelImpl.java:286)
    at org.hornetq.core.client.impl.ClientSessionFactoryImpl.createSessionInternal(ClientSessionFactoryImpl.java:695)
    at org.hornetq.core.client.impl.ClientSessionFactoryImpl.createSession(ClientSessionFactoryImpl.java:264)
    at org.hornetq.jms.client.HornetQConnection.authorize(HornetQConnection.java:589)
    at org.hornetq.jms.client.HornetQConnectionFactory.createConnectionInternal(HornetQConnectionFactory.java:694)
    at org.hornetq.jms.client.HornetQConnectionFactory.createConnection(HornetQConnectionFactory.java:121)
    at org.hornetq.jms.client.HornetQConnectionFactory.createConnection(HornetQConnectionFactory.java:116)
    at com.jms.client.ConsoleClient.runExample(ConsoleClient.java:51)
    at com.jms.client.ConsoleClient.main(ConsoleClient.java:20)
Caused by: HornetQException[errorCode=105 message=Unable to validate user: null]
    ... 9 more

我一直在 Google 上四处寻找,每个示例似乎都指向如何使用 HornetQ 作为独立服务器来配置安全设置。我不知道如何在 Jboss 上配置用户以及我是否需要。

有什么想法吗?

【问题讨论】:

  • 我记得前段时间在使用 JBoss 5.1.0GA 时遇到过这个问题。我记得通过在 hornetq.sar/hornetq-users.xml 中添加正确的用户/每个队列来修复它。我不知道 hornetQ 在 JBoss 7 中是如何使用的,但也许这个提示会为您指明正确的方向。

标签: java jboss jms jboss7.x hornetq


【解决方案1】:

我同意 Sergiu 的观点,并且可以添加队列,无需用户名和密码即可设置。

【讨论】:

    【解决方案2】:

    您似乎创建了一个QueueConnection,其用户名和密码如下:

    QueueConnection qcon = qconFactory.createQueueConnection("appuser2","s3cr3t");
    

    如果你不这样做,你会得到这个错误

    无法验证用户:null。

    如果您不想使用用户名和密码,您可以使用值false 设置安全启用,如下所示:

    <subsystem xmlns="urn:jboss:domain:messaging:1.1">
         <hornetq-server>
             <security-enabled>false</security-enabled>
             ......
         </hornetq-server>
    </subsystem>
    

    然后你可以创建一个没有用户名和密码的QueueConnection,如下所示:

    QueueConnection qcon = qconFactory.createQueueConnection();
    

    【讨论】:

      【解决方案3】:

      它对我有用。我刚刚在standalone-full.xml 中添加了以下内容:

                  <security-enabled>false</security-enabled> 
      

      【讨论】:

        【解决方案4】:

        检查您的standalone-full.xml。如果urn:jboss:domain:messaging-activemq:1.0 中的角色配置如下所示:

        <security-setting name="#">
           <role name="guest" send="true" consume="true" create-non-durable-queue="true" delete-non-durable-queue="true"/>
        </security-setting>
        

        那么,你必须:

        1. 创建访客用户(确保将角色guest 设置为用户);
        2. 如下设置初始上下文:
        Properties props = new Properties();
        props.put(Context.PROVIDER_URL, "http-remoting://localhost:8080");
        props.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
        props.put(Context.SECURITY_PRINCIPAL, "username");
        props.put(Context.SECURITY_CREDENTIALS, "password");
        InitialContext ctx = new InitialContext(props);
        
        1. 如下创建上下文:
        ConnectionFactory cf = (ConnectionFactory) ctx.lookup("jms/RemoteConnectionFactory");
        Queue queue = (Queue) ctx.lookup("jms/queue/queueName");
        JMSContext context = cf.createContext("username", "password");
        

        【讨论】:

          【解决方案5】:

          使用 from cli 将队列添加到 jboss:

          jms-topic add --topic-address=testTopic -–entries=topic/test,java:jboss/exported/jms/topic/test
          

          添加用户如下:

          add-user.bat -a -u mquser -p mqpassword -g guest
          

          消费者将代码粘贴到main方法中:

          Properties properties = new Properties();
          properties.put(Context.INITIAL_CONTEXT_FACTORY,"org.wildfly.naming.client.WildFlyInitialContextFactory");
          properties.put(Context.PROVIDER_URL, "http-remoting://localhost:8080");
          properties.put("jboss.naming.client.ejb.context", true);
          properties.put("java.naming.security.principal", "mquser");
          properties.put("java.naming.security.credentials", "mqpassword");
          properties.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
          
          QueueConnection cnn = null;
          QueueSender sender = null;
          QueueSession session = null;
          InitialContext ctx = new InitialContext(properties);
          Queue queue = (Queue) ctx.lookup("jms/queue/tests");
          QueueConnectionFactory factory = (QueueConnectionFactory) ctx.lookup("jms/RemoteConnectionFactory");
          cnn =  factory.createQueueConnection("mquser", "mqpassword");
          cnn.start();
          
          session = cnn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
          TextMessage msg = session.createTextMessage("Hello World");
          sender = session.createSender(queue);
          sender.send(msg);
          
          System.out.println("Message sent successfully to remote queue.");
          
          @MessageDriven(name = "ExampleMDB", activationConfig = {
              @ActivationConfigProperty(propertyName = "destination", propertyValue = "testQueues"), @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
              @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge")
          public class ExampleMDB implements MessageListener {
          
              /**
               * Default constructor. 
               */
              public ExampleMDB() {
                  // TODO Auto-generated constructor stub
              }
          
          
              @Override
              public void onMessage(Message arg0) {
                  System.out.println("----------------");
                  try {
                      System.out.println("Received message" + ((TextMessage)arg0).getText());
                  } catch (JMSException e) {
                      // TODO Auto-generated catch block
                      e.printStackTrace();
                  }
                  System.out.println("----------------");
          
              }
          
          }
          

          【讨论】:

            【解决方案6】:

            如果您使用的是 WildFly 10+(我使用的是 WildFly 18),您必须通过添加以下内容来禁用安全性:

            <security enabled="false"/>
            

            在你的standalone-full.xml(wildFly目录/standalone/configuration)里面:

                <subsystem xmlns="urn:jboss:domain:messaging-activemq:8.0">
            

            <server name="default">
            

            类似的东西:

            <subsystem xmlns="urn:jboss:domain:messaging-activemq:8.0">
                            <server name="default">
            			
                            <!-- Disable security with the following row, otherwise of course it will give error without authentication in java -->
                            <security enabled="false"/>
            				
                            <statistics enabled="${wildfly.messaging-activemq.statistics-enabled:${wildfly.statistics-enabled:false}}"/>
                            <security-setting name="#">
                                <role name="guest" send="true" consume="true" create-non-durable-queue="true" delete-non-durable-queue="true"/>
                            </security-setting>
                            <address-setting name="#" dead-letter-address="jms.queue.DLQ" expiry-address="jms.queue.ExpiryQueue" max-size-bytes="10485760" page-size-bytes="2097152" message-counter-history-day-limit="10"/>
                            <http-connector name="http-connector" socket-binding="http" endpoint="http-acceptor"/>
                            <http-connector name="http-connector-throughput" socket-binding="http" endpoint="http-acceptor-throughput">
                                <param name="batch-delay" value="50"/>
                            </http-connector>
                            <in-vm-connector name="in-vm" server-id="0">
                                <param name="buffer-pooling" value="false"/>
                            </in-vm-connector>
                            <http-acceptor name="http-acceptor" http-listener="default"/>
                            <http-acceptor name="http-acceptor-throughput" http-listener="default">
                                <param name="batch-delay" value="50"/>
                                <param name="direct-deliver" value="false"/>
                            </http-acceptor>
                            <in-vm-acceptor name="in-vm" server-id="0">
                                <param name="buffer-pooling" value="false"/>
                            </in-vm-acceptor>
                            <jms-queue name="ExpiryQueue" entries="java:/jms/queue/ExpiryQueue"/>
                            <jms-queue name="DLQ" entries="java:/jms/queue/DLQ"/>
                            <!-- Adding a new queue -->
            		<jms-queue name="ShippingQueue" entries="java:jboss/exported/jms/queue/ShippingQueue"/>
            				
            
                            <connection-factory name="InVmConnectionFactory" entries="java:/ConnectionFactory" connectors="in-vm"/>
                            <connection-factory name="RemoteConnectionFactory" entries="java:jboss/exported/jms/RemoteConnectionFactory" connectors="http-connector"/>
                            <pooled-connection-factory name="activemq-ra" entries="java:/JmsXA java:jboss/DefaultJMSConnectionFactory" connectors="in-vm" transaction="xa"/>
            
                        </server>
                    </subsystem>

            检查: https://developer.jboss.org/thread/271457

            【讨论】:

              【解决方案7】:

              如果有人使用 JBoss EAP 7.2 版本,那么这里就是解决方案。

              如果您不想通过添加标签&lt;security enabled="false"/&gt;来禁用安全性,并希望使用用户名和密码进行身份验证,请按照以下步骤操作。

              1. 无论您在代码中编写了什么用户名(例如“jmsuser”)和密码(例如“pass”),都需要首先在 JBoss 中创建确切的用户(“jmsuser”)。请使用 bin 文件夹下的 add-user 实用程序,将用户添加为应用程序用户,并在出现提示时将其分配给“guest”角色。

              1. 经过上述步骤,用户名和角色详细信息可以在application-role.properties和application-users.properties文件\standalone\configuration路径中找到。

              2. 重启 JBoss 服务器。

              3. 假设您使用的是 JMS 2.0 规范,然后像下面这样创建 JMSContext。

              JMSContext jmsCtx = connectionFactory.createContext("jmsuser", "pass");
              
              1. 立即运行代码,您将不会再遇到此错误。

              【讨论】:

                猜你喜欢
                • 2011-02-12
                • 2016-11-14
                • 1970-01-01
                • 2019-08-20
                • 2011-08-03
                • 2017-02-10
                • 2015-10-27
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多