为什么在 activemq createConnection 中不考虑用户名和密码

Why username and password are not respected in activemq createConnection

我在 activemq 中创建了一个唯一的代理,我正在使用以下代码来生成和使用消息。我拿了这段代码 from here.

public boolean runExample() throws Exception {
        Connection connection = null;
        InitialContext initialContext = null;
        try {
            Properties properties = new Properties();
            properties.put("java.naming.factory.initial", "org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory");
            properties.put("connectionFactory.ConnectionFactory", "tcp://localhost:61616");
            properties.put("queue.queue/exampleQueue", "exampleQueue");
            
            initialContext = new InitialContext(properties);
            
            Queue queue = (Queue) initialContext.lookup("queue/exampleQueue");
            
            ConnectionFactory connectionFactory = (ConnectionFactory) initialContext.lookup("ConnectionFactory");
            connection = connectionFactory.createConnection("admin", "admin");//brokerone
            Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            MessageProducer producer = session.createProducer(queue);
            TextMessage message = session.createTextMessage("This is a text message");

            System.out.println("Sent message: " + message.getText());
            producer.send(message);
            MessageConsumer messageConsumer = session.createConsumer(queue);
            connection.start();
            TextMessage messageReceived = (TextMessage) messageConsumer.receive(5000);
            System.out.println("Received message: " + messageReceived.getText());

            return true;
        } finally {
            if (initialContext != null) {
                initialContext.close();
            }
            if (connection != null) {
                connection.close();
            }
        }
    }

现在,在创建连接时,如果我在 connectionFactory.createConnection 方法中放入任何随机密码字符串,它仍然会创建连接,我可以在代理控制台中看到生成的消息。我查阅了 documentation and here 以获得更多解释,但它也说在 createConnection 方法中传递的字符串是用户名和密码。

那么现在,我的问题是,在创建连接时用户名和密码未被使用的目的是什么?

编辑 1:

broker.xml(删除批量注释行后)

<configuration xmlns="urn:activemq"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:xi="http://www.w3.org/2001/XInclude"
               xsi:schemaLocation="urn:activemq /schema/artemis-configuration.xsd">

   <core xmlns="urn:activemq:core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="urn:activemq:core ">

      <name>0.0.0.0</name>
      <persistence-enabled>true</persistence-enabled>    
      <journal-type>NIO</journal-type>
      <paging-directory>data/paging</paging-directory>
      <bindings-directory>data/bindings</bindings-directory>
      <journal-directory>data/journal</journal-directory>
      <large-messages-directory>data/large-messages</large-messages-directory>
      <journal-datasync>true</journal-datasync>
      <journal-min-files>2</journal-min-files>
      <journal-pool-files>10</journal-pool-files>
      <journal-device-block-size>4096</journal-device-block-size>
      <journal-file-size>10M</journal-file-size>
      <journal-buffer-timeout>1192000</journal-buffer-timeout>
      <!--        When using ASYNCIO, this will determine the writing queue depth for libaio.       -->
      <journal-max-io>1</journal-max-io>     
      <!-- how often we are looking for how many bytes are being used on the disk in ms -->
      <disk-scan-period>5000</disk-scan-period>

      <!-- once the disk hits this limit the system will block, or close the connection in certain protocols that won't support flow control. -->
      <max-disk-usage>90</max-disk-usage>

      <!-- should the broker detect dead locks and other issues -->
      <critical-analyzer>true</critical-analyzer>
      <critical-analyzer-timeout>120000</critical-analyzer-timeout>
      <critical-analyzer-check-period>60000</critical-analyzer-check-period>
      <critical-analyzer-policy>HALT</critical-analyzer-policy>      
      <page-sync-timeout>1192000</page-sync-timeout>

      <acceptors>
         <!-- Acceptor for every supported protocol -->
         <acceptor name="artemis">tcp://0.0.0.0:61616?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;amqpMinLargeMessageSize=102400;protocols=CORE,AMQP,STOMP,HORNETQ,MQTT,OPENWIRE;useEpoll=true;amqpCredits=1000;amqpLowCredits=300;amqpDuplicateDetection=true</acceptor>
         <!-- AMQP Acceptor.  Listens on default AMQP port for AMQP traffic.-->
         <acceptor name="amqp">tcp://0.0.0.0:5672?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=AMQP;useEpoll=true;amqpCredits=1000;amqpLowCredits=300;amqpMinLargeMessageSize=102400;amqpDuplicateDetection=true</acceptor>
         <!-- STOMP Acceptor. -->
         <acceptor name="stomp">tcp://0.0.0.0:61613?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=STOMP;useEpoll=true</acceptor>
         <!-- HornetQ Compatibility Acceptor.  Enables HornetQ Core and STOMP for legacy HornetQ clients. -->
         <acceptor name="hornetq">tcp://0.0.0.0:5445?anycastPrefix=jms.queue.;multicastPrefix=jms.topic.;protocols=HORNETQ,STOMP;useEpoll=true</acceptor>
         <!-- MQTT Acceptor -->
         <acceptor name="mqtt">tcp://0.0.0.0:1883?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=MQTT;useEpoll=true</acceptor>
      </acceptors>
      
      <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-settings>

      <address-settings>
         <!-- if you define auto-create on certain queues, management has to be auto-create -->
         <address-setting match="activemq.management#">
            <dead-letter-address>DLQ</dead-letter-address>
            <expiry-address>ExpiryQueue</expiry-address>
            <redelivery-delay>0</redelivery-delay>
            <!-- with -1 only the global-max-size is in use for limiting -->
            <max-size-bytes>-1</max-size-bytes>
            <message-counter-history-day-limit>10</message-counter-history-day-limit>
            <address-full-policy>PAGE</address-full-policy>
            <auto-create-queues>true</auto-create-queues>
            <auto-create-addresses>true</auto-create-addresses>
            <auto-create-jms-queues>true</auto-create-jms-queues>
            <auto-create-jms-topics>true</auto-create-jms-topics>
         </address-setting>
         <!--default for catch all-->
         <address-setting match="#">
            <dead-letter-address>DLQ</dead-letter-address>
            <expiry-address>ExpiryQueue</expiry-address>
            <redelivery-delay>0</redelivery-delay>
            <!-- with -1 only the global-max-size is in use for limiting -->
            <max-size-bytes>-1</max-size-bytes>
            <message-counter-history-day-limit>10</message-counter-history-day-limit>
            <address-full-policy>PAGE</address-full-policy>
            <auto-create-queues>true</auto-create-queues>
            <auto-create-addresses>true</auto-create-addresses>
            <auto-create-jms-queues>true</auto-create-jms-queues>
            <auto-create-jms-topics>true</auto-create-jms-topics>
         </address-setting>
      </address-settings>

      <addresses>
         <address name="DLQ">
            <anycast>
               <queue name="DLQ" />
            </anycast>
         </address>
         <address name="ExpiryQueue">
            <anycast>
               <queue name="ExpiryQueue" />
            </anycast>
         </address>

      </addresses>
   </core>
