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 2016/07/06 15:43:46 UTC
[1/2] activemq-artemis git commit: ARTEMIS-584 add validated user to
msg
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 <jb...@apache.org>
Authored: Tue Jun 28 21:33:44 2016 -0500
Committer: jbertram <jb...@apache.org>
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;
+ }
+}
[2/2] activemq-artemis git commit: This closes #621
Posted by cl...@apache.org.
This closes #621
Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/b3ffac30
Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/b3ffac30
Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/b3ffac30
Branch: refs/heads/master
Commit: b3ffac30eafd9f131797f833498d75fa949b8a1f
Parents: 2b62bc7 765b225
Author: Clebert Suconic <cl...@apache.org>
Authored: Wed Jul 6 11:43:30 2016 -0400
Committer: Clebert Suconic <cl...@apache.org>
Committed: Wed Jul 6 11:43:30 2016 -0400
----------------------------------------------------------------------
.../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(-)
----------------------------------------------------------------------