You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@doris.apache.org by "LompleZ (via GitHub)" <gi...@apache.org> on 2024/03/27 02:24:52 UTC

[PR] [refactor](Mysql) Refactoring the process of using external component… [doris]

LompleZ opened a new pull request, #32875:
URL: https://github.com/apache/doris/pull/32875

   …s to authenticate in MySQL connections
   
   ## Proposed changes
   
   Issue Number: close #32795 
   
   Add a separate processing method for external permission verification, and LDAP is now just one of its many switch cases. It will be easier to add other external authentication systems in the future.
   This change did not change the original execution logic of the code.
   
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org


Re: [PR] [refactor](Mysql) Refactoring the process of using external component… [doris]

Posted by "yongjinhou (via GitHub)" <gi...@apache.org>.
yongjinhou commented on PR #32875:
URL: https://github.com/apache/doris/pull/32875#issuecomment-2025049261

   run buildall


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org


Re: [PR] [refactor](Mysql) Refactoring the process of using external component… [doris]

Posted by "morningman (via GitHub)" <gi...@apache.org>.
morningman commented on code in PR #32875:
URL: https://github.com/apache/doris/pull/32875#discussion_r1540727061


##########
fe/fe-common/src/main/java/org/apache/doris/common/LdapConfig.java:
##########
@@ -26,7 +26,7 @@ public class LdapConfig extends ConfigBase {
      * Flag to enable LDAP authentication.
      */
     @ConfigBase.ConfField
-    public static boolean ldap_authentication_enabled = false;
+    public static boolean ldap_authentication_enabled = Config.authentication_type.equalsIgnoreCase("ldap");

Review Comment:
   I think this config should be removed direclty?



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org


Re: [PR] [refactor](Mysql) Refactoring the process of using external component… [doris]

Posted by "morningman (via GitHub)" <gi...@apache.org>.
morningman merged PR #32875:
URL: https://github.com/apache/doris/pull/32875


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org


Re: [PR] [refactor](Mysql) Refactoring the process of using external component… [doris]

Posted by "LompleZ (via GitHub)" <gi...@apache.org>.
LompleZ commented on code in PR #32875:
URL: https://github.com/apache/doris/pull/32875#discussion_r1546441839


##########
fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/MysqlAuth.java:
##########
@@ -0,0 +1,204 @@
+// 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.analysis.UserIdentity;
+import org.apache.doris.catalog.Env;
+import org.apache.doris.common.AuthenticationException;
+import org.apache.doris.common.Config;
+import org.apache.doris.common.ErrorCode;
+import org.apache.doris.common.ErrorReport;
+import org.apache.doris.mysql.MysqlAuthPacket;
+import org.apache.doris.mysql.MysqlAuthSwitchPacket;
+import org.apache.doris.mysql.MysqlChannel;
+import org.apache.doris.mysql.MysqlClearTextPacket;
+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.LdapAuthenticate;
+import org.apache.doris.mysql.privilege.Auth;
+import org.apache.doris.qe.ConnectContext;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import com.google.common.collect.Lists;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.List;
+
+import static org.apache.doris.mysql.MysqlProto.sendResponsePacket;
+
+
+public class MysqlAuth {
+    private static final Logger LOG = LogManager.getLogger(MysqlAuth.class);
+
+    // scramble: data receive from server.
+    // randomString: data send by server in plugin data field
+    // user_name#HIGH@cluster_name
+    private static boolean internalAuthenticate(ConnectContext context, byte[] scramble,
+                                                byte[] randomString, String qualifiedUser) {
+        String remoteIp = context.getMysqlChannel().getRemoteIp();
+        List<UserIdentity> currentUserIdentity = Lists.newArrayList();
+
+        try {
+            Env.getCurrentEnv().getAuth().checkPassword(qualifiedUser, remoteIp,
+                scramble, randomString, currentUserIdentity);
+        } catch (AuthenticationException e) {
+            ErrorReport.report(e.errorCode, e.msgs);
+            return false;
+        }
+
+        context.setCurrentUserIdentity(currentUserIdentity.get(0));
+        context.setRemoteIP(remoteIp);
+        return true;
+    }
+
+    // Default auth uses doris internal user system to authenticate.
+    private static boolean defaultAuth(
+        ConnectContext context,
+        String qualifiedUser,
+        MysqlChannel channel,
+        MysqlSerializer serializer,
+        MysqlAuthPacket authPacket,
+        MysqlHandshakePacket handshakePacket) throws IOException {
+        // Starting with MySQL 8.0.4, MySQL changed the default authentication plugin for MySQL client
+        // from mysql_native_password to caching_sha2_password.
+        // ref: https://mysqlserverteam.com/mysql-8-0-4-new-default-authentication-plugin-caching_sha2_password/
+        // So, User use mysql client or ODBC Driver after 8.0.4 have problem to connect to Doris
+        // with password.
+        // So Doris support the Protocol::AuthSwitchRequest to tell client to keep the default password plugin
+        // which Doris is using now.
+        // Note: Check the authPacket whether support plugin auth firstly,
+        // before we check AuthPlugin between doris and client to compatible with older version: like mysql 5.1
+        if (authPacket.getCapability().isPluginAuth()
+            && !handshakePacket.checkAuthPluginSameAsDoris(authPacket.getPluginName())) {
+            // 1. clear the serializer
+            serializer.reset();
+            // 2. build the auth switch request and send to the client
+            handshakePacket.buildAuthSwitchRequest(serializer);
+            channel.sendAndFlush(serializer.toByteBuffer());
+            // Server receive auth switch response packet from client.
+            ByteBuffer authSwitchResponse = channel.fetchOnePacket();
+            if (authSwitchResponse == null) {
+                // receive response failed.
+                return false;
+            }
+            // 3. the client use default password plugin of Doris to dispose
+            // password
+            authPacket.setAuthResponse(MysqlProto.readEofString(authSwitchResponse));
+        }
+
+        // NOTE: when we behind proxy, we need random string sent by proxy.
+        byte[] randomString = handshakePacket.getAuthPluginData();
+        if (Config.proxy_auth_enable && authPacket.getRandomString() != null) {
+            randomString = authPacket.getRandomString();
+        }
+        // check authenticate
+        if (!internalAuthenticate(context, authPacket.getAuthResponse(), randomString, qualifiedUser)) {
+            sendResponsePacket(context);
+            return false;
+        }
+        return true;
+    }
+
+    /*
+     * ldap:
+     * server ---AuthSwitch---> client
+     * server <--- clear text password --- client
+     */
+    private static boolean ldapAuth(
+        ConnectContext context,
+        String qualifiedUser,
+        MysqlChannel channel,
+        MysqlSerializer serializer) throws IOException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("user:{} start to ldap authenticate.", qualifiedUser);
+        }
+        // server send authentication switch packet to request password clear text.
+        // https://dev.mysql.com/doc/internals/en/authentication-method-change.html
+        serializer.reset();
+        MysqlAuthSwitchPacket mysqlAuthSwitchPacket = new MysqlAuthSwitchPacket();
+        mysqlAuthSwitchPacket.writeTo(serializer);
+        channel.sendAndFlush(serializer.toByteBuffer());
+
+        // Server receive password clear text.
+        ByteBuffer authSwitchResponse = channel.fetchOnePacket();
+        if (authSwitchResponse == null) {
+            return false;
+        }
+        MysqlClearTextPacket clearTextPacket = new MysqlClearTextPacket();
+        if (!clearTextPacket.readFrom(authSwitchResponse)) {
+            ErrorReport.report(ErrorCode.ERR_NOT_SUPPORTED_AUTH_MODE);
+            sendResponsePacket(context);
+            return false;
+        }
+        if (!LdapAuthenticate.authenticate(context, clearTextPacket.getPassword(), qualifiedUser)) {
+            sendResponsePacket(context);
+            return false;
+        }
+        return true;
+    }
+
+    // Based on FE configuration and some prerequisites, decide which authentication type to actually use
+    public static MysqlAuthType useWhichAuthType(ConnectContext context, String qualifiedUser) throws IOException {
+        MysqlAuthType typeConfig = MysqlAuthType.getAuthTypeConfig();
+
+        // Root and admin are internal users of the Doris.
+        // They are used to set the ldap admin password.
+        // Cannot use external authentication.
+        if (qualifiedUser.equals(Auth.ROOT_USER) || qualifiedUser.equals(Auth.ADMIN_USER)) {
+            return MysqlAuthType.DEFAULT;
+        }
+
+        // precondition
+        switch (typeConfig) {
+            case LDAP:
+                try {
+                    // If LDAP authentication is enabled and the user exists in LDAP, use LDAP authentication,
+                    // otherwise use Doris internal authentication.
+                    if (!Env.getCurrentEnv().getAuth().getLdapManager().doesUserExist(qualifiedUser)) {
+                        return MysqlAuthType.DEFAULT;
+                    }
+                } catch (Exception e) {
+                    // TODO: can we catch exception here?
+                    LOG.warn("Check if user exists in ldap error.", e);
+                    sendResponsePacket(context);
+                    return MysqlAuthType.DEFAULT;
+                }

Review Comment:
   > missing `default`? Better add it
   
   Modified



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org


Re: [PR] [refactor](Mysql) Refactoring the process of using external component… [doris]

Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #32875:
URL: https://github.com/apache/doris/pull/32875#issuecomment-2031231056

   PR approved by at least one committer and no changes requested.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org


Re: [PR] [refactor](Mysql) Refactoring the process of using external component… [doris]

Posted by "yongjinhou (via GitHub)" <gi...@apache.org>.
yongjinhou commented on code in PR #32875:
URL: https://github.com/apache/doris/pull/32875#discussion_r1540953362


##########
fe/fe-common/src/main/java/org/apache/doris/common/LdapConfig.java:
##########
@@ -26,7 +26,7 @@ public class LdapConfig extends ConfigBase {
      * Flag to enable LDAP authentication.
      */
     @ConfigBase.ConfField
-    public static boolean ldap_authentication_enabled = false;
+    public static boolean ldap_authentication_enabled = Config.authentication_type.equalsIgnoreCase("ldap");

Review Comment:
   You should remove this config and rebase latest master branch.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org


Re: [PR] [refactor](Mysql) Refactoring the process of using external component… [doris]

Posted by "morningman (via GitHub)" <gi...@apache.org>.
morningman commented on code in PR #32875:
URL: https://github.com/apache/doris/pull/32875#discussion_r1543159828


##########
fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/MysqlAuth.java:
##########
@@ -0,0 +1,204 @@
+// 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.analysis.UserIdentity;
+import org.apache.doris.catalog.Env;
+import org.apache.doris.common.AuthenticationException;
+import org.apache.doris.common.Config;
+import org.apache.doris.common.ErrorCode;
+import org.apache.doris.common.ErrorReport;
+import org.apache.doris.mysql.MysqlAuthPacket;
+import org.apache.doris.mysql.MysqlAuthSwitchPacket;
+import org.apache.doris.mysql.MysqlChannel;
+import org.apache.doris.mysql.MysqlClearTextPacket;
+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.LdapAuthenticate;
+import org.apache.doris.mysql.privilege.Auth;
+import org.apache.doris.qe.ConnectContext;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import com.google.common.collect.Lists;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.List;
+
+import static org.apache.doris.mysql.MysqlProto.sendResponsePacket;
+
+
+public class MysqlAuth {
+    private static final Logger LOG = LogManager.getLogger(MysqlAuth.class);
+
+    // scramble: data receive from server.
+    // randomString: data send by server in plugin data field
+    // user_name#HIGH@cluster_name
+    private static boolean internalAuthenticate(ConnectContext context, byte[] scramble,
+                                                byte[] randomString, String qualifiedUser) {
+        String remoteIp = context.getMysqlChannel().getRemoteIp();
+        List<UserIdentity> currentUserIdentity = Lists.newArrayList();
+
+        try {
+            Env.getCurrentEnv().getAuth().checkPassword(qualifiedUser, remoteIp,
+                scramble, randomString, currentUserIdentity);
+        } catch (AuthenticationException e) {
+            ErrorReport.report(e.errorCode, e.msgs);
+            return false;
+        }
+
+        context.setCurrentUserIdentity(currentUserIdentity.get(0));
+        context.setRemoteIP(remoteIp);
+        return true;
+    }
+
+    // Default auth uses doris internal user system to authenticate.
+    private static boolean defaultAuth(
+        ConnectContext context,
+        String qualifiedUser,
+        MysqlChannel channel,
+        MysqlSerializer serializer,
+        MysqlAuthPacket authPacket,
+        MysqlHandshakePacket handshakePacket) throws IOException {
+        // Starting with MySQL 8.0.4, MySQL changed the default authentication plugin for MySQL client
+        // from mysql_native_password to caching_sha2_password.
+        // ref: https://mysqlserverteam.com/mysql-8-0-4-new-default-authentication-plugin-caching_sha2_password/
+        // So, User use mysql client or ODBC Driver after 8.0.4 have problem to connect to Doris
+        // with password.
+        // So Doris support the Protocol::AuthSwitchRequest to tell client to keep the default password plugin
+        // which Doris is using now.
+        // Note: Check the authPacket whether support plugin auth firstly,
+        // before we check AuthPlugin between doris and client to compatible with older version: like mysql 5.1
+        if (authPacket.getCapability().isPluginAuth()
+            && !handshakePacket.checkAuthPluginSameAsDoris(authPacket.getPluginName())) {
+            // 1. clear the serializer
+            serializer.reset();
+            // 2. build the auth switch request and send to the client
+            handshakePacket.buildAuthSwitchRequest(serializer);
+            channel.sendAndFlush(serializer.toByteBuffer());
+            // Server receive auth switch response packet from client.
+            ByteBuffer authSwitchResponse = channel.fetchOnePacket();
+            if (authSwitchResponse == null) {
+                // receive response failed.
+                return false;
+            }
+            // 3. the client use default password plugin of Doris to dispose
+            // password
+            authPacket.setAuthResponse(MysqlProto.readEofString(authSwitchResponse));
+        }
+
+        // NOTE: when we behind proxy, we need random string sent by proxy.
+        byte[] randomString = handshakePacket.getAuthPluginData();
+        if (Config.proxy_auth_enable && authPacket.getRandomString() != null) {
+            randomString = authPacket.getRandomString();
+        }
+        // check authenticate
+        if (!internalAuthenticate(context, authPacket.getAuthResponse(), randomString, qualifiedUser)) {
+            sendResponsePacket(context);
+            return false;
+        }
+        return true;
+    }
+
+    /*
+     * ldap:
+     * server ---AuthSwitch---> client
+     * server <--- clear text password --- client
+     */
+    private static boolean ldapAuth(
+        ConnectContext context,
+        String qualifiedUser,
+        MysqlChannel channel,
+        MysqlSerializer serializer) throws IOException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("user:{} start to ldap authenticate.", qualifiedUser);
+        }
+        // server send authentication switch packet to request password clear text.
+        // https://dev.mysql.com/doc/internals/en/authentication-method-change.html
+        serializer.reset();
+        MysqlAuthSwitchPacket mysqlAuthSwitchPacket = new MysqlAuthSwitchPacket();
+        mysqlAuthSwitchPacket.writeTo(serializer);
+        channel.sendAndFlush(serializer.toByteBuffer());
+
+        // Server receive password clear text.
+        ByteBuffer authSwitchResponse = channel.fetchOnePacket();
+        if (authSwitchResponse == null) {
+            return false;
+        }
+        MysqlClearTextPacket clearTextPacket = new MysqlClearTextPacket();
+        if (!clearTextPacket.readFrom(authSwitchResponse)) {
+            ErrorReport.report(ErrorCode.ERR_NOT_SUPPORTED_AUTH_MODE);
+            sendResponsePacket(context);
+            return false;
+        }
+        if (!LdapAuthenticate.authenticate(context, clearTextPacket.getPassword(), qualifiedUser)) {
+            sendResponsePacket(context);
+            return false;
+        }
+        return true;
+    }
+
+    // Based on FE configuration and some prerequisites, decide which authentication type to actually use
+    public static MysqlAuthType useWhichAuthType(ConnectContext context, String qualifiedUser) throws IOException {
+        MysqlAuthType typeConfig = MysqlAuthType.getAuthTypeConfig();
+
+        // Root and admin are internal users of the Doris.
+        // They are used to set the ldap admin password.
+        // Cannot use external authentication.
+        if (qualifiedUser.equals(Auth.ROOT_USER) || qualifiedUser.equals(Auth.ADMIN_USER)) {
+            return MysqlAuthType.DEFAULT;
+        }
+
+        // precondition
+        switch (typeConfig) {
+            case LDAP:
+                try {
+                    // If LDAP authentication is enabled and the user exists in LDAP, use LDAP authentication,
+                    // otherwise use Doris internal authentication.
+                    if (!Env.getCurrentEnv().getAuth().getLdapManager().doesUserExist(qualifiedUser)) {
+                        return MysqlAuthType.DEFAULT;
+                    }
+                } catch (Exception e) {
+                    // TODO: can we catch exception here?
+                    LOG.warn("Check if user exists in ldap error.", e);
+                    sendResponsePacket(context);
+                    return MysqlAuthType.DEFAULT;
+                }

Review Comment:
   missing `default`?
   Better add it



##########
fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/MysqlAuth.java:
##########
@@ -0,0 +1,204 @@
+// 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.analysis.UserIdentity;
+import org.apache.doris.catalog.Env;
+import org.apache.doris.common.AuthenticationException;
+import org.apache.doris.common.Config;
+import org.apache.doris.common.ErrorCode;
+import org.apache.doris.common.ErrorReport;
+import org.apache.doris.mysql.MysqlAuthPacket;
+import org.apache.doris.mysql.MysqlAuthSwitchPacket;
+import org.apache.doris.mysql.MysqlChannel;
+import org.apache.doris.mysql.MysqlClearTextPacket;
+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.LdapAuthenticate;
+import org.apache.doris.mysql.privilege.Auth;
+import org.apache.doris.qe.ConnectContext;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import com.google.common.collect.Lists;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.List;
+
+import static org.apache.doris.mysql.MysqlProto.sendResponsePacket;
+
+
+public class MysqlAuth {
+    private static final Logger LOG = LogManager.getLogger(MysqlAuth.class);
+
+    // scramble: data receive from server.
+    // randomString: data send by server in plugin data field
+    // user_name#HIGH@cluster_name
+    private static boolean internalAuthenticate(ConnectContext context, byte[] scramble,
+                                                byte[] randomString, String qualifiedUser) {
+        String remoteIp = context.getMysqlChannel().getRemoteIp();
+        List<UserIdentity> currentUserIdentity = Lists.newArrayList();
+
+        try {
+            Env.getCurrentEnv().getAuth().checkPassword(qualifiedUser, remoteIp,
+                scramble, randomString, currentUserIdentity);
+        } catch (AuthenticationException e) {
+            ErrorReport.report(e.errorCode, e.msgs);
+            return false;
+        }
+
+        context.setCurrentUserIdentity(currentUserIdentity.get(0));
+        context.setRemoteIP(remoteIp);
+        return true;
+    }
+
+    // Default auth uses doris internal user system to authenticate.
+    private static boolean defaultAuth(
+        ConnectContext context,
+        String qualifiedUser,
+        MysqlChannel channel,
+        MysqlSerializer serializer,
+        MysqlAuthPacket authPacket,
+        MysqlHandshakePacket handshakePacket) throws IOException {
+        // Starting with MySQL 8.0.4, MySQL changed the default authentication plugin for MySQL client
+        // from mysql_native_password to caching_sha2_password.
+        // ref: https://mysqlserverteam.com/mysql-8-0-4-new-default-authentication-plugin-caching_sha2_password/
+        // So, User use mysql client or ODBC Driver after 8.0.4 have problem to connect to Doris
+        // with password.
+        // So Doris support the Protocol::AuthSwitchRequest to tell client to keep the default password plugin
+        // which Doris is using now.
+        // Note: Check the authPacket whether support plugin auth firstly,
+        // before we check AuthPlugin between doris and client to compatible with older version: like mysql 5.1
+        if (authPacket.getCapability().isPluginAuth()
+            && !handshakePacket.checkAuthPluginSameAsDoris(authPacket.getPluginName())) {
+            // 1. clear the serializer
+            serializer.reset();
+            // 2. build the auth switch request and send to the client
+            handshakePacket.buildAuthSwitchRequest(serializer);
+            channel.sendAndFlush(serializer.toByteBuffer());
+            // Server receive auth switch response packet from client.
+            ByteBuffer authSwitchResponse = channel.fetchOnePacket();
+            if (authSwitchResponse == null) {
+                // receive response failed.
+                return false;
+            }
+            // 3. the client use default password plugin of Doris to dispose
+            // password
+            authPacket.setAuthResponse(MysqlProto.readEofString(authSwitchResponse));
+        }
+
+        // NOTE: when we behind proxy, we need random string sent by proxy.
+        byte[] randomString = handshakePacket.getAuthPluginData();
+        if (Config.proxy_auth_enable && authPacket.getRandomString() != null) {
+            randomString = authPacket.getRandomString();
+        }
+        // check authenticate
+        if (!internalAuthenticate(context, authPacket.getAuthResponse(), randomString, qualifiedUser)) {
+            sendResponsePacket(context);
+            return false;
+        }
+        return true;
+    }
+
+    /*
+     * ldap:
+     * server ---AuthSwitch---> client
+     * server <--- clear text password --- client
+     */
+    private static boolean ldapAuth(
+        ConnectContext context,
+        String qualifiedUser,
+        MysqlChannel channel,
+        MysqlSerializer serializer) throws IOException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("user:{} start to ldap authenticate.", qualifiedUser);
+        }
+        // server send authentication switch packet to request password clear text.
+        // https://dev.mysql.com/doc/internals/en/authentication-method-change.html
+        serializer.reset();
+        MysqlAuthSwitchPacket mysqlAuthSwitchPacket = new MysqlAuthSwitchPacket();
+        mysqlAuthSwitchPacket.writeTo(serializer);
+        channel.sendAndFlush(serializer.toByteBuffer());
+
+        // Server receive password clear text.
+        ByteBuffer authSwitchResponse = channel.fetchOnePacket();
+        if (authSwitchResponse == null) {
+            return false;
+        }
+        MysqlClearTextPacket clearTextPacket = new MysqlClearTextPacket();
+        if (!clearTextPacket.readFrom(authSwitchResponse)) {
+            ErrorReport.report(ErrorCode.ERR_NOT_SUPPORTED_AUTH_MODE);
+            sendResponsePacket(context);
+            return false;
+        }
+        if (!LdapAuthenticate.authenticate(context, clearTextPacket.getPassword(), qualifiedUser)) {
+            sendResponsePacket(context);
+            return false;
+        }
+        return true;
+    }
+
+    // Based on FE configuration and some prerequisites, decide which authentication type to actually use
+    public static MysqlAuthType useWhichAuthType(ConnectContext context, String qualifiedUser) throws IOException {

Review Comment:
   ```suggestion
       private static MysqlAuthType useWhichAuthType(ConnectContext context, String qualifiedUser) throws IOException {
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org


Re: [PR] [refactor](Mysql) Refactoring the process of using external component… [doris]

Posted by "LompleZ (via GitHub)" <gi...@apache.org>.
LompleZ commented on code in PR #32875:
URL: https://github.com/apache/doris/pull/32875#discussion_r1546443163


##########
fe/fe-common/src/main/java/org/apache/doris/common/LdapConfig.java:
##########
@@ -26,7 +26,7 @@ public class LdapConfig extends ConfigBase {
      * Flag to enable LDAP authentication.
      */
     @ConfigBase.ConfField
-    public static boolean ldap_authentication_enabled = false;
+    public static boolean ldap_authentication_enabled = Config.authentication_type.equalsIgnoreCase("ldap");

Review Comment:
   Modified



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org


Re: [PR] [refactor](Mysql) Refactoring the process of using external component… [doris]

Posted by "github-actions[bot] (via GitHub)" <gi...@apache.org>.
github-actions[bot] commented on PR #32875:
URL: https://github.com/apache/doris/pull/32875#issuecomment-2031231109

   PR approved by anyone and no changes requested.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org


Re: [PR] [refactor](Mysql) Refactoring the process of using external component… [doris]

Posted by "LompleZ (via GitHub)" <gi...@apache.org>.
LompleZ commented on PR #32875:
URL: https://github.com/apache/doris/pull/32875#issuecomment-2029936507

   run buildall


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org


Re: [PR] [refactor](Mysql) Refactoring the process of using external component… [doris]

Posted by "LompleZ (via GitHub)" <gi...@apache.org>.
LompleZ commented on PR #32875:
URL: https://github.com/apache/doris/pull/32875#issuecomment-2029967312

   run buildall


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org


Re: [PR] [refactor](Mysql) Refactoring the process of using external component… [doris]

Posted by "yongjinhou (via GitHub)" <gi...@apache.org>.
yongjinhou commented on PR #32875:
URL: https://github.com/apache/doris/pull/32875#issuecomment-2022567075

   run buildall


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org


Re: [PR] [refactor](Mysql) Refactoring the process of using external component… [doris]

Posted by "doris-robot (via GitHub)" <gi...@apache.org>.
doris-robot commented on PR #32875:
URL: https://github.com/apache/doris/pull/32875#issuecomment-2021802659

   Thank you for your contribution to Apache Doris.
   Don't know what should be done next? See [How to process your PR](https://cwiki.apache.org/confluence/display/DORIS/How+to+process+your+PR)
   
   Since 2024-03-18, the Document has been moved to [doris-website](https://github.com/apache/doris-website).
   See [Doris Document](https://cwiki.apache.org/confluence/display/DORIS/Doris+Document).


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@doris.apache.org
For additional commands, e-mail: commits-help@doris.apache.org