</configuration>

bootstrap.xml

<broker xmlns="http://activemq.org/schema">

   <jaas-security domain="activemq"/>

   <!-- artemis.URI.instance is parsed from artemis.instance by the CLI startup.
        This is to avoid situations where you could have spaces or special characters on this URI -->
   <server configuration="file:/C:/dev/artemis/apache-artemis-2.13.0/bin/brokerone/etc//broker.xml"/>

   <!-- The web server is only bound to localhost by default -->
   <web bind="http://localhost:8161" path="web">
       <app url="activemq-branding" war="activemq-branding.war"/>
       <app url="artemis-plugin" war="artemis-plugin.war"/>
       <app url="console" war="console.war"/>
   </web>


</broker>

login.config

activemq {
   org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule sufficient
       debug=false
       reload=true
       org.apache.activemq.jaas.properties.user="artemis-users.properties"
       org.apache.activemq.jaas.properties.role="artemis-roles.properties";

   org.apache.activemq.artemis.spi.core.security.jaas.GuestLoginModule sufficient
       debug=false
       org.apache.activemq.jaas.guest.user="admin"
       org.apache.activemq.jaas.guest.role="amq";
};

当客户端创建会话时,代理会尝试使用传递的用户名和密码对客户端进行身份验证。

您的 login.config 文件包含 2 个登录模块 PropertiesLoginModuleGuestLoginModule。如果 PropertiesLoginModule 由于 username/password 错误导致登录失败,则 GuestLoginModule 将使用 login.config 中定义的角色 amq 登录用户 admin文件。

创建连接时使用的用户名和密码。您观察到的行为与您传递的凭据无关,这取决于您的配置。您已经专门配置代理以允许“访客”用户(即凭据错误或没有凭据的用户)通过您的 login.config:

   org.apache.activemq.artemis.spi.core.security.jaas.GuestLoginModule sufficient
       debug=false
       org.apache.activemq.jaas.guest.user="admin"
       org.apache.activemq.jaas.guest.role="amq";

您可以在 the documentation 中阅读有关此登录模块的更多信息。

如果您不想允许“访客”用户,那么您可以将 login.config 更改为:

activemq {
   org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule required
       debug=false
       reload=true
       org.apache.activemq.jaas.properties.user="artemis-users.properties"
       org.apache.activemq.jaas.properties.role="artemis-roles.properties";
};

考虑到标准安装 (5.16.3),当您解压缩存档时,您会发现一个 conf 文件夹。

从那里作为 Docker 容器的基础开始,我很难配置 ActiveMQ 安全性,因为涉及多个文件,其中一部分没有按预期工作。 我假设我没有正确配置所有内容,因为更改 login.config 基本上没有效果。

我让安全工作的唯一方法是

  • 更改 jetty-realm.properties 以访问管理网页
  • 更改 activemq.xml 代理安全配置

(已找到 activemq.xml 的解决方案 here

经纪人安全的示例配置片段:

    <broker xmlns="http://activemq.apache.org/schema/core" brokerName="localhost" dataDirectory="${activemq.data}">
    
    <plugins>
        <simpleAuthenticationPlugin anonymousAccessAllowed="false">
            <users>
                <authenticationUser username="admin" password="admin1234!" groups="admins,senders,receivers"/>
                <!---<authenticationUser username="user" password="password" groups="users"/>
                <authenticationUser username="guest" password="password" groups="guests"/>-->
            </users>
        </simpleAuthenticationPlugin>
        <authorizationPlugin>
            <map>
                <authorizationMap>
                    <authorizationEntries>
                        <authorizationEntry queue=">" write="senders" read="receivers" admin="admins" />
                    <authorizationEntry topic="ActiveMQ.Advisory.>" write="senders" read="receivers" admin="admins,senders,receivers" />
                    </authorizationEntries>
                </authorizationMap>
            </map>
        </authorizationPlugin>
    </plugins>
    .
    .

这最终启用了队列访问的安全性。