From 4574f711aea1ad2ebddfa6d9e0726286e79d6ed8 Mon Sep 17 00:00:00 2001 From: Calvin Kirs Date: Thu, 29 Aug 2024 16:15:58 +0800 Subject: [PATCH 1/3] [feat](Authenticator) Pluginization of Authenticator introduces the pluginization of the Authenticator component, enabling greater flexibility and modularity within the authentication system. By refactoring the Authenticator into a pluggable SPI (Service Provider Interface), we allow for custom authentication mechanisms to be seamlessly integrated and managed. Key Changes AuthenticatorFactory Interface: Defined a new AuthenticatorFactory interface to standardize the creation of Authenticator instances. The interface includes methods to create Authenticator instances based on configuration (ConfigBase) and to return a unique identifier for each factory (e.g., "ldap", "default"). The interface also provides a method getAuthenticatorConfig() to retrieve default configuration templates, aiding in the initialization process. Factory Identifier: Each AuthenticatorFactory implementation must provide a unique identifier. This allows for easy registration and retrieval of specific Authenticator implementations based on the factory identifier. Configuration Management: The getAuthenticatorConfig() method returns a ConfigBase instance, providing a default configuration that can be used or modified before creating an Authenticator. Benefits Modularity: Authentication logic is now decoupled from the core system, making it easier to extend and maintain. Flexibility: Different authentication strategies (e.g., LDAP, default, etc.) can be easily added or swapped without altering the core codebase. Customization: Users can define custom Authenticator implementations and configure them as needed, enabling a more tailored authentication process. --- .../java/org/apache/doris/catalog/Env.java | 2 +- .../mysql/authenticate/AuthenticateType.java | 18 ++++++ .../authenticate/AuthenticatorFactory.java | 49 +++++++++++++++ .../authenticate/AuthenticatorManager.java | 59 ++++++++++++++----- .../DefaultAuthenticatorFactory.java | 37 ++++++++++++ .../authenticate/ldap/LdapAuthenticator.java | 9 +-- .../ldap/LdapAuthenticatorFactory.java | 41 +++++++++++++ ...is.mysql.authenticate.AuthenticatorFactory | 2 + 8 files changed, 197 insertions(+), 20 deletions(-) create mode 100644 fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/AuthenticatorFactory.java create mode 100644 fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/DefaultAuthenticatorFactory.java create mode 100644 fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorFactory.java create mode 100644 fe/fe-core/src/main/resources/META-INF/services/org.apache.doris.mysql.authenticate.AuthenticatorFactory diff --git a/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java b/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java index 83907255641384..1cf7d4bb184912 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java +++ b/fe/fe-core/src/main/java/org/apache/doris/catalog/Env.java @@ -742,7 +742,7 @@ public Env(boolean isCheckpointCatalog) { this.auth = new Auth(); this.accessManager = new AccessControllerManager(auth); - this.authenticatorManager = new AuthenticatorManager(AuthenticateType.getAuthTypeConfig()); + this.authenticatorManager = new AuthenticatorManager(AuthenticateType.getAuthTypeConfigString()); this.domainResolver = new DomainResolver(auth); this.metaContext = new MetaContext(); diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/AuthenticateType.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/AuthenticateType.java index 4281c19bba6412..1f16c1f541b391 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/AuthenticateType.java +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/AuthenticateType.java @@ -40,4 +40,22 @@ public static AuthenticateType getAuthTypeConfig() { return DEFAULT; } } + + public static String getAuthTypeConfigString() { + String authType = Config.authentication_type.toLowerCase(); + + if (LdapConfig.ldap_authentication_enabled) { + return LDAP.name(); + } + + switch (authType) { + case "default": + return DEFAULT.toString(); + case "ldap": + return LDAP.toString(); + default: + return authType; + } + } + } diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/AuthenticatorFactory.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/AuthenticatorFactory.java new file mode 100644 index 00000000000000..fe8d33accbba99 --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/AuthenticatorFactory.java @@ -0,0 +1,49 @@ +// 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.doris.mysql.authenticate; + +import org.apache.doris.common.ConfigBase; + +public interface AuthenticatorFactory { + /** + * Creates a new instance of Authenticator. + * + * @return an instance of Authenticator + */ + Authenticator create(ConfigBase config); + + /** + * Returns the identifier for the factory, such as "ldap" or "default". + * + * @return the factory identifier + */ + String factoryIdentifier(); + + /** + * Retrieves the configuration template associated with this authenticator. + *

