You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by cl...@apache.org on 2022/12/15 16:51:46 UTC

[activemq-artemis] branch main updated (1de10671f8 -> 635ca1fbd6)

This is an automated email from the ASF dual-hosted git repository.

clebertsuconic pushed a change to branch main
in repository https://gitbox.apache.org/repos/asf/activemq-artemis.git


    from 1de10671f8 ARTEMIS-3609 Do not use netty thread for thread completion listener
     new fa8d487ff2 ARTEMIS-3866 Authorize management message sending using context subject
     new 635ca1fbd6 ARTEMIS-3866 Move user preferences to the send message view

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../src/main/webapp/plugin/js/artemisPlugin.js     |  7 --
 .../plugin/js/components/addressSendMessage.js     | 42 ++++++++---
 .../webapp/plugin/js/components/preferences.js     | 26 -------
 .../webapp/plugin/js/components/sendMessage.js     | 42 ++++++++---
 .../plugin/js/services/sendMessageService.js       | 18 ++---
 .../core/security/impl/SecurityStoreImpl.java      | 21 ++++++
 .../artemis/tests/smoke/console/QueuesTest.java    | 60 ++++++++++++++++
 .../tests/smoke/console/pages/QueuePage.java       | 22 ++++++
 .../tests/smoke/console/pages/SendMessagePage.java | 74 +++++++++++++++++++
 .../artemis/tests/smoke/jmxrbac/JmxRBACTest.java   | 82 ++++++++++++++++++++--
 10 files changed, 326 insertions(+), 68 deletions(-)
 create mode 100644 tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/console/pages/SendMessagePage.java


[activemq-artemis] 01/02: ARTEMIS-3866 Authorize management message sending using context subject

Posted by cl...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

clebertsuconic pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/activemq-artemis.git

commit fa8d487ff2cef2c5fc0e5541a4b554ae8c54cf0d
Author: Domenico Francesco Bruscino <br...@apache.org>
AuthorDate: Mon Jun 20 18:51:55 2022 +0200

    ARTEMIS-3866 Authorize management message sending using context subject
---
 .../core/security/impl/SecurityStoreImpl.java      | 21 ++++++
 .../artemis/tests/smoke/jmxrbac/JmxRBACTest.java   | 82 ++++++++++++++++++++--
 2 files changed, 99 insertions(+), 4 deletions(-)

diff --git a/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/impl/SecurityStoreImpl.java b/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/impl/SecurityStoreImpl.java
index a834779c1f..e364723121 100644
--- a/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/impl/SecurityStoreImpl.java
+++ b/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/impl/SecurityStoreImpl.java
@@ -17,6 +17,8 @@
 package org.apache.activemq.artemis.core.security.impl;
 
 import javax.security.auth.Subject;
+import java.security.AccessControlContext;
+import java.security.AccessController;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
@@ -26,6 +28,7 @@ import org.apache.activemq.artemis.api.core.Pair;
 import org.apache.activemq.artemis.api.core.SimpleString;
 import org.apache.activemq.artemis.api.core.management.CoreNotificationType;
 import org.apache.activemq.artemis.api.core.management.ManagementHelper;
+import org.apache.activemq.artemis.core.management.impl.ManagementRemotingConnection;
 import org.apache.activemq.artemis.core.remoting.CertificateUtil;
 import org.apache.activemq.artemis.core.security.CheckType;
 import org.apache.activemq.artemis.core.security.Role;
@@ -168,6 +171,16 @@ public class SecurityStoreImpl implements SecurityStore, HierarchicalRepositoryC
                subject = cacheEntry.getB();
                validatedUser = getUserFromSubject(subject);
             }
