Repository: activemq-artemis
Updated Branches:
  refs/heads/master 2b62bc74f -> b3ffac30e


ARTEMIS-584 add validated user to msg

Implements a new feature to aid in security auditing by adding the name
of the validated user to the messages it sends.


Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/765b2259
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/765b2259
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/765b2259

Branch: refs/heads/master
Commit: 765b2259243b1855ca0e0f2d4d3e481453951ebe
Parents: 2b62bc7
Author: jbertram <[email protected]>
Authored: Tue Jun 28 21:33:44 2016 -0500
Committer: jbertram <[email protected]>
Committed: Wed Jul 6 09:37:29 2016 -0500

----------------------------------------------------------------------
 .../config/ActiveMQDefaultConfiguration.java    |  10 +
 .../activemq/artemis/api/core/Message.java      |   5 +
 .../activemq/artemis/reader/MessageUtil.java    |   5 +-
 .../artemis/jms/client/ActiveMQMessage.java     |  20 +-
 .../impl/openmbean/JMSOpenTypeSupport.java      |   2 +-
 .../openwire/OpenWireProtocolManager.java       |   8 +-
 .../artemis/core/protocol/stomp/Stomp.java      |   2 +
 .../protocol/stomp/StompProtocolManager.java    |   8 +-
 .../artemis/core/protocol/stomp/StompUtils.java |  29 +-
 .../artemis/core/config/Configuration.java      |   4 +
 .../core/config/impl/ConfigurationImpl.java     |  16 +
 .../deployers/impl/FileConfigurationParser.java |   2 +
 .../artemis/core/security/SecurityStore.java    |   2 +-
 .../core/security/impl/SecurityStoreImpl.java   |  23 +-
 .../core/server/impl/ActiveMQServerImpl.java    |  10 +-
 .../core/server/impl/ServerSessionImpl.java     |   9 +
 .../security/ActiveMQJAASSecurityManager.java   |  34 ++-
 .../core/security/ActiveMQSecurityManager3.java |  64 ++++
 .../resources/schema/artemis-configuration.xsd  |   8 +
 .../core/config/impl/FileConfigurationTest.java |   1 +
 .../resources/ConfigurationTest-full-config.xml |   1 +
 docs/user-manual/en/configuration-index.md      |   1 +
 docs/user-manual/en/security.md                 |   7 +
 .../integration/client/HangConsumerTest.java    |   3 +-
 .../server/management/JMSQueueControlTest.java  |  14 +-
 .../integration/security/SecurityTest.java      | 289 ++++++++++++++-----
 .../tests/integration/stomp/StompTestBase.java  |  32 +-
 .../stomp/StompTestWithSecurity.java            |  61 ++++
 28 files changed, 546 insertions(+), 124 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/765b2259/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java