+ * This method provides a default configuration template that can be used + * as a base for initializing the authenticator. The returned configuration + * can be modified as needed before passing it to the `create` method to + * instantiate an authenticator. + * + * @return the configuration template for the authenticator + */ + ConfigBase getAuthenticatorConfig(); +} + diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/AuthenticatorManager.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/AuthenticatorManager.java index c00828f82fad92..337794db1f2e41 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/AuthenticatorManager.java +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/AuthenticatorManager.java @@ -17,20 +17,23 @@ package org.apache.doris.mysql.authenticate; +import org.apache.doris.common.ConfigBase; +import org.apache.doris.common.EnvUtils; import org.apache.doris.mysql.MysqlAuthPacket; import org.apache.doris.mysql.MysqlChannel; import org.apache.doris.mysql.MysqlHandshakePacket; import org.apache.doris.mysql.MysqlProto; import org.apache.doris.mysql.MysqlSerializer; -import org.apache.doris.mysql.authenticate.ldap.LdapAuthenticator; import org.apache.doris.mysql.authenticate.password.Password; import org.apache.doris.qe.ConnectContext; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.io.File; import java.io.IOException; import java.util.Optional; +import java.util.ServiceLoader; public class AuthenticatorManager { private static final Logger LOG = LogManager.getLogger(AuthenticatorManager.class); @@ -38,26 +41,45 @@ public class AuthenticatorManager { private Authenticator defaultAuthenticator; private Authenticator authTypeAuthenticator; - public AuthenticatorManager(AuthenticateType type) { + public AuthenticatorManager(String type) { LOG.info("authenticate type: {}", type); this.defaultAuthenticator = new DefaultAuthenticator(); - switch (type) { - case LDAP: - this.authTypeAuthenticator = new LdapAuthenticator(); - break; - case DEFAULT: - default: - this.authTypeAuthenticator = defaultAuthenticator; - break; + AuthenticatorFactory authenticatorFactory = loadFactoriesByName(type); + //refactory is null when using default authenticator + if (type.equalsIgnoreCase(AuthenticateType.LDAP.name()) + || type.equalsIgnoreCase(AuthenticateType.DEFAULT.name())) { + this.authTypeAuthenticator = authenticatorFactory.create(null); + return; + } + try { + //init config properties when using other authenticator + ConfigBase config = authenticatorFactory.getAuthenticatorConfig(); + loadConfigFile(config); + authenticatorFactory.create(config); + } catch (Exception e) { + LOG.warn("init authenticator {} failed", e, type); } } + + private AuthenticatorFactory loadFactoriesByName(String identifier) { + ServiceLoader loader = ServiceLoader.load(AuthenticatorFactory.class); + for (AuthenticatorFactory factory : loader) { + LOG.info("Found Authenticator Plugin Factory: {}", factory.factoryIdentifier()); + if (factory.factoryIdentifier().equalsIgnoreCase(identifier)) { + + return factory; + } + } + throw new RuntimeException("No AuthenticatorFactory found for identifier: " + identifier); + } + public boolean authenticate(ConnectContext context, - String userName, - MysqlChannel channel, - MysqlSerializer serializer, - MysqlAuthPacket authPacket, - MysqlHandshakePacket handshakePacket) throws IOException { + String userName, + MysqlChannel channel, + MysqlSerializer serializer, + MysqlAuthPacket authPacket, + MysqlHandshakePacket handshakePacket) throws IOException { Authenticator authenticator = chooseAuthenticator(userName); Optional password = authenticator.getPasswordResolver() .resolvePassword(context, channel, serializer, authPacket, handshakePacket); @@ -80,4 +102,11 @@ public boolean authenticate(ConnectContext context, private Authenticator chooseAuthenticator(String userName) { return authTypeAuthenticator.canDeal(userName) ? authTypeAuthenticator : defaultAuthenticator; } + + private static void loadConfigFile(ConfigBase authenticateConfig) throws Exception { + String dorisHomeDir = EnvUtils.getDorisHome(); + if (new File(dorisHomeDir + "/conf/authenticate.conf").exists()) { + authenticateConfig.init(dorisHomeDir + "/conf/ldap.conf"); + } + } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/DefaultAuthenticatorFactory.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/DefaultAuthenticatorFactory.java new file mode 100644 index 00000000000000..6803116ef3b5cd --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/DefaultAuthenticatorFactory.java @@ -0,0 +1,37 @@ +// 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.doris.mysql.authenticate; + +import org.apache.doris.common.ConfigBase; + +public class DefaultAuthenticatorFactory implements AuthenticatorFactory { + @Override + public Authenticator create(ConfigBase config) { + return new DefaultAuthenticator(); + } + + @Override + public String factoryIdentifier() { + return "default"; + } + + @Override + public ConfigBase getAuthenticatorConfig() { + return null; + } +} diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticator.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticator.java index e37112372ceb88..cd9cef469d2520 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticator.java +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticator.java @@ -75,10 +75,11 @@ public boolean canDeal(String qualifiedUser) { if (qualifiedUser.equals(Auth.ROOT_USER) || qualifiedUser.equals(Auth.ADMIN_USER)) { return false; } - if (!Env.getCurrentEnv().getAuth().getLdapManager().doesUserExist(qualifiedUser)) { - return false; - } - return true; + // Fixme Note: LdapManager should be managed internally within the Ldap plugin + // and not be placed inside the Env class. This ensures that Ldap-related + // logic and dependencies are encapsulated within the plugin, promoting + // better modularity and maintainability. + return Env.getCurrentEnv().getAuth().getLdapManager().doesUserExist(qualifiedUser); } /** diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorFactory.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorFactory.java new file mode 100644 index 00000000000000..6deb7c2321058c --- /dev/null +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorFactory.java @@ -0,0 +1,41 @@ +// 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.doris.mysql.authenticate.ldap; + +import org.apache.doris.common.ConfigBase; +import org.apache.doris.common.LdapConfig; +import org.apache.doris.mysql.authenticate.AuthenticatorFactory; + +public class LdapAuthenticatorFactory implements AuthenticatorFactory { + + + @Override + public LdapAuthenticator create(ConfigBase config) { + return new LdapAuthenticator(); + } + + @Override + public String factoryIdentifier() { + return "ldap"; + } + + @Override + public LdapConfig getAuthenticatorConfig() { + return new LdapConfig(); + } +} diff --git a/fe/fe-core/src/main/resources/META-INF/services/org.apache.doris.mysql.authenticate.AuthenticatorFactory b/fe/fe-core/src/main/resources/META-INF/services/org.apache.doris.mysql.authenticate.AuthenticatorFactory new file mode 100644 index 00000000000000..cef74b3c59bdbe --- /dev/null +++ b/fe/fe-core/src/main/resources/META-INF/services/org.apache.doris.mysql.authenticate.AuthenticatorFactory @@ -0,0 +1,2 @@ +org.apache.doris.mysql.authenticate.DefaultAuthenticatorFactory +org.apache.doris.mysql.authenticate.ldap.LdapAuthenticatorFactory \ No newline at end of file From a40d7a1b4b2dd2bdac69680ca9015c6dcd720b86 Mon Sep 17 00:00:00 2001 From: Calvin Kirs Date: Thu, 29 Aug 2024 17:04:09 +0800 Subject: [PATCH 2/3] useing properties load plugin --- .../authenticate/AuthenticatorFactory.java | 16 +----- .../authenticate/AuthenticatorManager.java | 54 ++++++++++--------- .../DefaultAuthenticatorFactory.java | 9 +--- .../ldap/LdapAuthenticatorFactory.java | 10 ++-- 4 files changed, 35 insertions(+), 54 deletions(-) diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/AuthenticatorFactory.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/AuthenticatorFactory.java index fe8d33accbba99..25ac87de4e7848 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/AuthenticatorFactory.java +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/AuthenticatorFactory.java @@ -17,7 +17,7 @@ package org.apache.doris.mysql.authenticate; -import org.apache.doris.common.ConfigBase; +import java.util.Properties; public interface AuthenticatorFactory { /** @@ -25,7 +25,7 @@ public interface AuthenticatorFactory { * * @return an instance of Authenticator */ - Authenticator create(ConfigBase config); + Authenticator create(Properties initProps); /** * Returns the identifier for the factory, such as "ldap" or "default". @@ -33,17 +33,5 @@ public interface AuthenticatorFactory { * @return the factory identifier */ String factoryIdentifier(); - - /** - * Retrieves the configuration template associated with this authenticator. - *

- * This method provides a default configuration template that can be used - * as a base for initializing the authenticator. The returned configuration - * can be modified as needed before passing it to the `create` method to - * instantiate an authenticator. - * - * @return the configuration template for the authenticator - */ - ConfigBase getAuthenticatorConfig(); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/AuthenticatorManager.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/AuthenticatorManager.java index 337794db1f2e41..68b6724b6d808b 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/AuthenticatorManager.java +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/AuthenticatorManager.java @@ -17,7 +17,6 @@ package org.apache.doris.mysql.authenticate; -import org.apache.doris.common.ConfigBase; import org.apache.doris.common.EnvUtils; import org.apache.doris.mysql.MysqlAuthPacket; import org.apache.doris.mysql.MysqlChannel; @@ -32,43 +31,42 @@ import java.io.File; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.Optional; +import java.util.Properties; import java.util.ServiceLoader; public class AuthenticatorManager { private static final Logger LOG = LogManager.getLogger(AuthenticatorManager.class); - private Authenticator defaultAuthenticator; - private Authenticator authTypeAuthenticator; + private static volatile Authenticator defaultAuthenticator = null; + private static volatile Authenticator authTypeAuthenticator = null; public AuthenticatorManager(String type) { - LOG.info("authenticate type: {}", type); - this.defaultAuthenticator = new DefaultAuthenticator(); - AuthenticatorFactory authenticatorFactory = loadFactoriesByName(type); - //refactory is null when using default authenticator - if (type.equalsIgnoreCase(AuthenticateType.LDAP.name()) - || type.equalsIgnoreCase(AuthenticateType.DEFAULT.name())) { - this.authTypeAuthenticator = authenticatorFactory.create(null); - return; - } - try { - //init config properties when using other authenticator - ConfigBase config = authenticatorFactory.getAuthenticatorConfig(); - loadConfigFile(config); - authenticatorFactory.create(config); - } catch (Exception e) { - LOG.warn("init authenticator {} failed", e, type); + LOG.info("Authenticate type: {}", type); + + if (authTypeAuthenticator == null) { + synchronized (AuthenticatorManager.class) { + if (authTypeAuthenticator == null) { + try { + authTypeAuthenticator = loadFactoriesByName(type); + } catch (Exception e) { + LOG.warn("Failed to load authenticator by name: {}, using default authenticator", type, e); + authTypeAuthenticator = defaultAuthenticator; + } + } + } } } - private AuthenticatorFactory loadFactoriesByName(String identifier) { + private Authenticator loadFactoriesByName(String identifier) throws Exception { ServiceLoader loader = ServiceLoader.load(AuthenticatorFactory.class); for (AuthenticatorFactory factory : loader) { LOG.info("Found Authenticator Plugin Factory: {}", factory.factoryIdentifier()); if (factory.factoryIdentifier().equalsIgnoreCase(identifier)) { - - return factory; + return factory.create(loadConfigFile()); } } throw new RuntimeException("No AuthenticatorFactory found for identifier: " + identifier); @@ -103,10 +101,14 @@ private Authenticator chooseAuthenticator(String userName) { return authTypeAuthenticator.canDeal(userName) ? authTypeAuthenticator : defaultAuthenticator; } - private static void loadConfigFile(ConfigBase authenticateConfig) throws Exception { - String dorisHomeDir = EnvUtils.getDorisHome(); - if (new File(dorisHomeDir + "/conf/authenticate.conf").exists()) { - authenticateConfig.init(dorisHomeDir + "/conf/ldap.conf"); + private static Properties loadConfigFile() throws Exception { + String configFilePath = EnvUtils.getDorisHome() + "/conf/authenticate.conf"; + if (new File(configFilePath).exists()) { + LOG.info("Loading authenticate configuration file: {}", configFilePath); + Properties properties = new Properties(); + properties.load(Files.newInputStream(Paths.get(configFilePath))); + return properties; } + return new Properties(); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/DefaultAuthenticatorFactory.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/DefaultAuthenticatorFactory.java index 6803116ef3b5cd..5d073a8296a3e4 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/DefaultAuthenticatorFactory.java +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/DefaultAuthenticatorFactory.java @@ -17,11 +17,11 @@ package org.apache.doris.mysql.authenticate; -import org.apache.doris.common.ConfigBase; +import java.util.Properties; public class DefaultAuthenticatorFactory implements AuthenticatorFactory { @Override - public Authenticator create(ConfigBase config) { + public DefaultAuthenticator create(Properties initProps) { return new DefaultAuthenticator(); } @@ -29,9 +29,4 @@ public Authenticator create(ConfigBase config) { public String factoryIdentifier() { return "default"; } - - @Override - public ConfigBase getAuthenticatorConfig() { - return null; - } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorFactory.java b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorFactory.java index 6deb7c2321058c..fba5c350d391de 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorFactory.java +++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorFactory.java @@ -17,15 +17,15 @@ package org.apache.doris.mysql.authenticate.ldap; -import org.apache.doris.common.ConfigBase; -import org.apache.doris.common.LdapConfig; import org.apache.doris.mysql.authenticate.AuthenticatorFactory; +import java.util.Properties; + public class LdapAuthenticatorFactory implements AuthenticatorFactory { @Override - public LdapAuthenticator create(ConfigBase config) { + public LdapAuthenticator create(Properties initProps) { return new LdapAuthenticator(); } @@ -34,8 +34,4 @@ public String factoryIdentifier() { return "ldap"; } - @Override - public LdapConfig getAuthenticatorConfig() { - return new LdapConfig(); - } } From 0ab34db0f8d9a7560a502c6384d040ae49df0dc1 Mon Sep 17 00:00:00 2001 From: Calvin Kirs Date: Thu, 5 Sep 2024 10:32:39 +0800 Subject: [PATCH 3/3] add license header --- ...oris.mysql.authenticate.AuthenticatorFactory | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/fe/fe-core/src/main/resources/META-INF/services/org.apache.doris.mysql.authenticate.AuthenticatorFactory b/fe/fe-core/src/main/resources/META-INF/services/org.apache.doris.mysql.authenticate.AuthenticatorFactory index cef74b3c59bdbe..3a013ff7f32d53 100644 --- a/fe/fe-core/src/main/resources/META-INF/services/org.apache.doris.mysql.authenticate.AuthenticatorFactory +++ b/fe/fe-core/src/main/resources/META-INF/services/org.apache.doris.mysql.authenticate.AuthenticatorFactory @@ -1,2 +1,19 @@ +# +# 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. +# +# org.apache.doris.mysql.authenticate.DefaultAuthenticatorFactory org.apache.doris.mysql.authenticate.ldap.LdapAuthenticatorFactory \ No newline at end of file