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 2021/02/07 16:18:39 UTC

[activemq-artemis] branch master updated: ARTEMIS-33 Generic integration with SASL Frameworks

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 0bedb30  ARTEMIS-33 Generic integration with SASL Frameworks
     new 76e3592  This closes #3432
0bedb30 is described below

commit 0bedb3048a1fcdd0e2604d2341842967e8fab628
Author: Christoph Läubrich <ch...@laeubi-soft.de>
AuthorDate: Fri Feb 5 06:16:01 2021 +0100

    ARTEMIS-33 Generic integration with SASL Frameworks
    
    This adds the opportunity to register new SASL schemes via the default
    java service-loader mechanism.
    Implementors have to provide an implementation of the ServerSASLFactory
    that is responsible for providing instances of the actual scheme.
---
 .../amqp/broker/AMQPConnectionCallback.java        | 44 +++------------
 .../amqp/broker/ProtonProtocolManager.java         |  2 +-
 .../amqp/sasl/AnonymousServerSASLFactory.java      | 48 ++++++++++++++++
 .../amqp/sasl/ExternalServerSASLFactory.java       | 65 ++++++++++++++++++++++
 .../amqp/sasl/GSSAPIServerSASLFactory.java         | 58 +++++++++++++++++++
 .../protocol/amqp/sasl/MechanismFinder.java        | 38 ++++++++++++-
 .../protocol/amqp/sasl/PlainServerSASLFactory.java | 48 ++++++++++++++++
 .../protocol/amqp/sasl/ServerSASLFactory.java      | 58 +++++++++++++++++++
 ...mq.artemis.protocol.amqp.sasl.ServerSASLFactory |  4 ++
 9 files changed, 325 insertions(+), 40 deletions(-)

diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/AMQPConnectionCallback.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/AMQPConnectionCallback.java
index 6cf4c8a..71dcfde 100644
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/AMQPConnectionCallback.java
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/AMQPConnectionCallback.java
@@ -17,7 +17,6 @@
 package org.apache.activemq.artemis.protocol.amqp.broker;
 
 import java.net.URI;
-import java.security.Principal;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
@@ -29,7 +28,6 @@ import org.apache.activemq.artemis.api.core.ActiveMQBuffers;
 import org.apache.activemq.artemis.api.core.ActiveMQException;
 import org.apache.activemq.artemis.core.buffers.impl.ChannelBufferWrapper;
 import org.apache.activemq.artemis.core.client.impl.TopologyMemberImpl;
-import org.apache.activemq.artemis.core.remoting.CertificateUtil;
 import org.apache.activemq.artemis.core.remoting.CloseListener;
 import org.apache.activemq.artemis.core.remoting.FailureListener;
 import org.apache.activemq.artemis.core.server.ActiveMQServer;
@@ -44,11 +42,10 @@ import org.apache.activemq.artemis.protocol.amqp.proton.AmqpSupport;
 import org.apache.activemq.artemis.protocol.amqp.proton.handler.ExtCapability;
 import org.apache.activemq.artemis.protocol.amqp.proton.transaction.ProtonTransactionImpl;
 import org.apache.activemq.artemis.protocol.amqp.sasl.AnonymousServerSASL;
-import org.apache.activemq.artemis.protocol.amqp.sasl.ExternalServerSASL;
-import org.apache.activemq.artemis.protocol.amqp.sasl.GSSAPIServerSASL;
-import org.apache.activemq.artemis.protocol.amqp.sasl.PlainSASL;
+import org.apache.activemq.artemis.protocol.amqp.sasl.MechanismFinder;
 import org.apache.activemq.artemis.protocol.amqp.sasl.SASLResult;
 import org.apache.activemq.artemis.protocol.amqp.sasl.ServerSASL;
+import org.apache.activemq.artemis.protocol.amqp.sasl.ServerSASLFactory;
 import org.apache.activemq.artemis.spi.core.remoting.Connection;
 import org.apache.activemq.artemis.spi.core.remoting.ReadyListener;
 import org.apache.activemq.artemis.utils.UUIDGenerator;