----------------------------------------------------------------------
diff --git 
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java
 
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java
index 1239b0b..e8fe1c5 100644
--- 
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java
+++ 
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/config/ActiveMQDefaultConfiguration.java
@@ -390,6 +390,9 @@ public final class ActiveMQDefaultConfiguration {
    // Will this backup server come live on a normal server shutdown
    private static boolean DEFAULT_FAILOVER_ON_SERVER_SHUTDOWN = false;
 
+   // Will the broker populate the message with the name of the validated user
+   private static boolean DEFAULT_POPULATE_VALIDATED_USER = false;
+
    // its possible that you only want a server to partake in scale down as a 
receiver, via a group. In this case set scale-down to false
    private static boolean DEFAULT_SCALE_DOWN_ENABLED = true;
 
@@ -1061,6 +1064,13 @@ public final class ActiveMQDefaultConfiguration {
    }
 
    /**
+    * Will the broker populate the message with the name of the validated user
+    */
+   public static boolean isDefaultPopulateValidatedUser() {
+      return DEFAULT_POPULATE_VALIDATED_USER;
+   }
+
+   /**
     * its possible that you only want a server to partake in scale down as a 
receiver, via a group. In this case set scale-down to false
     */
    public static boolean isDefaultScaleDownEnabled() {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/765b2259/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/Message.java
----------------------------------------------------------------------
diff --git 
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/Message.java
 
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/Message.java
index 5bb6f42..01db007 100644
--- 
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/Message.java
+++ 
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/api/core/Message.java
@@ -106,6 +106,11 @@ public interface Message {
     */
    SimpleString HDR_CONTENT_TYPE = new SimpleString("_AMQ_CONTENT_TYPE");
 
+   /**
+    * The name of the validated user who sent the message. Useful for auditing.
+    */
+   SimpleString HDR_VALIDATED_USER = new SimpleString("_AMQ_VALIDATED_USER");
+
    byte DEFAULT_TYPE = 0;
 
    byte OBJECT_TYPE = 2;

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/765b2259/artemis-core-client/src/main/java/org/apache/activemq/artemis/reader/MessageUtil.java
----------------------------------------------------------------------
diff --git 
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/reader/MessageUtil.java
 
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/reader/MessageUtil.java
index f61384d..be6568c 100644
--- 
a/artemis-core-client/src/main/java/org/apache/activemq/artemis/reader/MessageUtil.java
+++ 
b/artemis-core-client/src/main/java/org/apache/activemq/artemis/reader/MessageUtil.java
@@ -49,6 +49,8 @@ public class MessageUtil {
 
    public static final String JMSXGROUPID = "JMSXGroupID";
 
+   public static final String JMSXUSERID = "JMSXUserID";
+
    public static final SimpleString CONNECTION_ID_PROPERTY_NAME = new 
SimpleString("__AMQ_CID");
 
 //   public static ActiveMQBuffer getBodyBuffer(Message message) {
@@ -155,6 +157,7 @@ public class MessageUtil {
 
    public static boolean propertyExists(Message message, String name) {
       return message.containsProperty(new SimpleString(name)) || 
name.equals(MessageUtil.JMSXDELIVERYCOUNT) ||
-         MessageUtil.JMSXGROUPID.equals(name) && 
message.containsProperty(Message.HDR_GROUP_ID);
+         (MessageUtil.JMSXGROUPID.equals(name) && 
message.containsProperty(Message.HDR_GROUP_ID)) ||
+         (MessageUtil.JMSXUSERID.equals(name) && 
message.containsProperty(Message.HDR_VALIDATED_USER));
    }
 }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/765b2259/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQMessage.java
----------------------------------------------------------------------
diff --git 
a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQMessage.java
 
b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQMessage.java
index 7b2ee5b..2dd0df1 100644
--- 
a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQMessage.java
+++ 
b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQMessage.java
@@ -581,6 +581,9 @@ public class ActiveMQMessage implements javax.jms.Message {
          if (MessageUtil.JMSXGROUPID.equals(name)) {
             return 
message.getStringProperty(org.apache.activemq.artemis.api.core.Message.HDR_GROUP_ID);
          }
+         else if (MessageUtil.JMSXUSERID.equals(name)) {
+            return 
message.getStringProperty(org.apache.activemq.artemis.api.core.Message.HDR_VALIDATED_USER);
+         }
          else {
             return message.getStringProperty(new SimpleString(name));
          }
@@ -656,7 +659,10 @@ public class ActiveMQMessage implements javax.jms.Message {
    public void setStringProperty(final String name, final String value) throws 
JMSException {
       checkProperty(name);
 
-      if (handleGroupID(name, value)) {
+      if (handleCoreProperty(name, value, MessageUtil.JMSXGROUPID, 
org.apache.activemq.artemis.api.core.Message.HDR_GROUP_ID)) {
+         return;
+      }
+      else if (handleCoreProperty(name, value, MessageUtil.JMSXUSERID, 
org.apache.activemq.artemis.api.core.Message.HDR_VALIDATED_USER)) {
          return;
       }
       else {
@@ -666,7 +672,11 @@ public class ActiveMQMessage implements javax.jms.Message {
 
    @Override
    public void setObjectProperty(final String name, final Object value) throws 
JMSException {
-      if (handleGroupID(name, value)) {
+      if (handleCoreProperty(name, value, MessageUtil.JMSXGROUPID, 
org.apache.activemq.artemis.api.core.Message.HDR_GROUP_ID)) {
+         return;
+      }
+
+      if (handleCoreProperty(name, value, MessageUtil.JMSXUSERID, 
org.apache.activemq.artemis.api.core.Message.HDR_VALIDATED_USER)) {
          return;
       }
 
@@ -954,11 +964,11 @@ public class ActiveMQMessage implements javax.jms.Message 
{
       }
    }
 
-   private boolean handleGroupID(final String name, final Object value) {
+   private boolean handleCoreProperty(final String name, final Object value, 
String jmsPropertyName, SimpleString corePropertyName) {
       boolean result = false;
 
-      if (MessageUtil.JMSXGROUPID.equals(name)) {
-         
message.putStringProperty(org.apache.activemq.artemis.api.core.Message.HDR_GROUP_ID,
 SimpleString.toSimpleString(value.toString()));
+      if (jmsPropertyName.equals(name)) {
+         message.putStringProperty(corePropertyName, 
SimpleString.toSimpleString(value.toString()));
 
          result = true;
       }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/765b2259/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/management/impl/openmbean/JMSOpenTypeSupport.java
----------------------------------------------------------------------
diff --git 
a/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/management/impl/openmbean/JMSOpenTypeSupport.java
 
b/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/management/impl/openmbean/JMSOpenTypeSupport.java
index 513d1f2..06ba26c 100644
--- 
a/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/management/impl/openmbean/JMSOpenTypeSupport.java
+++ 
b/artemis-jms-server/src/main/java/org/apache/activemq/artemis/jms/management/impl/openmbean/JMSOpenTypeSupport.java
@@ -166,7 +166,7 @@ public final class JMSOpenTypeSupport {
          rc.put(JMSCompositeDataConstants.JMS_REDELIVERED, 
data.get(CompositeDataConstants.REDELIVERED));
          putStringProperty(rc, data, JMSCompositeDataConstants.JMSXGROUP_ID, 
Message.HDR_GROUP_ID.toString());
          putIntProperty(rc, data, JMSCompositeDataConstants.JMSXGROUP_SEQ, 
JMSCompositeDataConstants.JMSXGROUP_SEQ);
-         putStringProperty(rc, data, JMSCompositeDataConstants.JMSXUSER_ID, 
JMSCompositeDataConstants.JMSXUSER_ID);
+         putStringProperty(rc, data, JMSCompositeDataConstants.JMSXUSER_ID, 
Message.HDR_VALIDATED_USER.toString());
          putStringProperty(rc, data, 
JMSCompositeDataConstants.ORIGINAL_DESTINATION, 
Message.HDR_ORIGINAL_ADDRESS.toString());
 
          rc.put(CompositeDataConstants.PROPERTIES, "" + 
data.get(CompositeDataConstants.PROPERTIES));

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/765b2259/artemis-protocols/artemis-openwire-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/openwire/OpenWireProtocolManager.java
----------------------------------------------------------------------
diff --git 
a/artemis-protocols/artemis-openwire-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/openwire/OpenWireProtocolManager.java
 
b/artemis-protocols/artemis-openwire-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/openwire/OpenWireProtocolManager.java
index b91a4e4..d20b661 100644
--- 
a/artemis-protocols/artemis-openwire-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/openwire/OpenWireProtocolManager.java
+++ 
b/artemis-protocols/artemis-openwire-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/openwire/OpenWireProtocolManager.java
@@ -50,6 +50,7 @@ import 
org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
 import org.apache.activemq.artemis.spi.core.remoting.Acceptor;
 import org.apache.activemq.artemis.spi.core.remoting.Connection;
 import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
+import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager3;
 import org.apache.activemq.artemis.utils.DataConstants;
 import org.apache.activemq.command.ActiveMQMessage;
 import org.apache.activemq.command.ActiveMQTopic;
@@ -442,7 +443,12 @@ public class OpenWireProtocolManager implements 
ProtocolManager<Interceptor>, Cl
       ActiveMQSecurityManager sm = server.getSecurityManager();
 
       if (sm != null && server.getConfiguration().isSecurityEnabled()) {
-         validated = sm.validateUser(login, passcode);
+         if (sm instanceof ActiveMQSecurityManager3) {
+            validated = ((ActiveMQSecurityManager3) sm).validateUser(login, 
passcode, null) != null;
+         }
+         else {
+            validated = sm.validateUser(login, passcode);
+         }
       }
 
       return validated;

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/765b2259/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/Stomp.java
----------------------------------------------------------------------
diff --git 
a/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/Stomp.java
 
b/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/Stomp.java
index 1607666..8e8acb3 100644
--- 
a/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/Stomp.java
+++ 
b/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/Stomp.java
@@ -125,6 +125,8 @@ public interface Stomp {
          String ACK = "ack";
 
          String PERSISTENT = "persistent";
+
+         String VALIDATED_USER = "JMSXUserID";
       }
 
       public interface Subscribe {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/765b2259/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompProtocolManager.java
----------------------------------------------------------------------
diff --git 
a/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompProtocolManager.java
 
b/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompProtocolManager.java
index 601d833..d572cd0 100644
--- 
a/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompProtocolManager.java
+++ 
b/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompProtocolManager.java
@@ -45,6 +45,7 @@ import 
org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
 import org.apache.activemq.artemis.spi.core.remoting.Acceptor;
 import org.apache.activemq.artemis.spi.core.remoting.Connection;
 import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
+import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager3;
 import org.apache.activemq.artemis.utils.UUIDGenerator;
 
 import static 
org.apache.activemq.artemis.core.protocol.stomp.ActiveMQStompProtocolMessageBundle.BUNDLE;
@@ -331,7 +332,12 @@ class StompProtocolManager extends 
AbstractProtocolManager<StompFrame,StompFrame
       ActiveMQSecurityManager sm = server.getSecurityManager();
 
       if (sm != null && server.getConfiguration().isSecurityEnabled()) {
-         validated = sm.validateUser(login, passcode);
+         if (sm instanceof ActiveMQSecurityManager3) {
+            validated = ((ActiveMQSecurityManager3) sm).validateUser(login, 
passcode, null) != null;
+         }
+         else {
+            validated = sm.validateUser(login, passcode);
+         }
       }
 
       return validated;

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/765b2259/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompUtils.java
----------------------------------------------------------------------
diff --git 
a/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompUtils.java
 
b/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompUtils.java
index d27a4bc..e45b220 100644
--- 
a/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompUtils.java
+++ 
b/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompUtils.java
@@ -26,6 +26,7 @@ import org.apache.activemq.artemis.api.core.SimpleString;
 import org.apache.activemq.artemis.core.client.impl.ClientMessageImpl;
 import org.apache.activemq.artemis.core.message.impl.MessageInternal;
 import org.apache.activemq.artemis.core.server.impl.ServerMessageImpl;
+import org.apache.activemq.artemis.reader.MessageUtil;
 
 public class StompUtils {
 
@@ -51,11 +52,10 @@ public class StompUtils {
          msg.setDurable(Boolean.parseBoolean(persistent));
       }
 
-      // FIXME should use a proper constant
-      msg.putObjectProperty("JMSCorrelationID", 
headers.remove(Stomp.Headers.Send.CORRELATION_ID));
-      msg.putObjectProperty("JMSType", 
headers.remove(Stomp.Headers.Send.TYPE));
+      msg.putObjectProperty(MessageUtil.CORRELATIONID_HEADER_NAME, 
headers.remove(Stomp.Headers.Send.CORRELATION_ID));
+      msg.putObjectProperty(MessageUtil.TYPE_HEADER_NAME, 
headers.remove(Stomp.Headers.Send.TYPE));
 
-      String groupID = headers.remove("JMSXGroupID");
+      String groupID = headers.remove(MessageUtil.JMSXGROUPID);
       if (groupID != null) {
          msg.putStringProperty(Message.HDR_GROUP_ID, 
SimpleString.toSimpleString(groupID));
       }
@@ -86,8 +86,8 @@ public class StompUtils {
       command.addHeader(Stomp.Headers.Message.MESSAGE_ID, 
String.valueOf(message.getMessageID()));
       command.addHeader(Stomp.Headers.Message.DESTINATION, 
message.getAddress().toString());
 
-      if (message.getObjectProperty("JMSCorrelationID") != null) {
-         command.addHeader(Stomp.Headers.Message.CORRELATION_ID, 
message.getObjectProperty("JMSCorrelationID").toString());
+      if (message.getObjectProperty(MessageUtil.CORRELATIONID_HEADER_NAME) != 
null) {
+         command.addHeader(Stomp.Headers.Message.CORRELATION_ID, 
message.getObjectProperty(MessageUtil.CORRELATIONID_HEADER_NAME).toString());
       }
       command.addHeader(Stomp.Headers.Message.EXPIRATION_TIME, "" + 
message.getExpiration());
       command.addHeader(Stomp.Headers.Message.REDELIVERED, 
String.valueOf(deliveryCount > 1));
@@ -98,22 +98,25 @@ public class StompUtils {
       }
       command.addHeader(Stomp.Headers.Message.TIMESTAMP, "" + 
message.getTimestamp());
 
-      if (message.getObjectProperty("JMSType") != null) {
-         command.addHeader(Stomp.Headers.Message.TYPE, 
message.getObjectProperty("JMSType").toString());
+      if (message.getObjectProperty(MessageUtil.TYPE_HEADER_NAME) != null) {
+         command.addHeader(Stomp.Headers.Message.TYPE, 
message.getObjectProperty(MessageUtil.TYPE_HEADER_NAME).toString());
       }
       if (message.getStringProperty(Message.HDR_CONTENT_TYPE.toString()) != 
null) {
          command.addHeader(Stomp.Headers.CONTENT_TYPE, 
message.getStringProperty(Message.HDR_CONTENT_TYPE.toString()));
       }
+      if (message.getStringProperty(Message.HDR_VALIDATED_USER.toString()) != 
null) {
+         command.addHeader(Stomp.Headers.Message.VALIDATED_USER, 
message.getStringProperty(Message.HDR_VALIDATED_USER.toString()));
+      }
 
-      // now let's add all the message headers
+      // now let's add all the rest of the message headers
       Set<SimpleString> names = message.getPropertyNames();
       for (SimpleString name : names) {
-         String value = name.toString();
          if (name.equals(ClientMessageImpl.REPLYTO_HEADER_NAME) ||
             name.equals(Message.HDR_CONTENT_TYPE) ||
-            value.equals("JMSType") ||
-            value.equals("JMSCorrelationID") ||
-            value.equals(Stomp.Headers.Message.DESTINATION)) {
+            name.equals(Message.HDR_VALIDATED_USER) ||
+            name.equals(MessageUtil.TYPE_HEADER_NAME) ||
+            name.equals(MessageUtil.CORRELATIONID_HEADER_NAME) ||
+            name.toString().equals(Stomp.Headers.Message.DESTINATION)) {
             continue;
          }
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/765b2259/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/Configuration.java
----------------------------------------------------------------------
diff --git 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/Configuration.java
 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/Configuration.java
index 4a24b57..8eb7f10 100644
--- 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/Configuration.java
+++ 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/Configuration.java
@@ -948,6 +948,10 @@ public interface Configuration {
 
    Configuration setStoreConfiguration(StoreConfiguration storeConfiguration);
 
+   boolean isPopulateValidatedUser();
+
+   Configuration setPopulateValidatedUser(boolean populateValidatedUser);
+
    /** It will return all the connectors in a toString manner for debug 
purposes. */
    String debugConnectors();
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/765b2259/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java
----------------------------------------------------------------------
diff --git 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java
 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java
index 19ef7da..6ecdc77 100644
--- 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java
+++ 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/config/impl/ConfigurationImpl.java
@@ -237,6 +237,8 @@ public class ConfigurationImpl implements Configuration, 
Serializable {
 
    private StoreConfiguration storeConfiguration;
 
+   protected boolean populateValidatedUser = 
ActiveMQDefaultConfiguration.isDefaultPopulateValidatedUser();
+
    /**
     * Parent folder for all data folders.
     */
@@ -1353,6 +1355,17 @@ public class ConfigurationImpl implements Configuration, 
Serializable {
    }
 
    @Override
+   public boolean isPopulateValidatedUser() {
+      return populateValidatedUser;
+   }
+
+   @Override
+   public ConfigurationImpl setPopulateValidatedUser(boolean 
populateValidatedUser) {
+      this.populateValidatedUser = populateValidatedUser;
+      return this;
+   }
+
+   @Override
    public int hashCode() {
       final int prime = 31;
       int result = 1;
@@ -1417,6 +1430,7 @@ public class ConfigurationImpl implements Configuration, 
Serializable {
       result = prime * result + (runSyncSpeedTest ? 1231 : 1237);
       result = prime * result + scheduledThreadPoolMaxSize;
       result = prime * result + (securityEnabled ? 1231 : 1237);
+      result = prime * result + (populateValidatedUser ? 1231 : 1237);
       result = prime * result + (int) (securityInvalidationInterval ^ 
(securityInvalidationInterval >>> 32));
       result = prime * result + ((securitySettings == null) ? 0 : 
securitySettings.hashCode());
       result = prime * result + (int) (serverDumpInterval ^ 
(serverDumpInterval >>> 32));
@@ -1654,6 +1668,8 @@ public class ConfigurationImpl implements Configuration, 
Serializable {
          return false;
       if (securityEnabled != other.securityEnabled)
          return false;
+      if (populateValidatedUser != other.populateValidatedUser)
+         return false;
       if (securityInvalidationInterval != other.securityInvalidationInterval)
          return false;
       if (securitySettings == null) {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/765b2259/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java
----------------------------------------------------------------------
diff --git 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java
 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java
index ca4bb52..0a47f9f 100644
--- 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java
+++ 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/deployers/impl/FileConfigurationParser.java
@@ -274,6 +274,8 @@ public final class FileConfigurationParser extends 
XMLConfigurationUtil {
 
       config.setPasswordCodec(getString(e, "password-codec", 
DefaultSensitiveStringCodec.class.getName(), Validators.NOT_NULL_OR_EMPTY));
 
+      config.setPopulateValidatedUser(getBoolean(e, "populate-validated-user", 
config.isPopulateValidatedUser()));
+
       // parsing cluster password
       String passwordText = getString(e, "cluster-password", null, 
Validators.NO_CHECK);
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/765b2259/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/SecurityStore.java
----------------------------------------------------------------------
diff --git 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/SecurityStore.java
 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/SecurityStore.java
index 88fab08..87ba380 100644
--- 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/SecurityStore.java
+++ 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/SecurityStore.java
@@ -22,7 +22,7 @@ import org.apache.activemq.artemis.api.core.SimpleString;
 
 public interface SecurityStore {
 
-   void authenticate(String user, String password, X509Certificate[] 
certificates) throws Exception;
+   String authenticate(String user, String password, X509Certificate[] 
certificates) throws Exception;
 
    void check(SimpleString address, CheckType checkType, SecurityAuth session) 
throws Exception;
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/765b2259/artemis-server/src/main/java/org/apache/activemq/artemis/core/security/impl/SecurityStoreImpl.java
----------------------------------------------------------------------
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 dcda59f..208d0cc 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
@@ -35,6 +35,7 @@ import 
org.apache.activemq.artemis.core.settings.HierarchicalRepository;
 import 
org.apache.activemq.artemis.core.settings.HierarchicalRepositoryChangeListener;
 import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
 import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager2;
+import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager3;
 import org.apache.activemq.artemis.utils.ConcurrentHashSet;
 import org.apache.activemq.artemis.utils.TypedProperties;
 import org.jboss.logging.Logger;
@@ -99,7 +100,7 @@ public class SecurityStoreImpl implements SecurityStore, 
HierarchicalRepositoryC
    }
 
    @Override
-   public void authenticate(final String user, final String password, 
X509Certificate[] certificates) throws Exception {
+   public String authenticate(final String user, final String password, 
X509Certificate[] certificates) throws Exception {
       if (securityEnabled) {
 
          if (managementClusterUser.equals(user)) {
@@ -115,20 +116,24 @@ public class SecurityStoreImpl implements SecurityStore, 
HierarchicalRepositoryC
                throw 
ActiveMQMessageBundle.BUNDLE.unableToValidateClusterUser(user);
             }
             else {
-               return;
+               return managementClusterUser;
             }
          }
 
+         String validatedUser = null;
          boolean userIsValid = false;
 
-         if (securityManager instanceof ActiveMQSecurityManager2) {
+         if (securityManager instanceof ActiveMQSecurityManager3) {
+            validatedUser = 
((ActiveMQSecurityManager3)securityManager).validateUser(user, password, 
certificates);
+         }
+         else if (securityManager instanceof ActiveMQSecurityManager2) {
             userIsValid = 
((ActiveMQSecurityManager2)securityManager).validateUser(user, password, 
certificates);
          }
          else {
             userIsValid = securityManager.validateUser(user, password);
          }
 
-         if (!userIsValid) {
+         if (!userIsValid && validatedUser == null) {
             if (notificationService != null) {
                TypedProperties props = new TypedProperties();
 
@@ -139,7 +144,11 @@ public class SecurityStoreImpl implements SecurityStore, 
HierarchicalRepositoryC
 
             throw ActiveMQMessageBundle.BUNDLE.unableToValidateUser();
          }
+
+         return validatedUser;
       }
+
+      return null;
    }
 
    @Override
@@ -167,7 +176,11 @@ public class SecurityStoreImpl implements SecurityStore, 
HierarchicalRepositoryC
          }
 
          final boolean validated;
-         if (securityManager instanceof ActiveMQSecurityManager2) {
+         if (securityManager instanceof ActiveMQSecurityManager3) {
+            final ActiveMQSecurityManager3 securityManager3 = 
(ActiveMQSecurityManager3) securityManager;
+            validated = securityManager3.validateUserAndRole(user, 
session.getPassword(), roles, checkType, saddress, 
session.getRemotingConnection()) != null;
+         }
+         else if (securityManager instanceof ActiveMQSecurityManager2) {
             final ActiveMQSecurityManager2 securityManager2 = 
(ActiveMQSecurityManager2) securityManager;
             validated = securityManager2.validateUserAndRole(user, 
session.getPassword(), roles, checkType, saddress, 
session.getRemotingConnection());
          }

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/765b2259/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
----------------------------------------------------------------------
diff --git 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
index 8acdc11..e67cd06 100644
--- 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
+++ 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java
@@ -1161,19 +1161,20 @@ public class ActiveMQServerImpl implements 
ActiveMQServer {
                                       final String defaultAddress,
                                       final SessionCallback callback,
                                       final boolean autoCreateQueues) throws 
Exception {
+      String validatedUser = "";
 
       if (securityStore != null) {
          X509Certificate[] certificates = null;
          if (connection.getTransportConnection() instanceof NettyConnection) {
             certificates = 
CertificateUtil.getCertsFromChannel(((NettyConnection) 
connection.getTransportConnection()).getChannel());
          }
-         securityStore.authenticate(username, password, certificates);
+         validatedUser = securityStore.authenticate(username, password, 
certificates);
       }
 
-      checkSessionLimit(username);
+      checkSessionLimit(validatedUser);
 
       final OperationContext context = 
storageManager.newContext(getExecutorFactory().getExecutor());
-      final ServerSessionImpl session = internalCreateSession(name, username, 
password, minLargeMessageSize, connection, autoCommitSends, autoCommitAcks, 
preAcknowledge, xa, defaultAddress, callback, context, autoCreateQueues);
+      final ServerSessionImpl session = internalCreateSession(name, username, 
password, validatedUser, minLargeMessageSize, connection, autoCommitSends, 
autoCommitAcks, preAcknowledge, xa, defaultAddress, callback, context, 
autoCreateQueues);
 
       sessions.put(name, session);
 
@@ -1237,6 +1238,7 @@ public class ActiveMQServerImpl implements ActiveMQServer 
{
    protected ServerSessionImpl internalCreateSession(String name,
                                                      String username,
                                                      String password,
+                                                     String validatedUser,
                                                      int minLargeMessageSize,
                                                      RemotingConnection 
connection,
                                                      boolean autoCommitSends,
@@ -1247,7 +1249,7 @@ public class ActiveMQServerImpl implements ActiveMQServer 
{
                                                      SessionCallback callback,
                                                      OperationContext context,
                                                      boolean 
autoCreateJMSQueues) throws Exception {
-      return new ServerSessionImpl(name, username, password, 
minLargeMessageSize, autoCommitSends, autoCommitAcks, preAcknowledge, 
configuration.isPersistDeliveryCountBeforeDelivery(), xa, connection, 
storageManager, postOffice, resourceManager, securityStore, managementService, 
this, configuration.getManagementAddress(), defaultAddress == null ? null : new 
SimpleString(defaultAddress), callback, context, autoCreateJMSQueues ? 
jmsQueueCreator : null);
+      return new ServerSessionImpl(name, username, password, validatedUser, 
minLargeMessageSize, autoCommitSends, autoCommitAcks, preAcknowledge, 
configuration.isPersistDeliveryCountBeforeDelivery(), xa, connection, 
storageManager, postOffice, resourceManager, securityStore, managementService, 
this, configuration.getManagementAddress(), defaultAddress == null ? null : new 
SimpleString(defaultAddress), callback, context, autoCreateJMSQueues ? 
jmsQueueCreator : null);
    }
 
    @Override

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/765b2259/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java
----------------------------------------------------------------------
diff --git 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java
 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java
index 50ccb50..883f499 100644
--- 
a/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java
+++ 
b/artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ServerSessionImpl.java
@@ -105,6 +105,8 @@ public class ServerSessionImpl implements ServerSession, 
FailureListener {
 
    protected final String password;
 
+   protected final String validatedUser;
+
    private final int minLargeMessageSize;
 
    protected boolean autoCommitSends;
@@ -176,6 +178,7 @@ public class ServerSessionImpl implements ServerSession, 
FailureListener {
    public ServerSessionImpl(final String name,
                             final String username,
                             final String password,
+                            final String validatedUser,
                             final int minLargeMessageSize,
                             final boolean autoCommitSends,
                             final boolean autoCommitAcks,
@@ -198,6 +201,8 @@ public class ServerSessionImpl implements ServerSession, 
FailureListener {
 
       this.password = password;
 
+      this.validatedUser = validatedUser;
+
       this.minLargeMessageSize = minLargeMessageSize;
 
       this.autoCommitSends = autoCommitSends;
@@ -1230,6 +1235,10 @@ public class ServerSessionImpl implements ServerSession, 
FailureListener {
          message.encodeMessageIDToBuffer();
       }
 
+      if (server.getConfiguration().isPopulateValidatedUser() && validatedUser 
!= null) {
+         message.putStringProperty(Message.HDR_VALIDATED_USER, 
SimpleString.toSimpleString(validatedUser));
+      }
+
       SimpleString address = message.getAddress();
 
       if (defaultAddress == null && address != null) {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/765b2259/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/ActiveMQJAASSecurityManager.java
----------------------------------------------------------------------
diff --git 
a/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/ActiveMQJAASSecurityManager.java
 
b/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/ActiveMQJAASSecurityManager.java
index a2d31bf..943851e 100644
--- 
a/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/ActiveMQJAASSecurityManager.java
+++ 
b/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/ActiveMQJAASSecurityManager.java
@@ -34,6 +34,7 @@ import org.apache.activemq.artemis.core.security.Role;
 import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
 import org.apache.activemq.artemis.spi.core.security.jaas.JaasCallbackHandler;
 import org.apache.activemq.artemis.spi.core.security.jaas.RolePrincipal;
+import org.apache.activemq.artemis.spi.core.security.jaas.UserPrincipal;
 import org.apache.activemq.artemis.utils.CertificateUtil;
 import org.jboss.logging.Logger;
 
@@ -43,7 +44,7 @@ import org.jboss.logging.Logger;
  * The {@link Subject} returned by the login context is expecting to have a 
set of {@link RolePrincipal} for each
  * role of the user.
  */
-public class ActiveMQJAASSecurityManager implements ActiveMQSecurityManager2 {
+public class ActiveMQJAASSecurityManager implements ActiveMQSecurityManager3 {
 
    private static final Logger logger = 
Logger.getLogger(ActiveMQJAASSecurityManager.class);
 
@@ -81,30 +82,40 @@ public class ActiveMQJAASSecurityManager implements 
ActiveMQSecurityManager2 {
 
    @Override
    public boolean validateUser(String user, String password) {
-      return validateUser(user, password, null);
+      throw new UnsupportedOperationException("Invoke validateUser(String, 
String, X509Certificate[]) instead");
    }
 
    @Override
-   public boolean validateUser(final String user, final String password, 
X509Certificate[] certificates) {
+   public String validateUser(final String user, final String password, 
X509Certificate[] certificates) {
       try {
-         getAuthenticatedSubject(user, password, certificates);
-         return true;
+         return getUserFromSubject(getAuthenticatedSubject(user, password, 
certificates));
       }
       catch (LoginException e) {
          if (logger.isDebugEnabled()) {
             logger.debug("Couldn't validate user", e);
          }
-         return false;
+         return null;
       }
    }
 
+   public String getUserFromSubject(Subject subject) {
+      String validatedUser = "";
+      Set<UserPrincipal> users = subject.getPrincipals(UserPrincipal.class);
+
+      // should only ever be 1 UserPrincipal
+      for (UserPrincipal userPrincipal : users) {
+         validatedUser = userPrincipal.getName();
+      }
+      return validatedUser;
+   }
+
    @Override
    public boolean validateUserAndRole(String user, String password, Set<Role> 
roles, CheckType checkType) {
       throw new UnsupportedOperationException("Invoke 
validateUserAndRole(String, String, Set<Role>, CheckType, String, 
RemotingConnection) instead");
    }
 
    @Override
-   public boolean validateUserAndRole(final String user,
+   public String validateUserAndRole(final String user,
                                       final String password,
                                       final Set<Role> roles,
                                       final CheckType checkType,
@@ -122,7 +133,7 @@ public class ActiveMQJAASSecurityManager implements 
ActiveMQSecurityManager2 {
          if (logger.isDebugEnabled()) {
             logger.debug("Couldn't validate user", e);
          }
-         return false;
+         return null;
       }
 
       boolean authorized = false;
@@ -155,7 +166,12 @@ public class ActiveMQJAASSecurityManager implements 
ActiveMQSecurityManager2 {
          }
       }
 
-      return authorized;
+      if (authorized) {
+         return getUserFromSubject(localSubject);
+      }
+      else {
+         return null;
+      }
    }
 
    private Subject getAuthenticatedSubject(final String user, final String 
password, final X509Certificate[] certificates) throws LoginException {

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/765b2259/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/ActiveMQSecurityManager3.java
----------------------------------------------------------------------
diff --git 
a/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/ActiveMQSecurityManager3.java
 
b/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/ActiveMQSecurityManager3.java
new file mode 100644
index 0000000..192f5dd
--- /dev/null
+++ 
b/artemis-server/src/main/java/org/apache/activemq/artemis/spi/core/security/ActiveMQSecurityManager3.java
@@ -0,0 +1,64 @@
+/*
+ * 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
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.spi.core.security;
+
+import javax.security.cert.X509Certificate;
+import java.util.Set;
+
+import org.apache.activemq.artemis.core.security.CheckType;
+import org.apache.activemq.artemis.core.security.Role;
+import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
+
+/**
+ * Used to validate whether a user is authorized to connect to the
+ * server and perform certain functions on certain destinations.
+ *
+ * This is an evolution of {@link ActiveMQSecurityManager} and
+ * {@link ActiveMQSecurityManager2} that adds the ability to determine
+ * the identity of the validated user.
+ */
+public interface ActiveMQSecurityManager3 extends ActiveMQSecurityManager {
+
+   /**
+    * is this a valid user.
+    *
+    * This method is called instead of
+    * {@link ActiveMQSecurityManager#validateUser(String, String)}.
+    *
+    * @param user     the user
+    * @param password the users password
+    * @return the name of the validated user or null if the user isn't 
validated
+    */
+   String validateUser(String user, String password, X509Certificate[] 
certificates);
+
+   /**
+    * Determine whether the given user is valid and whether they have
+    * the correct role for the given destination address.
+    *
+    * This method is called instead of
+    * {@link ActiveMQSecurityManager#validateUserAndRole(String, String, Set, 
CheckType)}.
+    *
+    * @param user      the user
+    * @param password  the user's password
+    * @param roles     the user's roles
+    * @param checkType which permission to validate
+    * @param address   the address for which to perform authorization
+    * @param connection   the user's connection
+    * @return the name of the validated user or null if the user isn't 
validated
+    */
+   String validateUserAndRole(String user, String password, Set<Role> roles, 
CheckType checkType, String address, RemotingConnection connection);
+}

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/765b2259/artemis-server/src/main/resources/schema/artemis-configuration.xsd
----------------------------------------------------------------------
diff --git a/artemis-server/src/main/resources/schema/artemis-configuration.xsd 
b/artemis-server/src/main/resources/schema/artemis-configuration.xsd
index 0d369ba..53e5aa8 100644
--- a/artemis-server/src/main/resources/schema/artemis-configuration.xsd
+++ b/artemis-server/src/main/resources/schema/artemis-configuration.xsd
@@ -324,6 +324,14 @@
             </xsd:annotation>
          </xsd:element>
 
+         <xsd:element name="populate-validated-user" type="xsd:boolean" 
default="false" maxOccurs="1" minOccurs="0">
+            <xsd:annotation>
+               <xsd:documentation>
+                  true means that the server will add the name of the 
validated user to messages it sends
+               </xsd:documentation>
+            </xsd:annotation>
+         </xsd:element>
+
          <xsd:element name="connectors" maxOccurs="1" minOccurs="0">
             <xsd:annotation>
                <xsd:documentation>

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/765b2259/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationTest.java
----------------------------------------------------------------------
diff --git 
a/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationTest.java
 
b/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationTest.java
index f7db6e7..3f4edd8 100644
--- 
a/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationTest.java
+++ 
b/artemis-server/src/test/java/org/apache/activemq/artemis/core/config/impl/FileConfigurationTest.java
@@ -102,6 +102,7 @@ public class FileConfigurationTest extends 
ConfigurationImplTest {
       Assert.assertEquals(33, conf.getJournalCompactPercentage());
       Assert.assertEquals(true, conf.isGracefulShutdownEnabled());
       Assert.assertEquals(12345, conf.getGracefulShutdownTimeout());
+      Assert.assertEquals(true, conf.isPopulateValidatedUser());
 
       Assert.assertEquals("largemessagesdir", 
conf.getLargeMessagesDirectory());
       Assert.assertEquals(95, conf.getMemoryWarningThreshold());

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/765b2259/artemis-server/src/test/resources/ConfigurationTest-full-config.xml
----------------------------------------------------------------------
diff --git 
a/artemis-server/src/test/resources/ConfigurationTest-full-config.xml 
b/artemis-server/src/test/resources/ConfigurationTest-full-config.xml
index 9304745..8bd540d 100644
--- a/artemis-server/src/test/resources/ConfigurationTest-full-config.xml
+++ b/artemis-server/src/test/resources/ConfigurationTest-full-config.xml
@@ -50,6 +50,7 @@
       <message-expiry-thread-priority>8</message-expiry-thread-priority>
       <id-cache-size>127</id-cache-size>
       <persist-id-cache>true</persist-id-cache>
+      <populate-validated-user>true</populate-validated-user>
       <remoting-incoming-interceptors>
          
<class-name>org.apache.activemq.artemis.tests.unit.core.config.impl.TestInterceptor1</class-name>
          
<class-name>org.apache.activemq.artemis.tests.unit.core.config.impl.TestInterceptor2</class-name>

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/765b2259/docs/user-manual/en/configuration-index.md
----------------------------------------------------------------------
diff --git a/docs/user-manual/en/configuration-index.md 
b/docs/user-manual/en/configuration-index.md
index 175a5dc..57b36e0 100644
--- a/docs/user-manual/en/configuration-index.md
+++ b/docs/user-manual/en/configuration-index.md
@@ -81,6 +81,7 @@ Name | Description
 
[scheduled-thread-pool-max-size](thread-pooling.md#server.scheduled.thread.pool 
"Server Scheduled Thread Pool")|  Maximum number of threads to use for the 
scheduled thread pool. Default=5
 [security-enabled](security.md "Security")  |  true means that security is 
enabled. Default=true
 [security-invalidation-interval](security.md "Security")                       
            |  how long (in ms) to wait before invalidating the security cache. 
Default=10000
+[populate-validated-user](security.md "Security")                              
            |  whether or not to add the name of the validated user to the 
messages that user sends. Default=false
 [security-settings](security.md "Role based security for addresses")           
                  |  [a list of security-setting](#security-setting-type)
 [thread-pool-max-size](thread-pooling.md "Server Scheduled Thread Pool")       
                |  Maximum number of threads to use for the thread pool. -1 
means 'no limits'.. Default=30
 [transaction-timeout](transaction-config.md "Resource Manager Configuration")  
            |  how long (in ms) before a transaction can be removed from the 
resource manager after create time. Default=300000

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/765b2259/docs/user-manual/en/security.md
----------------------------------------------------------------------
diff --git a/docs/user-manual/en/security.md b/docs/user-manual/en/security.md
index 6c0d078..32c9a35 100644
--- a/docs/user-manual/en/security.md
+++ b/docs/user-manual/en/security.md
@@ -10,6 +10,13 @@ long. To change this period set the property
 `security-invalidation-interval`, which is in milliseconds. The default
 is `10000` ms.
 
+To assist in security auditing the `populate-validated-user` option exists. If 
this is `true` then
+the server will add the name of the validated user to the message using the 
key `_AMQ_VALIDATED_USER`.
+For JMS and Stomp clients this is mapped to the key `JMSXUserID`. For users 
authenticated based on
+their SSL certificate this name is the name to which their certificate's DN 
maps. If `security-enabled`
+is `false` and `populate-validated-user` is `true` then the server will simply 
use whatever user name
+(if any) the client provides. This option is `false` by default.
+
 ## Role based security for addresses
 
 Apache ActiveMQ Artemis contains a flexible role-based security model for 
applying

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/765b2259/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/HangConsumerTest.java
----------------------------------------------------------------------
diff --git 
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/HangConsumerTest.java
 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/HangConsumerTest.java
index 2be2947..bbccbf1 100644
--- 
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/HangConsumerTest.java
+++ 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/client/HangConsumerTest.java
@@ -577,6 +577,7 @@ public class HangConsumerTest extends ActiveMQTestBase {
       protected ServerSessionImpl internalCreateSession(String name,
                                                         String username,
                                                         String password,
+                                                        String validatedUser,
                                                         int 
minLargeMessageSize,
                                                         RemotingConnection 
connection,
                                                         boolean 
autoCommitSends,
@@ -587,7 +588,7 @@ public class HangConsumerTest extends ActiveMQTestBase {
                                                         SessionCallback 
callback,
                                                         OperationContext 
context,
                                                         boolean 
autoCreateQueue) throws Exception {
-         return new ServerSessionImpl(name, username, password, 
minLargeMessageSize, autoCommitSends, autoCommitAcks, preAcknowledge, 
getConfiguration().isPersistDeliveryCountBeforeDelivery(), xa, connection, 
getStorageManager(), getPostOffice(), getResourceManager(), getSecurityStore(), 
getManagementService(), this, getConfiguration().getManagementAddress(), 
defaultAddress == null ? null : new SimpleString(defaultAddress), new 
MyCallback(callback), context, null);
+         return new ServerSessionImpl(name, username, password, validatedUser, 
minLargeMessageSize, autoCommitSends, autoCommitAcks, preAcknowledge, 
getConfiguration().isPersistDeliveryCountBeforeDelivery(), xa, connection, 
getStorageManager(), getPostOffice(), getResourceManager(), getSecurityStore(), 
getManagementService(), this, getConfiguration().getManagementAddress(), 
defaultAddress == null ? null : new SimpleString(defaultAddress), new 
MyCallback(callback), context, null);
       }
    }
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/765b2259/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/server/management/JMSQueueControlTest.java
----------------------------------------------------------------------
diff --git 
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/server/management/JMSQueueControlTest.java
 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/server/management/JMSQueueControlTest.java
index 7636248..6acd9ae 100644
--- 
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/server/management/JMSQueueControlTest.java
+++ 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/jms/server/management/JMSQueueControlTest.java
@@ -236,8 +236,8 @@ public class JMSQueueControlTest extends ManagementTestBase 
{
 
       CompositeData[] data = queueControl.browse();
       Assert.assertEquals(1, data.length);
-      Assert.assertNotNull(data[0].get("JMSCorrelationID"));
-      Assert.assertEquals("foo", data[0].get("JMSCorrelationID"));
+      
Assert.assertNotNull(data[0].get(MessageUtil.CORRELATIONID_HEADER_NAME.toString()));
+      Assert.assertEquals("foo", 
data[0].get(MessageUtil.CORRELATIONID_HEADER_NAME.toString()));
       System.out.println(data[0]);
 
       JMSUtil.consumeMessages(1, queue);
@@ -248,8 +248,8 @@ public class JMSQueueControlTest extends ManagementTestBase 
{
 
       data = queueControl.browse();
       Assert.assertEquals(1, data.length);
-      Assert.assertNotNull(data[0].get("JMSXGroupID"));
-      Assert.assertEquals("myGroupID", data[0].get("JMSXGroupID"));
+      Assert.assertNotNull(data[0].get(MessageUtil.JMSXGROUPID.toString()));
+      Assert.assertEquals("myGroupID", 
data[0].get(MessageUtil.JMSXGROUPID.toString()));
       System.out.println(data[0]);
 
       JMSUtil.consumeMessages(1, queue);
@@ -266,14 +266,14 @@ public class JMSQueueControlTest extends 
ManagementTestBase {
 
       JMSUtil.consumeMessages(1, queue);
 
-      JMSUtil.sendMessageWithProperty(session, queue, "JMSXUserID", 
"theheadhonch");
+      JMSUtil.sendMessageWithProperty(session, queue, 
MessageUtil.JMSXUSERID.toString(), "theheadhonch");
 
       Assert.assertEquals(1, getMessageCount(queueControl));
 
       data = queueControl.browse();
       Assert.assertEquals(1, data.length);
-      Assert.assertNotNull(data[0].get("JMSXUserID"));
-      Assert.assertEquals("theheadhonch", data[0].get("JMSXUserID"));
+      Assert.assertNotNull(data[0].get(MessageUtil.JMSXUSERID.toString()));
+      Assert.assertEquals("theheadhonch", 
data[0].get(MessageUtil.JMSXUSERID.toString()));
       System.out.println(data[0]);
 
       JMSUtil.consumeMessages(1, queue);

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/765b2259/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/SecurityTest.java
----------------------------------------------------------------------
diff --git 
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/SecurityTest.java
 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/SecurityTest.java
index 71cd369..fd61c00 100644
--- 
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/SecurityTest.java
+++ 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/security/SecurityTest.java
@@ -52,6 +52,7 @@ import 
org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
 import 
org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager;
 import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager;
 import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager2;
+import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager3;
 import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
 import org.apache.activemq.artemis.tests.util.CreateMessage;
 import org.junit.Assert;
@@ -1648,39 +1649,39 @@ public class SecurityTest extends ActiveMQTestBase {
    public void testCustomSecurityManager() throws Exception {
       final Configuration configuration = 
createDefaultInVMConfig().setSecurityEnabled(true);
       final ActiveMQSecurityManager customSecurityManager = new 
ActiveMQSecurityManager() {
-            @Override
-            public boolean validateUser(final String username, final String 
password) {
-               return (username.equals("foo") || username.equals("bar") || 
username.equals("all")) &&
-                  password.equals("frobnicate");
-            }
-            @Override
-            public boolean validateUserAndRole(
-               final String username,
-               final String password,
-               final Set<Role> requiredRoles,
-               final CheckType checkType) {
-
-               if ((username.equals("foo") || username.equals("bar") || 
username.equals("all")) &&
-                   password.equals("frobnicate")) {
-
-                  if (username.equals("all")) {
-                     return true;
-                  }
-                  else if (username.equals("foo")) {
-                     return checkType == CheckType.CONSUME || checkType == 
CheckType.CREATE_NON_DURABLE_QUEUE;
-                  }
-                  else if (username.equals("bar")) {
-                     return checkType == CheckType.SEND || checkType == 
CheckType.CREATE_NON_DURABLE_QUEUE;
-                  }
-                  else {
-                     return false;
-                  }
+         @Override
+         public boolean validateUser(final String username, final String 
password) {
+            return (username.equals("foo") || username.equals("bar") || 
username.equals("all")) &&
+               password.equals("frobnicate");
+         }
+         @Override
+         public boolean validateUserAndRole(
+            final String username,
+            final String password,
+            final Set<Role> requiredRoles,
+            final CheckType checkType) {
+
+            if ((username.equals("foo") || username.equals("bar") || 
username.equals("all")) &&
+               password.equals("frobnicate")) {
+
+               if (username.equals("all")) {
+                  return true;
+               }
+               else if (username.equals("foo")) {
+                  return checkType == CheckType.CONSUME || checkType == 
CheckType.CREATE_NON_DURABLE_QUEUE;
+               }
+               else if (username.equals("bar")) {
+                  return checkType == CheckType.SEND || checkType == 
CheckType.CREATE_NON_DURABLE_QUEUE;
                }
                else {
                   return false;
                }
             }
-         };
+            else {
+               return false;
+            }
+         }
+      };
       final ActiveMQServer server = addServer(new 
ActiveMQServerImpl(configuration, customSecurityManager));
       server.start();
 
@@ -1734,61 +1735,207 @@ public class SecurityTest extends ActiveMQTestBase {
    public void testCustomSecurityManager2() throws Exception {
       final Configuration configuration = 
createDefaultInVMConfig().setSecurityEnabled(true);
       final ActiveMQSecurityManager customSecurityManager = new 
ActiveMQSecurityManager2() {
-            @Override
-            public boolean validateUser(final String username, final String 
password) {
-               fail("Unexpected call to overridden method");
+         @Override
+         public boolean validateUser(final String username, final String 
password) {
+            fail("Unexpected call to overridden method");
+            return false;
+         }
+         @Override
+         public boolean validateUser(final String username, final String 
password, final X509Certificate[] certificates) {
+            return (username.equals("foo") || username.equals("bar") || 
username.equals("all")) &&
+               password.equals("frobnicate");
+         }
+         @Override
+         public boolean validateUserAndRole(
+            final String username,
+            final String password,
+            final Set<Role> requiredRoles,
+            final CheckType checkType) {
+
+            fail("Unexpected call to overridden method");
+            return false;
+         }
+
+         @Override
+         public boolean validateUserAndRole(
+            final String username,
+            final String password,
+            final Set<Role> requiredRoles,
+            final CheckType checkType,
+            final String address,
+            final RemotingConnection connection) {
+
+            if (!(connection.getTransportConnection() instanceof 
InVMConnection)) {
                return false;
             }
-            @Override
-            public boolean validateUser(final String username, final String 
password, final X509Certificate[] certificates) {
-               return (username.equals("foo") || username.equals("bar") || 
username.equals("all")) &&
-                  password.equals("frobnicate");
+
+            if ((username.equals("foo") || username.equals("bar") || 
username.equals("all")) &&
+               password.equals("frobnicate")) {
+
+               if (username.equals("all")) {
+                  return true;
+               }
+               else if (username.equals("foo")) {
+                  return address.equals("test.queue") && checkType == 
CheckType.CONSUME;
+               }
+               else if (username.equals("bar")) {
+                  return address.equals("test.queue") && checkType == 
CheckType.SEND;
+               }
+               else {
+                  return false;
+               }
             }
-            @Override
-            public boolean validateUserAndRole(
-               final String username,
-               final String password,
-               final Set<Role> requiredRoles,
-               final CheckType checkType) {
-
-               fail("Unexpected call to overridden method");
+            else {
                return false;
             }
+         }
+      };
+      final ActiveMQServer server = addServer(new 
ActiveMQServerImpl(configuration, customSecurityManager));
+      server.start();
 
-            @Override
-            public boolean validateUserAndRole(
-               final String username,
-               final String password,
-               final Set<Role> requiredRoles,
-               final CheckType checkType,
-               final String address,
-               final RemotingConnection connection) {
+      final ServerLocator locator = createInVMNonHALocator();
+      locator.setBlockOnNonDurableSend(true).setBlockOnDurableSend(true);
+      final ClientSessionFactory factory = createSessionFactory(locator);
+      ClientSession adminSession = factory.createSession("all", "frobnicate", 
false, true, true, false, -1);
 
-               if (!(connection.getTransportConnection() instanceof 
InVMConnection)) {
-                  return false;
-               }
+      final String queueName = "test.queue";
+      adminSession.createQueue(queueName, queueName, false);
+
+      final String otherQueueName = "other.queue";
+      adminSession.createQueue(otherQueueName, otherQueueName, false);
+
+      // Wrong user name
+      try {
+         factory.createSession("baz", "frobnicate", false, true, true, false, 
-1);
+         Assert.fail("should throw exception");
+      }
+      catch (ActiveMQSecurityException se) {
+         //ok
+      }
+      catch (ActiveMQException e) {
+         fail("Invalid Exception type:" + e.getType());
+      }
 
-               if ((username.equals("foo") || username.equals("bar") || 
username.equals("all")) &&
-                   password.equals("frobnicate")) {
-
-                  if (username.equals("all")) {
-                     return true;
-                  }
-                  else if (username.equals("foo")) {
-                     return address.equals("test.queue") && checkType == 
CheckType.CONSUME;
-                  }
-                  else if (username.equals("bar")) {
-                     return address.equals("test.queue") && checkType == 
CheckType.SEND;
-                  }
-                  else {
-                     return false;
-                  }
+      // Wrong password
+      try {
+         factory.createSession("foo", "xxx", false, true, true, false, -1);
+         Assert.fail("should throw exception");
+      }
+      catch (ActiveMQSecurityException se) {
+         //ok
+      }
+      catch (ActiveMQException e) {
+         fail("Invalid Exception type:" + e.getType());
+      }
+
+      // Correct user and password, wrong queue for sending
+      try {
+         final ClientSession session = factory.createSession("foo", 
"frobnicate", false, true, true, false, -1);
+         checkUserReceiveNoSend(otherQueueName, session, adminSession);
+         Assert.fail("should throw exception");
+      }
+      catch (ActiveMQSecurityException se) {
+         //ok
+      }
+      catch (ActiveMQException e) {
+         fail("Invalid Exception type:" + e.getType());
+      }
+
+      // Correct user and password, wrong queue for receiving
+      try {
+         final ClientSession session = factory.createSession("foo", 
"frobnicate", false, true, true, false, -1);
+         checkUserReceiveNoSend(otherQueueName, session, adminSession);
+         Assert.fail("should throw exception");
+      }
+      catch (ActiveMQSecurityException se) {
+         //ok
+      }
+      catch (ActiveMQException e) {
+         fail("Invalid Exception type:" + e.getType());
+      }
+
+      // Correct user and password, allowed to send but not receive
+      {
+         final ClientSession session = factory.createSession("foo", 
"frobnicate", false, true, true, false, -1);
+         checkUserReceiveNoSend(queueName, session, adminSession);
+      }
+
+      // Correct user and password, allowed to receive but not send
+      {
+         final ClientSession session = factory.createSession("bar", 
"frobnicate", false, true, true, false, -1);
+         checkUserSendNoReceive(queueName, session);
+      }
+   }
+
+   @Test
+   public void testCustomSecurityManager3() throws Exception {
+      final Configuration configuration = 
createDefaultInVMConfig().setSecurityEnabled(true);
+      final ActiveMQSecurityManager customSecurityManager = new 
ActiveMQSecurityManager3() {
+         @Override
+         public boolean validateUser(final String username, final String 
password) {
+            fail("Unexpected call to overridden method");
+            return false;
+         }
+         @Override
+         public String validateUser(final String username, final String 
password, final X509Certificate[] certificates) {
+            if ((username.equals("foo") || username.equals("bar") || 
username.equals("all")) && password.equals("frobnicate")) {
+               return username;
+            }
+            else {
+               return null;
+            }
+         }
+         @Override
+         public boolean validateUserAndRole(
+            final String username,
+            final String password,
+            final Set<Role> requiredRoles,
+            final CheckType checkType) {
+
+            fail("Unexpected call to overridden method");
+            return false;
+         }
+
+         @Override
+         public String validateUserAndRole(
+            final String username,
+            final String password,
+            final Set<Role> requiredRoles,
+            final CheckType checkType,
+            final String address,
+            final RemotingConnection connection) {
+
+            if (!(connection.getTransportConnection() instanceof 
InVMConnection)) {
+               return null;
+            }
+
+            if ((username.equals("foo") || username.equals("bar") || 
username.equals("all")) &&
+               password.equals("frobnicate")) {
+
+               if (username.equals("all")) {
+                  return username;
+               }
+               else if (username.equals("foo")) {
+                  if (address.equals("test.queue") && checkType == 
CheckType.CONSUME)
+                     return username;
+                  else
+                     return null;
+               }
+               else if (username.equals("bar")) {
+                  if (address.equals("test.queue") && checkType == 
CheckType.SEND)
+                     return username;
+                  else
+                     return null;
                }
                else {
-                  return false;
+                  return null;
                }
             }
-         };
+            else {
+               return null;
+            }
+         }
+      };
       final ActiveMQServer server = addServer(new 
ActiveMQServerImpl(configuration, customSecurityManager));
       server.start();
 

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/765b2259/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/stomp/StompTestBase.java
----------------------------------------------------------------------
diff --git 
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/stomp/StompTestBase.java
 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/stomp/StompTestBase.java
index 827bf68..f2def06 100644
--- 
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/stomp/StompTestBase.java
+++ 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/stomp/StompTestBase.java
@@ -30,6 +30,7 @@ import java.net.Socket;
 import java.net.URISyntaxException;
 import java.nio.charset.StandardCharsets;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Map;
 import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.BlockingQueue;
@@ -50,8 +51,6 @@ import io.netty.channel.socket.nio.NioSocketChannel;
 import io.netty.handler.codec.string.StringDecoder;
 import io.netty.handler.codec.string.StringEncoder;
 import org.apache.activemq.artemis.api.core.TransportConfiguration;
-import org.apache.activemq.artemis.tests.unit.util.InVMNamingContext;
-import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
 import org.apache.activemq.artemis.core.config.Configuration;
 import 
org.apache.activemq.artemis.core.protocol.stomp.StompProtocolManagerFactory;
 import org.apache.activemq.artemis.core.registry.JndiBindingRegistry;
@@ -59,6 +58,7 @@ import 
org.apache.activemq.artemis.core.remoting.impl.invm.InVMAcceptorFactory;
 import 
org.apache.activemq.artemis.core.remoting.impl.invm.InVMConnectorFactory;
 import 
org.apache.activemq.artemis.core.remoting.impl.netty.NettyAcceptorFactory;
 import org.apache.activemq.artemis.core.remoting.impl.netty.TransportConstants;
+import org.apache.activemq.artemis.core.security.Role;
 import org.apache.activemq.artemis.core.server.ActiveMQServer;
 import org.apache.activemq.artemis.core.server.ActiveMQServers;
 import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory;
@@ -69,6 +69,9 @@ import 
org.apache.activemq.artemis.jms.server.config.impl.JMSConfigurationImpl;
 import 
org.apache.activemq.artemis.jms.server.config.impl.JMSQueueConfigurationImpl;
 import 
org.apache.activemq.artemis.jms.server.config.impl.TopicConfigurationImpl;
 import org.apache.activemq.artemis.jms.server.impl.JMSServerManagerImpl;
+import 
org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager;
+import org.apache.activemq.artemis.tests.unit.util.InVMNamingContext;
+import org.apache.activemq.artemis.tests.util.ActiveMQTestBase;
 import org.junit.After;
 import org.junit.Before;
 
@@ -116,7 +119,12 @@ public abstract class StompTestBase extends 
ActiveMQTestBase {
          connectionFactory = createConnectionFactory();
          createBootstrap();
 
-         connection = connectionFactory.createConnection();
+         if (isSecurityEnabled()) {
+            connection = connectionFactory.createConnection("brianm", 
"wombats");
+         }
+         else {
+            connection = connectionFactory.createConnection();
+         }
          session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
          queue = session.createQueue(getQueueName());
          topic = session.createTopic(getTopicName());
@@ -185,11 +193,23 @@ public abstract class StompTestBase extends 
ActiveMQTestBase {
       TransportConfiguration stompTransport = new 
TransportConfiguration(NettyAcceptorFactory.class.getName(), params);
       TransportConfiguration allTransport = new 
TransportConfiguration(NettyAcceptorFactory.class.getName());
 
-      Configuration config = 
createBasicConfig().setPersistenceEnabled(false).addAcceptorConfiguration(stompTransport).addAcceptorConfiguration(new
 TransportConfiguration(InVMAcceptorFactory.class.getName()));
+      Configuration config = 
createBasicConfig().setSecurityEnabled(isSecurityEnabled()).setPersistenceEnabled(false).addAcceptorConfiguration(stompTransport).addAcceptorConfiguration(new
 TransportConfiguration(InVMAcceptorFactory.class.getName()));
       config.addAcceptorConfiguration(allTransport);
 
       ActiveMQServer activeMQServer = 
addServer(ActiveMQServers.newActiveMQServer(config, defUser, defPass));
 
+      if (isSecurityEnabled()) {
+         ActiveMQJAASSecurityManager securityManager = 
(ActiveMQJAASSecurityManager) activeMQServer.getSecurityManager();
+
+         final String role = "testRole";
+         securityManager.getConfiguration().addRole(defUser, role);
+         config.getSecurityRoles().put("#", new HashSet<Role>() {
+            {
+               add(new Role(role, true, true, true, true, true, true, true));
+            }
+         });
+      }
+
       JMSConfiguration jmsConfig = new JMSConfigurationImpl();
       jmsConfig.getQueueConfigurations().add(new 
JMSQueueConfigurationImpl().setName(getQueueName()).setDurable(false).setBindings(getQueueName()));
       jmsConfig.getTopicConfigurations().add(new 
TopicConfigurationImpl().setName(getTopicName()).setBindings(getTopicName()));
@@ -319,6 +339,10 @@ public abstract class StompTestBase extends 
ActiveMQTestBase {
       Thread.sleep(500);
    }
 
+   public boolean isSecurityEnabled() {
+      return false;
+   }
+
    class StompClientHandler extends SimpleChannelInboundHandler<String> {
 
       StringBuffer currentMessage = new StringBuffer("");

http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/765b2259/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/stomp/StompTestWithSecurity.java
----------------------------------------------------------------------
diff --git 
a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/stomp/StompTestWithSecurity.java
 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/stomp/StompTestWithSecurity.java
new file mode 100644
index 0000000..40e8a63
--- /dev/null
+++ 
b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/stomp/StompTestWithSecurity.java
@@ -0,0 +1,61 @@
+/*
+ * 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
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.integration.stomp;
+
+import javax.jms.MessageConsumer;
+import javax.jms.TextMessage;
+
+import org.apache.activemq.artemis.core.protocol.stomp.Stomp;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class StompTestWithSecurity extends StompTestBase {
+
+   @Test
+   public void testJMSXUserID() throws Exception {
+      
server.getActiveMQServer().getConfiguration().setPopulateValidatedUser(true);
+
+      MessageConsumer consumer = session.createConsumer(queue);
+
+      String frame = "CONNECT\n" + "login: brianm\n" + "passcode: wombats\n\n" 
+ Stomp.NULL;
+      sendFrame(frame);
+
+      frame = receiveFrame(10000);
+      Assert.assertTrue(frame.startsWith("CONNECTED"));
+
+      frame = "SEND\n" + "destination:" + getQueuePrefix() + getQueueName() + 
"\n\n" + "Hello World" + Stomp.NULL;
+
+      sendFrame(frame);
+
+      TextMessage message = (TextMessage) consumer.receive(1000);
+      Assert.assertNotNull(message);
+      Assert.assertEquals("Hello World", message.getText());
+      // Assert default priority 4 is used when priority header is not set
+      Assert.assertEquals("getJMSPriority", 4, message.getJMSPriority());
+      Assert.assertEquals("JMSXUserID", "brianm", 
message.getStringProperty("JMSXUserID"));
+
+      // Make sure that the timestamp is valid - should
+      // be very close to the current time.
+      long tnow = System.currentTimeMillis();
+      long tmsg = message.getJMSTimestamp();
+      Assert.assertTrue(Math.abs(tnow - tmsg) < 1000);
+   }
+
+   public boolean isSecurityEnabled() {
+      return true;
+   }
+}

Reply via email to