To run the example, simply type mvn verify from this directory, or mvn -PnoServer verify if you want to start and create the server manually.
+
+
This example shows you how to configure 2-way SSL along with 2 different authentications mechanisms so that SSL and non-SSL clients can send and consume messages to/from ActiveMQ Artemis.
+ The non-SSL authentication mechanism simply uses username and password. The SSL authentication mechanism uses the client's certificate. The Stomp client uses SSL socket directly to send
+ a message. Then a JMS client will use a non-SSL connection to consume it.
+
+
The various keystore files are generated using the following commands:
+
+
diff --git a/examples/protocols/stomp/stomp-dual-authentication/src/main/java/org/apache/activemq/artemis/jms/example/StompDualAuthenticationExample.java b/examples/protocols/stomp/stomp-dual-authentication/src/main/java/org/apache/activemq/artemis/jms/example/StompDualAuthenticationExample.java
new file mode 100644
index 0000000000..1694cf11a4
--- /dev/null
+++ b/examples/protocols/stomp/stomp-dual-authentication/src/main/java/org/apache/activemq/artemis/jms/example/StompDualAuthenticationExample.java
@@ -0,0 +1,141 @@
+/*
+ * 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.jms.example;
+
+import javax.jms.Connection;
+import javax.jms.ConnectionFactory;
+import javax.jms.MessageConsumer;
+import javax.jms.Queue;
+import javax.jms.Session;
+import javax.jms.TextMessage;
+import javax.naming.InitialContext;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.nio.charset.StandardCharsets;
+import java.security.Security;
+
+import com.sun.net.ssl.internal.ssl.Provider;
+
+/**
+ * An example where a client will send a Stomp message on a TCP socket
+ * and consume it from a JMS MessageConsumer.
+ */
+public class StompDualAuthenticationExample {
+
+ private static final String END_OF_FRAME = "\u0000";
+
+ public static void main(final String[] args) throws Exception {
+ // set up SSL keystores for Stomp connection
+ System.setProperty("javax.net.ssl.keyStore", args[0]);
+ System.setProperty("javax.net.ssl.keyStorePassword", args[1]);
+ System.setProperty("javax.net.ssl.trustStore", args[2]);
+ System.setProperty("javax.net.ssl.trustStorePassword", args[3]);
+
+ Connection connection = null;
+ InitialContext initialContext = null;
+ Security.addProvider(new Provider());
+
+ try {
+ // Step 1. Create an SSL socket to connect to the broker
+ SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
+ SSLSocket socket = (SSLSocket) sslsocketfactory.createSocket("localhost", 5500);
+
+ // Step 2. Send a CONNECT frame to connect to the server
+ String connectFrame = "CONNECT\n" +
+ "request-id: 1\n" +
+ "\n" +
+ END_OF_FRAME;
+ sendFrame(socket, connectFrame);
+
+ readFrame(socket);
+
+ // Step 3. Send a SEND frame (a Stomp message) to the
+ // jms.queue.exampleQueue address with a text body
+ String text = "Hello, world from Stomp!";
+ String message = "SEND\n" +
+ "destination: jms.queue.exampleQueue\n" +
+ "\n" +
+ text +
+ END_OF_FRAME;
+ sendFrame(socket, message);
+ System.out.println("Sent Stomp message: " + text);
+
+ // Step 4. Send a DISCONNECT frame to disconnect from the server
+ String disconnectFrame = "DISCONNECT\n" +
+ "\n" +
+ END_OF_FRAME;
+ sendFrame(socket, disconnectFrame);
+
+ // Step 5. Slose the TCP socket
+ socket.close();
+
+ // We will now consume from JMS the message sent with Stomp.
+
+ // Step 6. Create an initial context to perform the JNDI lookup.
+ initialContext = new InitialContext();
+
+ // Step 7. Perform a lookup on the queue and the connection factory
+ Queue queue = (Queue) initialContext.lookup("queue/exampleQueue");
+ ConnectionFactory cf = (ConnectionFactory) initialContext.lookup("ConnectionFactory");
+
+ // Step 8.Create a JMS Connection, Session and a MessageConsumer on the queue
+ connection = cf.createConnection("consumer", "activemq");
+ Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ MessageConsumer consumer = session.createConsumer(queue);
+
+ // Step 9. Start the Connection
+ connection.start();
+
+ // Step 10. Receive the message
+ TextMessage messageReceived = (TextMessage) consumer.receive(5000);
+ System.out.println("Received JMS message: " + messageReceived.getText());
+ }
+ finally {
+ // Step 11. Be sure to close our JMS resources!
+ if (initialContext != null) {
+ initialContext.close();
+ }
+ if (connection != null) {
+ connection.close();
+ }
+ }
+ }
+
+ private static void sendFrame(Socket socket, String data) throws Exception {
+ byte[] bytes = data.getBytes(StandardCharsets.UTF_8);
+ OutputStream outputStream = socket.getOutputStream();
+ for (int i = 0; i < bytes.length; i++) {
+ outputStream.write(bytes[i]);
+ }
+ outputStream.flush();
+ }
+
+ private static String readFrame(Socket socket) throws Exception {
+ byte[] bytes = new byte[2048];
+ InputStream inputStream = socket.getInputStream();
+ int nbytes = inputStream.read(bytes);
+ byte[] data = new byte[nbytes];
+ System.arraycopy(bytes, 0, data, 0, data.length);
+ String resp = new String(data, StandardCharsets.UTF_8);
+ System.out.println("Got response from server: " + resp);
+ return resp;
+ }
+
+}
diff --git a/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/artemis-roles.properties b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/artemis-roles.properties
new file mode 100644
index 0000000000..643dfc37d1
--- /dev/null
+++ b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/artemis-roles.properties
@@ -0,0 +1,17 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+consumers=consumer
\ No newline at end of file
diff --git a/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/artemis-users.properties b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/artemis-users.properties
new file mode 100644
index 0000000000..1c68f505dd
--- /dev/null
+++ b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/artemis-users.properties
@@ -0,0 +1,17 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+consumer=activemq
\ No newline at end of file
diff --git a/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/bootstrap.xml b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/bootstrap.xml
new file mode 100644
index 0000000000..2eabc517a6
--- /dev/null
+++ b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/bootstrap.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/broker.xml b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/broker.xml
new file mode 100644
index 0000000000..14fa849c77
--- /dev/null
+++ b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/broker.xml
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ ./data/messaging/bindings
+
+ ./data/messaging/journal
+
+ ./data/messaging/largemessages
+
+ ./data/messaging/paging
+
+
+
+ tcp://localhost:61616
+ tcp://localhost:5500?sslEnabled=true;needClientAuth=true;keyStorePath=${data.dir}/../etc/server-side-keystore.jks;keyStorePassword=secureexample;trustStorePath=${data.dir}/../etc/server-side-truststore.jks;trustStorePassword=secureexample
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/cert-roles.properties b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/cert-roles.properties
new file mode 100644
index 0000000000..f52fa21753
--- /dev/null
+++ b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/cert-roles.properties
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+producers=producer
diff --git a/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/cert-users.properties b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/cert-users.properties
new file mode 100644
index 0000000000..06874dc5e9
--- /dev/null
+++ b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/cert-users.properties
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+producer=CN=ActiveMQ Artemis Client, OU=Artemis, O=ActiveMQ, L=AMQ, ST=AMQ, C=AMQ
diff --git a/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/client-side-keystore.jks b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/client-side-keystore.jks
new file mode 100644
index 0000000000..cb65a44ddc
Binary files /dev/null and b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/client-side-keystore.jks differ
diff --git a/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/client-side-truststore.jks b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/client-side-truststore.jks
new file mode 100644
index 0000000000..7eb1d5634d
Binary files /dev/null and b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/client-side-truststore.jks differ
diff --git a/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/login.config b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/login.config
new file mode 100644
index 0000000000..9bd479d204
--- /dev/null
+++ b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/login.config
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+activemq {
+ org.apache.activemq.artemis.spi.core.security.jaas.PropertiesLoginModule required
+ debug=false
+ org.apache.activemq.jaas.properties.user="artemis-users.properties"
+ org.apache.activemq.jaas.properties.role="artemis-roles.properties";
+};
+
+activemq-cert {
+ org.apache.activemq.artemis.spi.core.security.jaas.TextFileCertificateLoginModule required
+ debug=true
+ org.apache.activemq.jaas.textfiledn.user="cert-users.properties"
+ org.apache.activemq.jaas.textfiledn.role="cert-roles.properties";
+};
\ No newline at end of file
diff --git a/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/server-side-keystore.jks b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/server-side-keystore.jks
new file mode 100644
index 0000000000..6089c6ee13
Binary files /dev/null and b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/server-side-keystore.jks differ
diff --git a/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/server-side-truststore.jks b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/server-side-truststore.jks
new file mode 100644
index 0000000000..0b7e224163
Binary files /dev/null and b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/server-side-truststore.jks differ
diff --git a/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/jndi.properties b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/jndi.properties
new file mode 100644
index 0000000000..93537c415a
--- /dev/null
+++ b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/jndi.properties
@@ -0,0 +1,20 @@
+# 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.
+
+java.naming.factory.initial=org.apache.activemq.artemis.jndi.ActiveMQInitialContextFactory
+connectionFactory.ConnectionFactory=tcp://localhost:61616
+queue.queue/exampleQueue=exampleQueue