+         } else {
+            if (user == null && password == null && connection instanceof ManagementRemotingConnection) {
+               AccessControlContext accessControlContext = AccessController.getContext();
+               if (accessControlContext != null) {
+                  check = false;
+                  userIsValid = true;
+                  subject = Subject.getSubject(accessControlContext);
+                  validatedUser = getUserFromSubject(subject);
+               }
+            }
          }
          if (check) {
             if (securityManager instanceof ActiveMQSecurityManager5) {
@@ -382,6 +395,14 @@ public class SecurityStoreImpl implements SecurityStore, HierarchicalRepositoryC
     */
    private Subject getSubjectForAuthorization(SecurityAuth auth, ActiveMQSecurityManager5 securityManager) {
       Pair<Boolean, Subject> cached = authenticationCache.getIfPresent(createAuthenticationCacheKey(auth.getUsername(), auth.getPassword(), auth.getRemotingConnection()));
+
+      if (cached == null && auth.getUsername() == null && auth.getPassword() == null && auth.getRemotingConnection() instanceof ManagementRemotingConnection) {
+         AccessControlContext accessControlContext = AccessController.getContext();
+         if (accessControlContext != null) {
+            cached = new Pair<>(true, Subject.getSubject(accessControlContext));
+         }
+      }
+
       /*
        * We don't need to worry about the cached boolean being false as users always have to
        * successfully authenticate before requesting authorization for anything.
diff --git a/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/jmxrbac/JmxRBACTest.java b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/jmxrbac/JmxRBACTest.java
index bc0e1517a4..edd31ed7ba 100644
--- a/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/jmxrbac/JmxRBACTest.java
+++ b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/jmxrbac/JmxRBACTest.java
@@ -26,7 +26,11 @@ import javax.management.remote.JMXServiceURL;
 import java.util.Collections;
 
 import org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration;
+import org.apache.activemq.artemis.api.core.Message;
+import org.apache.activemq.artemis.api.core.RoutingType;
+import org.apache.activemq.artemis.api.core.SimpleString;
 import org.apache.activemq.artemis.api.core.management.ActiveMQServerControl;
+import org.apache.activemq.artemis.api.core.management.AddressControl;
 import org.apache.activemq.artemis.api.core.management.ObjectNameBuilder;
 import org.apache.activemq.artemis.tests.smoke.common.SmokeTestBase;
 import org.apache.activemq.artemis.util.ServerUtil;
@@ -40,11 +44,14 @@ public class JmxRBACTest extends SmokeTestBase {
    private static final String JMX_SERVER_HOSTNAME = "localhost";
    private static final int JMX_SERVER_PORT = 10099;
 
+   public static final String BROKER_NAME = "0.0.0.0";
+
    public static final String SERVER_NAME_0 = "jmx-rbac";
 
    public static final String SERVER_ADMIN = "admin";
    public static final String SERVER_USER = "user";
 
+   public static final String ADDRESS_TEST = "TEST";
 
    @Before
    public void before() throws Exception {
@@ -79,8 +86,7 @@ public class JmxRBACTest extends SmokeTestBase {
       try {
          //Create an user.
          MBeanServerConnection mBeanServerConnection = jmxConnector.getMBeanServerConnection();
-         String brokerName = "0.0.0.0";  // configured e.g. in broker.xml <broker-name> element
-         ObjectNameBuilder objectNameBuilder = ObjectNameBuilder.create(ActiveMQDefaultConfiguration.getDefaultJmxDomain(), brokerName, true);
+         ObjectNameBuilder objectNameBuilder = ObjectNameBuilder.create(ActiveMQDefaultConfiguration.getDefaultJmxDomain(), BROKER_NAME, true);
          ActiveMQServerControl activeMQServerControl = MBeanServerInvocationHandler.newProxyInstance(mBeanServerConnection, objectNameBuilder.getActiveMQServerObjectName(), ActiveMQServerControl.class, false);
          ObjectName memoryObjectName = new ObjectName("java.lang:type=Memory");
 
@@ -116,8 +122,7 @@ public class JmxRBACTest extends SmokeTestBase {
 
       try {
          MBeanServerConnection mBeanServerConnection = jmxConnector.getMBeanServerConnection();
-         String brokerName = "0.0.0.0";  // configured e.g. in broker.xml <broker-name> element
-         ObjectNameBuilder objectNameBuilder = ObjectNameBuilder.create(ActiveMQDefaultConfiguration.getDefaultJmxDomain(), brokerName, true);
+         ObjectNameBuilder objectNameBuilder = ObjectNameBuilder.create(ActiveMQDefaultConfiguration.getDefaultJmxDomain(), BROKER_NAME, true);
          ActiveMQServerControl activeMQServerControl = MBeanServerInvocationHandler.newProxyInstance(mBeanServerConnection, objectNameBuilder.getActiveMQServerObjectName(), ActiveMQServerControl.class, false);
          ObjectName memoryObjectName = new ObjectName("java.lang:type=Memory");
 
@@ -133,4 +138,73 @@ public class JmxRBACTest extends SmokeTestBase {
          jmxConnector.close();
       }
    }
+
+   @Test
+   public void testSendMessageWithoutUserAndPassword() throws Exception {
+      // Without this, the RMI server would bind to the default interface IP (the user's local IP mostly)
+      System.setProperty("java.rmi.server.hostname", JMX_SERVER_HOSTNAME);
+
+      // I don't specify both ports here manually on purpose. See actual RMI registry connection port extraction below.
+      String urlString = "service:jmx:rmi:///jndi/rmi://" + JMX_SERVER_HOSTNAME + ":" + JMX_SERVER_PORT + "/jmxrmi";
+
+      JMXServiceURL url = new JMXServiceURL(urlString);
+      JMXConnector jmxConnector;
+
+      try {
+         //Connect using the admin.
+         jmxConnector = JMXConnectorFactory.connect(url, Collections.singletonMap(
+            "jmx.remote.credentials", new String[] {SERVER_ADMIN, SERVER_ADMIN}));
+         System.out.println("Successfully connected to: " + urlString);
+      } catch (Exception e) {
+         jmxConnector = null;
+         e.printStackTrace();
+         Assert.fail(e.getMessage());
+      }
+
+      try {
+         MBeanServerConnection mBeanServerConnection = jmxConnector.getMBeanServerConnection();
+         ObjectNameBuilder objectNameBuilder = ObjectNameBuilder.create(ActiveMQDefaultConfiguration.getDefaultJmxDomain(), BROKER_NAME, true);
+         ActiveMQServerControl activeMQServerControl = MBeanServerInvocationHandler.newProxyInstance(mBeanServerConnection, objectNameBuilder.getActiveMQServerObjectName(), ActiveMQServerControl.class, false);
+
+         activeMQServerControl.createAddress(ADDRESS_TEST, RoutingType.MULTICAST.name());
+         AddressControl testAddressControl = MBeanServerInvocationHandler.newProxyInstance(mBeanServerConnection, objectNameBuilder.getAddressObjectName(SimpleString.toSimpleString(ADDRESS_TEST)), AddressControl.class, false);
+
+         testAddressControl.sendMessage(null, Message.TEXT_TYPE, ADDRESS_TEST, true, null, null);
+
+
+         try {
+            activeMQServerControl.removeUser(SERVER_USER);
+         } catch (Exception ignore) {
+         }
+         activeMQServerControl.addUser(SERVER_USER, SERVER_USER, "amq-user", true);
+      } finally {
+         jmxConnector.close();
+      }
+
+      try {
+         //Connect using an user.
+         jmxConnector = JMXConnectorFactory.connect(url, Collections.singletonMap(
+            "jmx.remote.credentials", new String[] {SERVER_USER, SERVER_USER}));
+         System.out.println("Successfully connected to: " + urlString);
+      } catch (Exception e) {
+         jmxConnector = null;
+         e.printStackTrace();
+         Assert.fail(e.getMessage());
+      }
+
+      try {
+         MBeanServerConnection mBeanServerConnection = jmxConnector.getMBeanServerConnection();
+         ObjectNameBuilder objectNameBuilder = ObjectNameBuilder.create(ActiveMQDefaultConfiguration.getDefaultJmxDomain(), BROKER_NAME, true);
+         AddressControl testAddressControl = MBeanServerInvocationHandler.newProxyInstance(mBeanServerConnection, objectNameBuilder.getAddressObjectName(SimpleString.toSimpleString("TEST")), AddressControl.class, false);
+
+         try {
+            testAddressControl.sendMessage(null, Message.TEXT_TYPE, ADDRESS_TEST, true, null, null);
+            Assert.fail(SERVER_USER + " should not have permissions to send a message to the address " + ADDRESS_TEST);
+         } catch (Exception e) {
+            Assert.assertEquals(SecurityException.class, e.getClass());
+         }
+      } finally {
+         jmxConnector.close();
+      }
+   }
 }


[activemq-artemis] 02/02: ARTEMIS-3866 Move user preferences to the send message view

Posted by cl...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

clebertsuconic pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/activemq-artemis.git

commit 635ca1fbd638d9ff8845777772bfd7d5c66140ee
Author: Domenico Francesco Bruscino <br...@apache.org>
AuthorDate: Tue Jun 21 13:43:45 2022 +0200

    ARTEMIS-3866 Move user preferences to the send message view
---
 .../src/main/webapp/plugin/js/artemisPlugin.js     |  7 --
 .../plugin/js/components/addressSendMessage.js     | 42 +++++++++---
 .../webapp/plugin/js/components/preferences.js     | 26 --------
 .../webapp/plugin/js/components/sendMessage.js     | 42 +++++++++---
 .../plugin/js/services/sendMessageService.js       | 18 ++----
 .../artemis/tests/smoke/console/QueuesTest.java    | 60 ++++++++++++++++++
 .../tests/smoke/console/pages/QueuePage.java       | 22 +++++++
 .../tests/smoke/console/pages/SendMessagePage.java | 74 ++++++++++++++++++++++
 8 files changed, 227 insertions(+), 64 deletions(-)

diff --git a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/artemisPlugin.js b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/artemisPlugin.js
index 9e7d49949a..f51f4ba1ed 100644
--- a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/artemisPlugin.js
+++ b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/artemisPlugin.js
@@ -63,13 +63,6 @@ var Artemis = (function (Artemis) {
             template: '<artemis></artemis>',
             isValid: function () { return workspace.treeContainsDomainAndProperties(artemisJmxDomain); }
         });
-
-        // clean up local storage upon logout
-        preLogoutTasks.addTask('CleanupArtemisCredentials', function () {
-            Artemis.log.debug("Clean up Artemis credentials in local storage");
-            localStorage.removeItem('artemisUserName');
-            localStorage.removeItem('artemisPassword');
-        });
     }
     configurePlugin.$inject = ['mainNavService', 'workspace', 'helpRegistry', 'preferencesRegistry', 'localStorage', 'preLogoutTasks', 'documentBase', '$templateCache'];
 
diff --git a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/addressSendMessage.js b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/addressSendMessage.js
index 974cb5684c..50283fe6ad 100644
--- a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/addressSendMessage.js
+++ b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/addressSendMessage.js
@@ -28,13 +28,6 @@ var Artemis;
                 </button>
             </h1>
 
-            <div class="alert alert-warning" ng-show="$ctrl.message.noCredentials">
-                <span class="pficon pficon-warning-triangle-o"></span>
-                <strong>No credentials set for endpoint!</strong>
-                Please set your username and password in the
-                <a href="#" class="alert-link" ng-click="$ctrl.message.openPrefs()">Preferences</a> page.
-            </div>
-
             <div class="row artemis-message-configuration">
 
                 <div class="col-sm-12">
@@ -57,6 +50,31 @@ var Artemis;
                                 <span class="pficon pficon-info"></span>
                             </button>
                         </div>
+                        <div class="form-group">
+                            <label>Use current logon user </label>
+                            <input id="useCurrentLogonUser" type="checkbox" ng-model="$ctrl.message.noCredentials" value="true">
+                            <button type="button" class="btn btn-link jvm-title-popover"
+                                      uib-popover-template="'use-current-logon-user-credentials-id-info.html'" popover-placement="bottom-left"
+                                      popover-title="Use current logon user" popover-trigger="'mouseenter'">
+                                <span class="pficon pficon-info"></span>
+                            </button>
+                        </div>
+                        <div class="form-group" ng-hide="$ctrl.message.noCredentials">
+                            <label class="col-sm-2 control-label" for="name-markup">Username</label>
+
+                            <div class="col-sm-10">
+                                <input id="name-markup" class="form-control" type="text" maxlength="300"
+                                       name="username" ng-model="$ctrl.message.username" placeholder="username"/>
+                            </div>
+                        </div>
+                        <div class="form-group" ng-hide="$ctrl.message.noCredentials">
+                            <label class="col-sm-2 control-label" for="name-markup">Password</label>
+
+                            <div class="col-sm-10">
+                                <input id="name-markup" class="form-control" type="password" maxlength="300"
+                                       name="password" ng-model="$ctrl.message.password" placeholder="password"/>
+                            </div>
+                        </div>
                     </form>
                 </div>
             </div>
@@ -110,8 +128,7 @@ var Artemis;
                 <p>
                     This page allows you to send a message to the chosen address. The message will be of type <code>text</code>
                     message and it will be possible to add headers to the message. The sending of the message will be authenticated
-                    using the username and password set in <code>preferences</code>, if this is not set then these will
-                    be null.
+                    using the current logon user, unselect <code>use current logon user</code> to use a different user.
                 </p>
             </div>
             </script>
@@ -131,6 +148,13 @@ var Artemis;
                 </p>
             </div>
             </script>
+            <script type="text/ng-template" id="use-current-logon-user-credentials-id-info.html">
+            <div>
+                <p>
+                    This option allows a user to send messages with the permissions of the user's current logon, disable it to send messages with different permissions than the user's current logon provides.
+                </p>
+            </div>
+            </script>
         `,
         controller: AddressSendMessageController
     })
diff --git a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/preferences.js b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/preferences.js
index 2dfb628336..5bfd208984 100644
--- a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/preferences.js
+++ b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/preferences.js
@@ -19,12 +19,6 @@ var Artemis;
     Artemis._module
     .controller("Artemis.PreferencesController", ["$scope", "localStorage", "userDetails", "$rootScope", function ($scope, localStorage, userDetails, $rootScope) {
           Core.initPreferenceScope($scope, localStorage, {
-             'artemisUserName': {
-                 'value': userDetails.username ? userDetails.username : ""
-             },
-             'artemisPassword': {
-                'value': userDetails.password ? userDetails.password : ""
-             },
              'artemisDLQ': {
                 'value': "^DLQ$"
              },
@@ -49,26 +43,6 @@ var Artemis;
         });
         $templateCache.put(path,
             `<form class="form-horizontal artemis-preferences-form" ng-controller="Artemis.PreferencesController">
-                  <div class="form-group">
-                    <label class="col-md-2 control-label" for="artemisUserName">
-                      Artemis user name
-                      <span class="pficon pficon-info" data-toggle="tooltip" data-placement="top" title="The user name to be used when connecting to the broker"></span>
-                    </label>
-                    <div class="col-md-6">
-                      <input id="artemisUserName" type="text" class="form-control" ng-model="artemisUserName"/>
-                    </div>
-                  </div>
-
-                  <div class="form-group">
-                    <label class="col-md-2 control-label" for="artemisPassword">
-                      Artemis password
-                      <span class="pficon pficon-info" data-toggle="tooltip" data-placement="top" title="The password to be used when connecting to the broker"></span>
-                    </label>
-                    <div class="col-md-6">
-                      <input id="artemisPassword" type="password" class="form-control" ng-model="artemisPassword"/>
-                    </div>
-                  </div>
-
                   <div class="form-group">
                     <label class="col-md-2 control-label" for="artemisDLQ">
                       Dead-letter address regex
diff --git a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/sendMessage.js b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/sendMessage.js
index 304ad6baec..423fcd1544 100644
--- a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/sendMessage.js
+++ b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/components/sendMessage.js
@@ -28,13 +28,6 @@ var Artemis;
                 </button>
             </h1>
 
-            <div class="alert alert-warning" ng-show="$ctrl.message.noCredentials">
-                <span class="pficon pficon-warning-triangle-o"></span>
-                <strong>No credentials set for endpoint!</strong>
-                Please set your username and password in the
-                <a href="#" class="alert-link" ng-click="$ctrl.message.openPrefs()">Preferences</a> page.
-            </div>
-
             <div class="row artemis-message-configuration">
 
                 <div class="col-sm-12">
@@ -57,6 +50,31 @@ var Artemis;
                                 <span class="pficon pficon-info"></span>
                             </button>
                         </div>
+                        <div class="form-group">
+                            <label>Use current logon user </label>
+                            <input id="useCurrentLogonUser" type="checkbox" ng-model="$ctrl.message.noCredentials" value="true">
+                            <button type="button" class="btn btn-link jvm-title-popover"
+                                      uib-popover-template="'use-current-logon-user-credentials-id-info.html'" popover-placement="bottom-left"
+                                      popover-title="Use current logon user" popover-trigger="'mouseenter'">
+                                <span class="pficon pficon-info"></span>
+                            </button>
+                        </div>
+                        <div class="form-group" ng-hide="$ctrl.message.noCredentials">
+                            <label class="col-sm-2 control-label" for="name-markup">Username</label>
+
+                            <div class="col-sm-10">
+                                <input id="name-markup" class="form-control" type="text" maxlength="300"
+                                       name="username" ng-model="$ctrl.message.username" placeholder="username"/>
+                            </div>
+                        </div>
+                        <div class="form-group" ng-hide="$ctrl.message.noCredentials">
+                            <label class="col-sm-2 control-label" for="name-markup">Password</label>
+
+                            <div class="col-sm-10">
+                                <input id="name-markup" class="form-control" type="password" maxlength="300"
+                                       name="password" ng-model="$ctrl.message.password" placeholder="password"/>
+                            </div>
+                        </div>
                     </form>
                 </div>
             </div>
@@ -110,8 +128,7 @@ var Artemis;
                 <p>
                     This page allows you to send a message to the chosen queue. The message will be of type <code>text</code>
                     message and it will be possible to add headers to the message. The sending of the message will be authenticated
-                    using the username and password set in <code>preferences</code>, if this is not set then these will
-                    be null.
+                    using the current logon user, unselect <code>use current logon user</code> to use a different user.
                 </p>
             </div>
             </script>
@@ -131,6 +148,13 @@ var Artemis;
                 </p>
             </div>
             </script>
+            <script type="text/ng-template" id="use-current-logon-user-credentials-id-info.html">
+            <div>
+                <p>
+                    This option allows a user to send messages with the permissions of the user's current logon, disable it to send messages with different permissions than the user's current logon provides.
+                </p>
+            </div>
+            </script>
         `,
         controller: SendMessageController
     })
diff --git a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/services/sendMessageService.js b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/services/sendMessageService.js
index f2fa297133..f4b264dd72 100644
--- a/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/services/sendMessageService.js
+++ b/artemis-hawtio/artemis-plugin/src/main/webapp/plugin/js/services/sendMessageService.js
@@ -28,7 +28,9 @@ var Artemis;
 
 
         function message(scope, location, route, localStorage, artemisMessage, workspace, element, timeout, jolokia) {
-            this.noCredentials = false,
+            this.username = "",
+            this.password= "",
+            this.noCredentials = true,
             this.durable = true,
             this.messageID = false;
             this.message = "",
@@ -45,9 +47,6 @@ var Artemis;
             // only reload the page if certain search parameters change
             Core.reloadWhenParametersChange(route, scope, location, localStorage);
             if (location.path().indexOf('artemis') > -1) {
-                this.localStorage = localStorage;
-                scope.$watch('localStorage.artemisUserName', this.checkCredentials);
-                scope.$watch('localStorage.artemisPassword', this.checkCredentials);
                 //prefill if it's a resend
                 if (artemisMessage.message !== null) {
                     this.message = artemisMessage.message.bodyText;
@@ -74,13 +73,6 @@ var Artemis;
                 scope.codeMirror = codeMirror;
             });
 
-            checkCredentials = function () {
-                this.noCredentials = (Core.isBlank(localStorage['artemisUserName']) || Core.isBlank(localStorage['artemisPassword']));
-            };
-            this.openPrefs = function (location) {
-                Artemis.log.debug("opening prefs");
-                location.path('/preferences').search({'pref': 'Artemis'});
-            };
             this.addHeader = function  () {
                 this.headers.push({name: "", value: ""});
                 // lets set the focus to the last header
@@ -141,8 +133,8 @@ var Artemis;
                             Artemis.log.debug("About to send headers: " + JSON.stringify(headers));
                         }
 
-                        var user = this.localStorage["artemisUserName"];
-                        var pwd = this.localStorage["artemisPassword"];
+                        var user = (this.noCredentials ? null : this.username);
+                        var pwd = (this.noCredentials ? null : this.password);
 
                         if (!headers) {
                             headers = {};
diff --git a/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/console/QueuesTest.java b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/console/QueuesTest.java
index acad0fba04..2b64eaa23a 100644
--- a/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/console/QueuesTest.java
+++ b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/console/QueuesTest.java
@@ -22,10 +22,12 @@ import org.apache.activemq.artemis.api.core.management.ObjectNameBuilder;
 import org.apache.activemq.artemis.cli.commands.ActionContext;
 import org.apache.activemq.artemis.cli.commands.messages.Consumer;
 import org.apache.activemq.artemis.cli.commands.messages.Producer;
+import org.apache.activemq.artemis.cli.commands.queue.CreateQueue;
 import org.apache.activemq.artemis.tests.smoke.console.pages.LoginPage;
 import org.apache.activemq.artemis.tests.smoke.console.pages.MessagePage;
 import org.apache.activemq.artemis.tests.smoke.console.pages.QueuePage;
 import org.apache.activemq.artemis.tests.smoke.console.pages.QueuesPage;
+import org.apache.activemq.artemis.tests.smoke.console.pages.SendMessagePage;
 import org.apache.activemq.artemis.tests.smoke.console.pages.StatusPage;
 import org.apache.activemq.artemis.utils.Wait;
 import org.junit.Assert;
@@ -163,4 +165,62 @@ public class QueuesTest extends ConsoleTest {
       QueuePage dlqPage = afterQueuesPage.getQueuePage(expiryQueueName, DEFAULT_TIMEOUT);
       assertEquals(testQueueName, dlqPage.getMessageOriginalQueue(0));
    }
+
+   @Test
+   public void testSendMessageUsingCurrentLogonUser() throws Exception {
+      final String queueName = "TEST";
+      final String messageText = "TEST";
+
+      driver.get(serverUrl + "/console");
+      LoginPage loginPage = new LoginPage(driver);
+      StatusPage statusPage = loginPage.loginValidUser(
+         SERVER_ADMIN_USERNAME, SERVER_ADMIN_PASSWORD, DEFAULT_TIMEOUT);
+      QueuesPage beforeSendingQueuesPage = statusPage.getQueuesPage(DEFAULT_TIMEOUT);
+      Wait.assertEquals(1, () -> beforeSendingQueuesPage.countQueue("DLQ"));
+      Wait.assertEquals(0, () -> beforeSendingQueuesPage.countQueue(queueName));
+
+      CreateQueue createQueueCommand = new CreateQueue();
+      createQueueCommand.setUser(SERVER_ADMIN_USERNAME);
+      createQueueCommand.setPassword(SERVER_ADMIN_PASSWORD);
+      createQueueCommand.setName(queueName);
+      createQueueCommand.setMulticast(true);
+      createQueueCommand.setAnycast(false);
+      createQueueCommand.setAutoCreateAddress(true);
+      createQueueCommand.execute(new ActionContext());
+
+      final int messages = 1;
+      beforeSendingQueuesPage.refresh(DEFAULT_TIMEOUT);
+      Wait.assertEquals(1, () -> beforeSendingQueuesPage.countQueue("DLQ"));
+      Wait.assertEquals(1, () -> beforeSendingQueuesPage.countQueue(queueName));
+      assertEquals(0, beforeSendingQueuesPage.getMessagesCount(queueName));
+
+      QueuePage queuePage = beforeSendingQueuesPage.getQueuePage(queueName, DEFAULT_TIMEOUT);
+      SendMessagePage sendMessagePage = queuePage.getSendMessagePage(DEFAULT_TIMEOUT);
+      for (int i = 0; i < messages; i++) {
+         sendMessagePage.clearMessageText();
+         sendMessagePage.selectUseCurrentLogonUser();
+         sendMessagePage.appendMessageText(messageText);
+         sendMessagePage.sendMessage();
+      }
+
+      QueuesPage afterSendingQueuesPage = sendMessagePage.getQueuesPage(DEFAULT_TIMEOUT);
+      Wait.assertEquals(1, () -> afterSendingQueuesPage.countQueue("DLQ"));
+      Wait.assertEquals(messages, () -> afterSendingQueuesPage.getMessagesCount(queueName));
+
+      Consumer consumer = new Consumer();
+      consumer.setUser(SERVER_ADMIN_USERNAME);
+      consumer.setPassword(SERVER_ADMIN_PASSWORD);
+      consumer.setDestination(queueName);
+      consumer.setMessageCount(messages);
+      consumer.setSilentInput(true);
+      consumer.setReceiveTimeout(2000);
+      consumer.setBreakOnNull(true);
+      int consumed = (int)consumer.execute(new ActionContext());
+
+      assertEquals(messages, consumed);
+
+      afterSendingQueuesPage.refresh(DEFAULT_TIMEOUT);
+      Wait.assertEquals(1, () -> afterSendingQueuesPage.countQueue("DLQ"));
+      Wait.assertEquals(0, () -> afterSendingQueuesPage.getMessagesCount(queueName));
+   }
 }
diff --git a/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/console/pages/QueuePage.java b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/console/pages/QueuePage.java
index f903ef71cf..018e842cf0 100644
--- a/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/console/pages/QueuePage.java
+++ b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/console/pages/QueuePage.java
@@ -28,6 +28,8 @@ public class QueuePage extends ArtemisPage {
    public QueuePage(WebDriver driver) {
       super(driver);
    }
+   private By dropdownMenuLocator = By.id("moreDropdown");
+   private By sendMessageMenuItemLocator = By.xpath("//a[contains(text(),'Send message')]");
 
    public MessagePage getMessagePage(int index, int timeout) {
       driver.findElements(By.cssSelector("button[title='Show message']")).get(index).click();
@@ -67,4 +69,24 @@ public class QueuePage extends ArtemisPage {
 
       return -1;
    }
+
+   public SendMessagePage getSendMessagePage(int timeout) {
+      WebElement queuesMenuItem = driver.findElement(sendMessageMenuItemLocator);
+
+      if (!queuesMenuItem.isDisplayed()) {
+         List<WebElement> dropdownMenu = driver.findElements(dropdownMenuLocator);
+
+         if (dropdownMenu.size() > 0) {
+            dropdownMenu.get(0).click();
+         } else {
+            waitForElementToBeVisible(sendMessageMenuItemLocator, timeout);
+         }
+      }
+
+      queuesMenuItem.click();
+
+      waitForElementToBeVisible(By.xpath("//h1[contains(text(),'Send Message')]"), timeout);
+
+      return new SendMessagePage(driver);
+   }
 }
diff --git a/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/console/pages/SendMessagePage.java b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/console/pages/SendMessagePage.java
new file mode 100644
index 0000000000..55d1317d24
--- /dev/null
+++ b/tests/smoke-tests/src/test/java/org/apache/activemq/artemis/tests/smoke/console/pages/SendMessagePage.java
@@ -0,0 +1,74 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.activemq.artemis.tests.smoke.console.pages;
+
+import org.openqa.selenium.By;
+import org.openqa.selenium.Keys;
+import org.openqa.selenium.WebDriver;
+import org.openqa.selenium.interactions.Actions;
+
+public class SendMessagePage extends ArtemisPage {
+   private By messageTextLocator = By.cssSelector("span[role='presentation']");
+   private By messageTextEditorLocator = By.cssSelector("div[hawtio-editor='$ctrl.message.message']");
+
+   public SendMessagePage(WebDriver driver) {
+      super(driver);
+   }
+
+   public void clearMessageText() {
+      while (getMessageText().length() > 0) {
+         Actions actions = new Actions(driver);
+         actions.click(driver.findElement(messageTextEditorLocator));
+         actions.sendKeys(Keys.BACK_SPACE);
+         actions.sendKeys(Keys.DELETE);
+         actions.perform();
+      }
+   }
+
+   public boolean isUseCurrentLogonUserSelected() {
+      return driver.findElement(By.id("useCurrentLogonUser")).isSelected();
+   }
+
+
+   public void selectUseCurrentLogonUser() {
+      if (!isUseCurrentLogonUserSelected()) {
+         driver.findElement(By.id("useCurrentLogonUser")).click();
+      }
+   }
+
+   public void unselectUseCurrentLogonUser() {
+      if (isUseCurrentLogonUserSelected()) {
+         driver.findElement(By.id("useCurrentLogonUser")).click();
+      }
+   }
+
+   public void appendMessageText(String text) {
+      Actions actions = new Actions(driver);
+      actions.click(driver.findElement(messageTextEditorLocator));
+      actions.sendKeys(text);
+      actions.perform();
+   }
+
+   public String getMessageText() {
+      return driver.findElement(messageTextLocator).getText();
+   }
+
+   public void sendMessage() {
+      driver.findElement(By.xpath("//button[contains(text(),'Send Message')]")).click();
+   }
+}