@@ -63,7 +60,7 @@ public class AMQPConnectionCallback implements FailureListener, CloseListener {
 
    private static final Logger logger = Logger.getLogger(AMQPConnectionCallback.class);
 
-   private ConcurrentMap<Binary, Transaction> transactions = new ConcurrentHashMap<>();
+   private final ConcurrentMap<Binary, Transaction> transactions = new ConcurrentHashMap<>();
 
    private final ProtonProtocolManager manager;
 
@@ -105,36 +102,11 @@ public class AMQPConnectionCallback implements FailureListener, CloseListener {
    public ServerSASL getServerSASL(final String mechanism) {
       ServerSASL result = null;
       if (isPermittedMechanism(mechanism)) {
-         switch (mechanism) {
-            case PlainSASL.NAME:
-               result = new PlainSASL(server.getSecurityStore(), manager.getSecurityDomain(), connection.getProtocolConnection());
-               break;
-
-            case AnonymousServerSASL.NAME:
-               result = new AnonymousServerSASL();
-               break;
-
-            case GSSAPIServerSASL.NAME:
-               GSSAPIServerSASL gssapiServerSASL = new GSSAPIServerSASL();
-               gssapiServerSASL.setLoginConfigScope(manager.getSaslLoginConfigScope());
-               result = gssapiServerSASL;
-               break;
-
-            case ExternalServerSASL.NAME:
-               // validate ssl cert present
-               Principal principal = CertificateUtil.getPeerPrincipalFromConnection(protonConnectionDelegate);
-               if (principal != null) {
-                  ExternalServerSASL externalServerSASL = new ExternalServerSASL();
-                  externalServerSASL.setPrincipal(principal);
-                  result = externalServerSASL;
-               } else {
-                  logger.debug("SASL EXTERNAL mechanism requires a TLS peer principal");
-               }
-               break;
-
-            default:
-               logger.debug("Mo matching mechanism found for: " + mechanism);
-               break;
+         ServerSASLFactory factory = MechanismFinder.getFactory(mechanism);
+         if (factory != null) {
+            result = factory.create(server, manager, connection, protonConnectionDelegate);
+         } else {
+            logger.debug("Mo matching mechanism found for: " + mechanism);
          }
       }
       return result;
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/ProtonProtocolManager.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/ProtonProtocolManager.java
index 666abb1..4940819 100644
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/ProtonProtocolManager.java
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/ProtonProtocolManager.java
@@ -88,7 +88,7 @@ public class ProtonProtocolManager extends AbstractProtocolManager<AMQPMessage,
 
    private int initialRemoteMaxFrameSize = 4 * 1024;
 
-   private String[] saslMechanisms = MechanismFinder.getKnownMechanisms();
+   private String[] saslMechanisms = MechanismFinder.getDefaultMechanisms();
 
    private String saslLoginConfigScope = "amqp-sasl-gssapi";
 
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/AnonymousServerSASLFactory.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/AnonymousServerSASLFactory.java
new file mode 100644
index 0000000..82d3ec1
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/AnonymousServerSASLFactory.java
@@ -0,0 +1,48 @@
+/*
+ * 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.protocol.amqp.sasl;
+
+import org.apache.activemq.artemis.core.server.ActiveMQServer;
+import org.apache.activemq.artemis.protocol.amqp.broker.AmqpInterceptor;
+import org.apache.activemq.artemis.spi.core.protocol.ProtocolManager;
+import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
+import org.apache.activemq.artemis.spi.core.remoting.Connection;
+
+public class AnonymousServerSASLFactory implements ServerSASLFactory {
+
+   @Override
+   public String getMechanism() {
+      return AnonymousServerSASL.NAME;
+   }
+
+   @Override
+   public ServerSASL create(ActiveMQServer server, ProtocolManager<AmqpInterceptor> manager, Connection connection,
+                            RemotingConnection remotingConnection) {
+      return new AnonymousServerSASL();
+   }
+
+   @Override
+   public int getPrecedence() {
+      return Integer.MIN_VALUE;
+   }
+
+   @Override
+   public boolean isDefaultPermitted() {
+      return true;
+   }
+
+}
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/ExternalServerSASLFactory.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/ExternalServerSASLFactory.java
new file mode 100644
index 0000000..e9087be
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/ExternalServerSASLFactory.java
@@ -0,0 +1,65 @@
+/*
+ * 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.protocol.amqp.sasl;
+
+import java.security.Principal;
+
+import org.apache.activemq.artemis.core.remoting.CertificateUtil;
+import org.apache.activemq.artemis.core.server.ActiveMQServer;
+import org.apache.activemq.artemis.protocol.amqp.broker.AmqpInterceptor;
+import org.apache.activemq.artemis.spi.core.protocol.ProtocolManager;
+import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
+import org.apache.activemq.artemis.spi.core.remoting.Connection;
+import org.jboss.logging.Logger;
+
+/**
+ *
+ */
+public class ExternalServerSASLFactory implements ServerSASLFactory {
+
+   private static final Logger logger = Logger.getLogger(ExternalServerSASLFactory.class);
+
+   @Override
+   public String getMechanism() {
+      return ExternalServerSASL.NAME;
+   }
+
+   @Override
+   public ServerSASL create(ActiveMQServer server, ProtocolManager<AmqpInterceptor> manager, Connection connection,
+                            RemotingConnection remotingConnection) {
+      // validate ssl cert present
+      Principal principal = CertificateUtil.getPeerPrincipalFromConnection(remotingConnection);
+      if (principal != null) {
+         ExternalServerSASL externalServerSASL = new ExternalServerSASL();
+         externalServerSASL.setPrincipal(principal);
+         return externalServerSASL;
+      }
+      logger.debug("SASL EXTERNAL mechanism requires a TLS peer principal");
+      return null;
+   }
+
+   @Override
+   public int getPrecedence() {
+      return 0;
+   }
+
+   @Override
+   public boolean isDefaultPermitted() {
+      return false;
+   }
+
+}
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/GSSAPIServerSASLFactory.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/GSSAPIServerSASLFactory.java
new file mode 100644
index 0000000..e31632a
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/GSSAPIServerSASLFactory.java
@@ -0,0 +1,58 @@
+/*
+ * 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.protocol.amqp.sasl;
+
+import org.apache.activemq.artemis.core.server.ActiveMQServer;
+import org.apache.activemq.artemis.protocol.amqp.broker.AmqpInterceptor;
+import org.apache.activemq.artemis.protocol.amqp.broker.ProtonProtocolManager;
+import org.apache.activemq.artemis.spi.core.protocol.ProtocolManager;
+import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
+import org.apache.activemq.artemis.spi.core.remoting.Connection;
+import org.jboss.logging.Logger;
+
+public class GSSAPIServerSASLFactory implements ServerSASLFactory {
+
+   private static final Logger logger = Logger.getLogger(GSSAPIServerSASLFactory.class);
+
+   @Override
+   public String getMechanism() {
+      return GSSAPIServerSASL.NAME;
+   }
+
+   @Override
+   public ServerSASL create(ActiveMQServer server, ProtocolManager<AmqpInterceptor> manager, Connection connection,
+                            RemotingConnection remotingConnection) {
+      if (manager instanceof ProtonProtocolManager) {
+         GSSAPIServerSASL gssapiServerSASL = new GSSAPIServerSASL();
+         gssapiServerSASL.setLoginConfigScope(((ProtonProtocolManager) manager).getSaslLoginConfigScope());
+         return gssapiServerSASL;
+      }
+      logger.debug("SASL GSSAPI requires ProtonProtocolManager");
+      return null;
+   }
+
+   @Override
+   public int getPrecedence() {
+      return 0;
+   }
+
+   @Override
+   public boolean isDefaultPermitted() {
+      return false;
+   }
+
+}
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/MechanismFinder.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/MechanismFinder.java
index fd24a5d..62551f0 100644
--- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/MechanismFinder.java
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/MechanismFinder.java
@@ -17,11 +17,43 @@
 
 package org.apache.activemq.artemis.protocol.amqp.sasl;
 
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.ServiceLoader;
+
 public class MechanismFinder {
 
-   public static String[] KNOWN_MECHANISMS = new String[]{PlainSASL.NAME, AnonymousServerSASL.NAME};
+   private static final Map<String, ServerSASLFactory> FACTORY_MAP = new HashMap<>();
+   private static final Comparator<? super ServerSASLFactory> PRECEDENCE_COMPARATOR =
+      (f1, f2) -> Integer.compare(f1.getPrecedence(), f2.getPrecedence());
+   private static final String[] DEFAULT_MECHANISMS;
+
+   static {
+      ServiceLoader<ServerSASLFactory> serviceLoader =
+               ServiceLoader.load(ServerSASLFactory.class, MechanismFinder.class.getClassLoader());
+      for (ServerSASLFactory factory : serviceLoader) {
+         FACTORY_MAP.merge(factory.getMechanism(), factory, (f1, f2) -> {
+            if (f2.getPrecedence() > f1.getPrecedence()) {
+               return f2;
+            } else {
+               return f1;
+            }
+         });
+      }
+      DEFAULT_MECHANISMS = FACTORY_MAP.values()
+                                      .stream()
+                                      .filter(ServerSASLFactory::isDefaultPermitted)
+                                      .sorted(PRECEDENCE_COMPARATOR.reversed())
+                                      .map(ServerSASLFactory::getMechanism)
+                                      .toArray(String[]::new);
+   }
+
+   public static String[] getDefaultMechanisms() {
+      return DEFAULT_MECHANISMS;
+   }
 
-   public static String[] getKnownMechanisms() {
-      return KNOWN_MECHANISMS;
+   public static ServerSASLFactory getFactory(String mechanism) {
+      return FACTORY_MAP.get(mechanism);
    }
 }
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/PlainServerSASLFactory.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/PlainServerSASLFactory.java
new file mode 100644
index 0000000..5a88a82
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/PlainServerSASLFactory.java
@@ -0,0 +1,48 @@
+/*
+ * 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.protocol.amqp.sasl;
+
+import org.apache.activemq.artemis.core.server.ActiveMQServer;
+import org.apache.activemq.artemis.protocol.amqp.broker.AmqpInterceptor;
+import org.apache.activemq.artemis.spi.core.protocol.ProtocolManager;
+import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
+import org.apache.activemq.artemis.spi.core.remoting.Connection;
+
+public class PlainServerSASLFactory implements ServerSASLFactory {
+
+   @Override
+   public String getMechanism() {
+      return ServerSASLPlain.NAME;
+   }
+
+   @Override
+   public ServerSASL create(ActiveMQServer server, ProtocolManager<AmqpInterceptor> manager, Connection connection,
+                            RemotingConnection remotingConnection) {
+      return new PlainSASL(server.getSecurityStore(), manager.getSecurityDomain(), connection.getProtocolConnection());
+   }
+
+   @Override
+   public int getPrecedence() {
+      return 0;
+   }
+
+   @Override
+   public boolean isDefaultPermitted() {
+      return true;
+   }
+
+}
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/ServerSASLFactory.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/ServerSASLFactory.java
new file mode 100644
index 0000000..9831652
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/sasl/ServerSASLFactory.java
@@ -0,0 +1,58 @@
+/*
+ * 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.protocol.amqp.sasl;
+
+import org.apache.activemq.artemis.core.server.ActiveMQServer;
+import org.apache.activemq.artemis.protocol.amqp.broker.AmqpInterceptor;
+import org.apache.activemq.artemis.spi.core.protocol.ProtocolManager;
+import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection;
+import org.apache.activemq.artemis.spi.core.remoting.Connection;
+
+/**
+ * A {@link ServerSASLFactory} is responsible for instantiating a given SASL mechanism
+ */
+public interface ServerSASLFactory {
+
+   /**
+    * @return the name of the scheme to offer
+    */
+   String getMechanism();
+
+   /**
+    * creates a new {@link ServerSASL} for the provided context
+    * @param server
+    * @param manager
+    * @param connection
+    * @param remotingConnection
+    * @return a new instance of {@link ServerSASL} that implements the provided mechanism
+    */
+   ServerSASL create(ActiveMQServer server, ProtocolManager<AmqpInterceptor> manager, Connection connection,
+                     RemotingConnection remotingConnection);
+
+   /**
+    * returns the precedence of the given SASL mechanism, the default precedence is zero, where
+    * higher means better
+    * @return the precedence of this mechanism
+    */
+   int getPrecedence();
+
+   /**
+    * @return <code>true</code> if this mechanism should be part of the servers default permitted
+    *         protocols or <code>false</code> if it must be explicitly configured
+    */
+   boolean isDefaultPermitted();
+}
diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/resources/META-INF/services/org.apache.activemq.artemis.protocol.amqp.sasl.ServerSASLFactory b/artemis-protocols/artemis-amqp-protocol/src/main/resources/META-INF/services/org.apache.activemq.artemis.protocol.amqp.sasl.ServerSASLFactory
new file mode 100644
index 0000000..eb2c112
--- /dev/null
+++ b/artemis-protocols/artemis-amqp-protocol/src/main/resources/META-INF/services/org.apache.activemq.artemis.protocol.amqp.sasl.ServerSASLFactory
@@ -0,0 +1,4 @@
+org.apache.activemq.artemis.protocol.amqp.sasl.AnonymousServerSASLFactory
+org.apache.activemq.artemis.protocol.amqp.sasl.PlainServerSASLFactory
+org.apache.activemq.artemis.protocol.amqp.sasl.GSSAPIServerSASLFactory
+org.apache.activemq.artemis.protocol.amqp.sasl.ExternalServerSASLFactory
\ No newline at end of file