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

morningman pushed a commit to branch branch-2.1
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-2.1 by this push:
     new b87674630e9 [enhance](auth)Abstract authentication interface (#33668) 
(#33961)
b87674630e9 is described below

commit b87674630e979819a1ebc08736b60f13e21e806c
Author: Mingyu Chen <morning...@163.com>
AuthorDate: Mon Apr 22 14:47:59 2024 +0800

    [enhance](auth)Abstract authentication interface (#33668) (#33961)
    
    bp #33668
    
    Co-authored-by: zhangdong <493738...@qq.com>
---
 .../org/apache/doris/analysis/CreateUserStmt.java  |   4 +-
 .../org/apache/doris/analysis/DropUserStmt.java    |   4 +-
 .../main/java/org/apache/doris/catalog/Env.java    |   9 +
 .../java/org/apache/doris/mysql/MysqlProto.java    |   4 +-
 ...MysqlAuthType.java => AuthenticateRequest.java} |  36 ++--
 .../mysql/authenticate/AuthenticateResponse.java   |  76 ++++++++
 .../{MysqlAuthType.java => AuthenticateType.java}  |   4 +-
 .../{MysqlAuthType.java => Authenticator.java}     |  24 +--
 .../mysql/authenticate/AuthenticatorManager.java   |  83 +++++++++
 .../mysql/authenticate/DefaultAuthenticator.java   |  75 ++++++++
 .../apache/doris/mysql/authenticate/MysqlAuth.java | 205 ---------------------
 ...dapAuthenticate.java => LdapAuthenticator.java} |  78 ++++++--
 .../doris/mysql/authenticate/ldap/LdapManager.java |   6 +-
 .../ClearPassword.java}                            |  24 +--
 .../password/ClearPasswordResolver.java            |  60 ++++++
 .../NativePassword.java}                           |  30 ++-
 .../password/NativePasswordResolver.java           |  71 +++++++
 .../{MysqlAuthType.java => password/Password.java} |  20 +-
 .../PasswordResolver.java}                         |  30 ++-
 .../org/apache/doris/mysql/privilege/Auth.java     |   4 +-
 .../org/apache/doris/mysql/MysqlProtoTest.java     |  53 +++---
 .../authenticate/DefaultAuthenticatorTest.java     | 100 ++++++++++
 .../authenticate/ldap/LdapAuthenticateTest.java    | 203 --------------------
 .../authenticate/ldap/LdapAuthenticatorTest.java   | 146 +++++++++++++++
 24 files changed, 783 insertions(+), 566 deletions(-)

diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateUserStmt.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateUserStmt.java
index 008e691af7e..9c07b7aee12 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateUserStmt.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/CreateUserStmt.java
@@ -24,7 +24,7 @@ import org.apache.doris.common.ErrorCode;
 import org.apache.doris.common.ErrorReport;
 import org.apache.doris.common.FeNameFormat;
 import org.apache.doris.common.UserException;
-import org.apache.doris.mysql.authenticate.MysqlAuthType;
+import org.apache.doris.mysql.authenticate.AuthenticateType;
 import org.apache.doris.mysql.privilege.PrivPredicate;
 import org.apache.doris.mysql.privilege.Role;
 import org.apache.doris.qe.ConnectContext;
@@ -120,7 +120,7 @@ public class CreateUserStmt extends DdlStmt {
         super.analyze(analyzer);
 
         if (Config.access_controller_type.equalsIgnoreCase("ranger-doris")
-                && MysqlAuthType.getAuthTypeConfig() == MysqlAuthType.LDAP) {
+                && AuthenticateType.getAuthTypeConfig() == 
AuthenticateType.LDAP) {
             throw new AnalysisException("Create user is prohibited when Ranger 
and LDAP are enabled at same time.");
         }
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/analysis/DropUserStmt.java 
b/fe/fe-core/src/main/java/org/apache/doris/analysis/DropUserStmt.java
index aa985751723..e336040d7f8 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/DropUserStmt.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/DropUserStmt.java
@@ -23,7 +23,7 @@ import org.apache.doris.common.Config;
 import org.apache.doris.common.ErrorCode;
 import org.apache.doris.common.ErrorReport;
 import org.apache.doris.common.UserException;
-import org.apache.doris.mysql.authenticate.MysqlAuthType;
+import org.apache.doris.mysql.authenticate.AuthenticateType;
 import org.apache.doris.mysql.privilege.PrivPredicate;
 import org.apache.doris.qe.ConnectContext;
 
@@ -57,7 +57,7 @@ public class DropUserStmt extends DdlStmt {
         super.analyze(analyzer);
 
         if (Config.access_controller_type.equalsIgnoreCase("ranger-doris")
-                && MysqlAuthType.getAuthTypeConfig() == MysqlAuthType.LDAP) {
+                && AuthenticateType.getAuthTypeConfig() == 
AuthenticateType.LDAP) {
             throw new AnalysisException("Drop user is prohibited when Ranger 
and LDAP are enabled at same time.");
         }
 
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 a70b0c05161..352583362bb 100755
--- 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
@@ -182,6 +182,8 @@ import org.apache.doris.mtmv.MTMVRefreshPartitionSnapshot;
 import org.apache.doris.mtmv.MTMVRelation;
 import org.apache.doris.mtmv.MTMVService;
 import org.apache.doris.mtmv.MTMVStatus;
+import org.apache.doris.mysql.authenticate.AuthenticateType;
+import org.apache.doris.mysql.authenticate.AuthenticatorManager;
 import org.apache.doris.mysql.privilege.AccessControllerManager;
 import org.apache.doris.mysql.privilege.Auth;
 import org.apache.doris.mysql.privilege.PrivPredicate;
@@ -453,6 +455,8 @@ public class Env {
     private Auth auth;
     private AccessControllerManager accessManager;
 
+    private AuthenticatorManager authenticatorManager;
+
     private DomainResolver domainResolver;
 
     private TabletSchedulerStat stat;
@@ -700,6 +704,7 @@ public class Env {
 
         this.auth = new Auth();
         this.accessManager = new AccessControllerManager(auth);
+        this.authenticatorManager = new 
AuthenticatorManager(AuthenticateType.getAuthTypeConfig());
         this.domainResolver = new DomainResolver(auth);
 
         this.metaContext = new MetaContext();
@@ -824,6 +829,10 @@ public class Env {
         return accessManager;
     }
 
+    public AuthenticatorManager getAuthenticatorManager() {
+        return authenticatorManager;
+    }
+
     public MTMVService getMtmvService() {
         return mtmvService;
     }
diff --git a/fe/fe-core/src/main/java/org/apache/doris/mysql/MysqlProto.java 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/MysqlProto.java
index 802a5a8ad96..426074f32e3 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/mysql/MysqlProto.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/MysqlProto.java
@@ -23,7 +23,6 @@ import org.apache.doris.common.DdlException;
 import org.apache.doris.common.ErrorCode;
 import org.apache.doris.common.ErrorReport;
 import org.apache.doris.datasource.CatalogIf;
-import org.apache.doris.mysql.authenticate.MysqlAuth;
 import org.apache.doris.qe.ConnectContext;
 
 import com.google.common.base.Strings;
@@ -194,7 +193,8 @@ public class MysqlProto {
         }
 
         //  authenticate
-        if (!MysqlAuth.authenticate(context, qualifiedUser, channel, 
serializer, authPacket, handshakePacket)) {
+        if (!Env.getCurrentEnv().getAuthenticatorManager()
+                .authenticate(context, qualifiedUser, channel, serializer, 
authPacket, handshakePacket)) {
             return false;
         }
 
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/MysqlAuthType.java
 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/AuthenticateRequest.java
similarity index 59%
copy from 
fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/MysqlAuthType.java
copy to 
fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/AuthenticateRequest.java
index 9c19e5d9a58..6f19cbbfa1e 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/MysqlAuthType.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/AuthenticateRequest.java
@@ -17,22 +17,28 @@
 
 package org.apache.doris.mysql.authenticate;
 
-import org.apache.doris.common.Config;
+import org.apache.doris.mysql.authenticate.password.Password;
 
-public enum MysqlAuthType {
-    DEFAULT,
-    LDAP;
+public class AuthenticateRequest {
+    private String userName;
+    private Password password;
+    private String remoteIp;
 
-    public static MysqlAuthType getAuthTypeConfig() {
-        switch (Config.authentication_type.toLowerCase()) {
-            case "default":
-                return DEFAULT;
-            case "ldap":
-                return LDAP;
-            // add other authentication system here
-            // case otherAuthType:
-            default:
-                return DEFAULT;
-        }
+    public AuthenticateRequest(String userName, Password password, String 
remoteIp) {
+        this.userName = userName;
+        this.password = password;
+        this.remoteIp = remoteIp;
+    }
+
+    public String getUserName() {
+        return userName;
+    }
+
+    public Password getPassword() {
+        return password;
+    }
+
+    public String getRemoteIp() {
+        return remoteIp;
     }
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/AuthenticateResponse.java
 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/AuthenticateResponse.java
new file mode 100644
index 00000000000..cab90f81a7f
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/AuthenticateResponse.java
@@ -0,0 +1,76 @@
+// 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;
+
+public class AuthenticateResponse {
+    public static AuthenticateResponse failedResponse = new 
AuthenticateResponse(false);
+
+    private boolean success;
+    private UserIdentity userIdentity;
+    private boolean isTemp = false;
+
+    public AuthenticateResponse(boolean success) {
+        this.success = success;
+    }
+
+    public AuthenticateResponse(boolean success, UserIdentity userIdentity) {
+        this.success = success;
+        this.userIdentity = userIdentity;
+    }
+
+    public AuthenticateResponse(boolean success, UserIdentity userIdentity, 
boolean isTemp) {
+        this.success = success;
+        this.userIdentity = userIdentity;
+        this.isTemp = isTemp;
+    }
+
+    public boolean isSuccess() {
+        return success;
+    }
+
+    public void setSuccess(boolean success) {
+        this.success = success;
+    }
+
+    public UserIdentity getUserIdentity() {
+        return userIdentity;
+    }
+
+    public void setUserIdentity(UserIdentity userIdentity) {
+        this.userIdentity = userIdentity;
+    }
+
+    public boolean isTemp() {
+        return isTemp;
+    }
+
+    public void setTemp(boolean temp) {
+        isTemp = temp;
+    }
+
+    @Override
+    public String toString() {
+        return "AuthenticateResponse{"
+                + "success=" + success
+                + ", userIdentity=" + userIdentity
+                + ", isTemp=" + isTemp
+                + '}';
+    }
+}
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/MysqlAuthType.java
 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/AuthenticateType.java
similarity index 93%
copy from 
fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/MysqlAuthType.java
copy to 
fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/AuthenticateType.java
index 9c19e5d9a58..0d180eba23d 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/MysqlAuthType.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/AuthenticateType.java
@@ -19,11 +19,11 @@ package org.apache.doris.mysql.authenticate;
 
 import org.apache.doris.common.Config;
 
-public enum MysqlAuthType {
+public enum AuthenticateType {
     DEFAULT,
     LDAP;
 
-    public static MysqlAuthType getAuthTypeConfig() {
+    public static AuthenticateType getAuthTypeConfig() {
         switch (Config.authentication_type.toLowerCase()) {
             case "default":
                 return DEFAULT;
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/MysqlAuthType.java
 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/Authenticator.java
similarity index 64%
copy from 
fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/MysqlAuthType.java
copy to 
fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/Authenticator.java
index 9c19e5d9a58..56d045f4340 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/MysqlAuthType.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/Authenticator.java
@@ -17,22 +17,14 @@
 
 package org.apache.doris.mysql.authenticate;
 
-import org.apache.doris.common.Config;
+import org.apache.doris.mysql.authenticate.password.PasswordResolver;
 
-public enum MysqlAuthType {
-    DEFAULT,
-    LDAP;
+import java.io.IOException;
 
-    public static MysqlAuthType getAuthTypeConfig() {
-        switch (Config.authentication_type.toLowerCase()) {
-            case "default":
-                return DEFAULT;
-            case "ldap":
-                return LDAP;
-            // add other authentication system here
-            // case otherAuthType:
-            default:
-                return DEFAULT;
-        }
-    }
+public interface Authenticator {
+    AuthenticateResponse authenticate(AuthenticateRequest request) throws 
IOException;
+
+    boolean canDeal(String qualifiedUser);
+
+    PasswordResolver getPasswordResolver();
 }
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
new file mode 100644
index 00000000000..c00828f82fa
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/AuthenticatorManager.java
@@ -0,0 +1,83 @@
+// 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.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.IOException;
+import java.util.Optional;
+
+public class AuthenticatorManager {
+    private static final Logger LOG = 
LogManager.getLogger(AuthenticatorManager.class);
+
+    private Authenticator defaultAuthenticator;
+    private Authenticator authTypeAuthenticator;
+
+    public AuthenticatorManager(AuthenticateType 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;
+        }
+    }
+
+    public boolean authenticate(ConnectContext context,
+            String userName,
+            MysqlChannel channel,
+            MysqlSerializer serializer,
+            MysqlAuthPacket authPacket,
+            MysqlHandshakePacket handshakePacket) throws IOException {
+        Authenticator authenticator = chooseAuthenticator(userName);
+        Optional<Password> password = authenticator.getPasswordResolver()
+                .resolvePassword(context, channel, serializer, authPacket, 
handshakePacket);
+        if (!password.isPresent()) {
+            return false;
+        }
+        String remoteIp = context.getMysqlChannel().getRemoteIp();
+        AuthenticateRequest request = new AuthenticateRequest(userName, 
password.get(), remoteIp);
+        AuthenticateResponse response = authenticator.authenticate(request);
+        if (!response.isSuccess()) {
+            MysqlProto.sendResponsePacket(context);
+            return false;
+        }
+        context.setCurrentUserIdentity(response.getUserIdentity());
+        context.setRemoteIP(remoteIp);
+        context.setIsTempUser(response.isTemp());
+        return true;
+    }
+
+    private Authenticator chooseAuthenticator(String userName) {
+        return authTypeAuthenticator.canDeal(userName) ? authTypeAuthenticator 
: defaultAuthenticator;
+    }
+}
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/DefaultAuthenticator.java
 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/DefaultAuthenticator.java
new file mode 100644
index 00000000000..7111477ce9e
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/DefaultAuthenticator.java
@@ -0,0 +1,75 @@
+// 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.ErrorReport;
+import org.apache.doris.mysql.authenticate.password.NativePassword;
+import org.apache.doris.mysql.authenticate.password.NativePasswordResolver;
+import org.apache.doris.mysql.authenticate.password.Password;
+import org.apache.doris.mysql.authenticate.password.PasswordResolver;
+
+import com.google.common.collect.Lists;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import java.io.IOException;
+import java.util.List;
+
+public class DefaultAuthenticator implements Authenticator {
+    private static final Logger LOG = 
LogManager.getLogger(DefaultAuthenticator.class);
+    private PasswordResolver passwordResolver;
+
+    public DefaultAuthenticator() {
+        this.passwordResolver = new NativePasswordResolver();
+    }
+
+    @Override
+    public AuthenticateResponse authenticate(AuthenticateRequest request) 
throws IOException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("user:{} start to default authenticate.", 
request.getUserName());
+        }
+        Password password = request.getPassword();
+        if (!(password instanceof NativePassword)) {
+            return AuthenticateResponse.failedResponse;
+        }
+        NativePassword nativePassword = (NativePassword) password;
+
+        List<UserIdentity> currentUserIdentity = Lists.newArrayList();
+        try {
+            Env.getCurrentEnv().getAuth().checkPassword(request.getUserName(), 
request.getRemoteIp(),
+                    nativePassword.getRemotePasswd(), 
nativePassword.getRandomString(), currentUserIdentity);
+        } catch (AuthenticationException e) {
+            ErrorReport.report(e.errorCode, e.msgs);
+            return AuthenticateResponse.failedResponse;
+        }
+        return new AuthenticateResponse(true, currentUserIdentity.get(0));
+    }
+
+    @Override
+    public boolean canDeal(String qualifiedUser) {
+        return true;
+    }
+
+    @Override
+    public PasswordResolver getPasswordResolver() {
+        return passwordResolver;
+    }
+}
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/MysqlAuth.java 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/MysqlAuth.java
deleted file mode 100644
index bb26c20796e..00000000000
--- 
a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/MysqlAuth.java
+++ /dev/null
@@ -1,205 +0,0 @@
-// 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 com.google.common.collect.Lists;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.util.List;
-
-
-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)) {
-            MysqlProto.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);
-            MysqlProto.sendResponsePacket(context);
-            return false;
-        }
-        if (!LdapAuthenticate.authenticate(context, 
clearTextPacket.getPassword(), qualifiedUser)) {
-            MysqlProto.sendResponsePacket(context);
-            return false;
-        }
-        return true;
-    }
-
-    // Based on FE configuration and some prerequisites, decide which 
authentication type to actually use
-    private 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);
-                    MysqlProto.sendResponsePacket(context);
-                    return MysqlAuthType.DEFAULT;
-                }
-                break;
-            default:
-        }
-        return typeConfig;
-    }
-
-    public static boolean authenticate(
-            ConnectContext context,
-            String qualifiedUser,
-            MysqlChannel channel,
-            MysqlSerializer serializer,
-            MysqlAuthPacket authPacket,
-            MysqlHandshakePacket handshakePacket) throws IOException {
-        MysqlAuthType authType = useWhichAuthType(context, qualifiedUser);
-        switch (authType) {
-            case DEFAULT:
-                return defaultAuth(context, qualifiedUser, channel, 
serializer, authPacket, handshakePacket);
-            case LDAP:
-                return ldapAuth(context, qualifiedUser, channel, serializer);
-            default:
-        }
-        return false;
-    }
-}
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticate.java
 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticator.java
similarity index 57%
rename from 
fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticate.java
rename to 
fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticator.java
index ee22aecc40d..e37112372ce 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticate.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticator.java
@@ -22,12 +22,20 @@ import org.apache.doris.catalog.Env;
 import org.apache.doris.cluster.ClusterNamespace;
 import org.apache.doris.common.ErrorCode;
 import org.apache.doris.common.ErrorReport;
-import org.apache.doris.qe.ConnectContext;
+import org.apache.doris.mysql.authenticate.AuthenticateRequest;
+import org.apache.doris.mysql.authenticate.AuthenticateResponse;
+import org.apache.doris.mysql.authenticate.Authenticator;
+import org.apache.doris.mysql.authenticate.password.ClearPassword;
+import org.apache.doris.mysql.authenticate.password.ClearPasswordResolver;
+import org.apache.doris.mysql.authenticate.password.Password;
+import org.apache.doris.mysql.authenticate.password.PasswordResolver;
+import org.apache.doris.mysql.privilege.Auth;
 
 import com.google.common.base.Strings;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
+import java.io.IOException;
 import java.util.List;
 
 /**
@@ -35,8 +43,43 @@ import java.util.List;
  * This means that users can log in to Doris with a user name and LDAP 
password,
  * and the user will get the privileges of all roles corresponding to the LDAP 
group.
  */
-public class LdapAuthenticate {
-    private static final Logger LOG = 
LogManager.getLogger(LdapAuthenticate.class);
+public class LdapAuthenticator implements Authenticator {
+    private static final Logger LOG = 
LogManager.getLogger(LdapAuthenticator.class);
+
+    private PasswordResolver passwordResolver;
+
+    public LdapAuthenticator() {
+        this.passwordResolver = new ClearPasswordResolver();
+    }
+
+    /*
+     * ldap:
+     * server ---AuthSwitch---> client
+     * server <--- clear text password --- client
+     */
+    @Override
+    public AuthenticateResponse authenticate(AuthenticateRequest request) 
throws IOException {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("user:{} start to ldap authenticate.", 
request.getUserName());
+        }
+        Password password = request.getPassword();
+        if (!(password instanceof ClearPassword)) {
+            return AuthenticateResponse.failedResponse;
+        }
+        ClearPassword clearPassword = (ClearPassword) password;
+        return internalAuthenticate(clearPassword.getPassword(), 
request.getUserName(), request.getRemoteIp());
+    }
+
+    @Override
+    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;
+    }
 
     /**
      * The LDAP authentication process is as follows:
@@ -45,7 +88,7 @@ public class LdapAuthenticate {
      * step3: Set current userIdentity. If the user account does not exist in 
Doris, login as a temporary user.
      * Otherwise, login to the Doris account.
      */
-    public static boolean authenticate(ConnectContext context, String 
password, String qualifiedUser) {
+    private AuthenticateResponse internalAuthenticate(String password, String 
qualifiedUser, String remoteIp) {
         String usePasswd = (Strings.isNullOrEmpty(password)) ? "NO" : "YES";
         String userName = ClusterNamespace.getNameFromFullName(qualifiedUser);
         if (LOG.isDebugEnabled()) {
@@ -56,35 +99,36 @@ public class LdapAuthenticate {
         try {
             if 
(!Env.getCurrentEnv().getAuth().getLdapManager().checkUserPasswd(qualifiedUser, 
password)) {
                 LOG.info("user:{} use check LDAP password failed.", userName);
-                ErrorReport.report(ErrorCode.ERR_ACCESS_DENIED_ERROR, 
qualifiedUser, context.getRemoteIP(), usePasswd);
-                return false;
+                ErrorReport.report(ErrorCode.ERR_ACCESS_DENIED_ERROR, 
qualifiedUser, remoteIp, usePasswd);
+                return AuthenticateResponse.failedResponse;
             }
         } catch (Exception e) {
             LOG.error("Check ldap password error.", e);
-            return false;
+            return AuthenticateResponse.failedResponse;
         }
 
-        String remoteIp = context.getMysqlChannel().getRemoteIp();
         UserIdentity tempUserIdentity = 
UserIdentity.createAnalyzedUserIdentWithIp(qualifiedUser, remoteIp);
         // Search the user in doris.
         List<UserIdentity> userIdentities = Env.getCurrentEnv().getAuth()
                 .getUserIdentityForLdap(qualifiedUser, remoteIp);
-        UserIdentity userIdentity;
+        AuthenticateResponse response = new AuthenticateResponse(true);
         if (userIdentities.isEmpty()) {
-            userIdentity = tempUserIdentity;
+            response.setUserIdentity(tempUserIdentity);
             if (LOG.isDebugEnabled()) {
                 LOG.debug("User:{} does not exists in doris, login as 
temporary users.", userName);
             }
-            context.setIsTempUser(true);
+            response.setTemp(true);
         } else {
-            userIdentity = userIdentities.get(0);
+            response.setUserIdentity(userIdentities.get(0));
         }
-
-        context.setCurrentUserIdentity(userIdentity);
-        context.setRemoteIP(remoteIp);
         if (LOG.isDebugEnabled()) {
-            LOG.debug("ldap authentication success: identity:{}", 
context.getCurrentUserIdentity());
+            LOG.debug("ldap authentication success: identity:{}", 
response.getUserIdentity());
         }
-        return true;
+        return response;
+    }
+
+    @Override
+    public PasswordResolver getPasswordResolver() {
+        return passwordResolver;
     }
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapManager.java
 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapManager.java
index 2accb404237..5f6003cd6c1 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapManager.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/ldap/LdapManager.java
@@ -25,7 +25,7 @@ import org.apache.doris.cluster.ClusterNamespace;
 import org.apache.doris.common.AnalysisException;
 import org.apache.doris.common.DdlException;
 import org.apache.doris.common.LdapConfig;
-import org.apache.doris.mysql.authenticate.MysqlAuthType;
+import org.apache.doris.mysql.authenticate.AuthenticateType;
 import org.apache.doris.mysql.privilege.Auth;
 import org.apache.doris.mysql.privilege.PrivBitSet;
 import org.apache.doris.mysql.privilege.Privilege;
@@ -103,7 +103,7 @@ public class LdapManager {
 
     public boolean checkUserPasswd(String fullName, String passwd) {
         String userName = ClusterNamespace.getNameFromFullName(fullName);
-        if (MysqlAuthType.getAuthTypeConfig() != MysqlAuthType.LDAP || 
Strings.isNullOrEmpty(userName)
+        if (AuthenticateType.getAuthTypeConfig() != AuthenticateType.LDAP || 
Strings.isNullOrEmpty(userName)
                 || Objects.isNull(passwd)) {
             return false;
         }
@@ -137,7 +137,7 @@ public class LdapManager {
     }
 
     private boolean checkParam(String fullName) {
-        return MysqlAuthType.getAuthTypeConfig() == MysqlAuthType.LDAP
+        return AuthenticateType.getAuthTypeConfig() == AuthenticateType.LDAP
                 && !Strings.isNullOrEmpty(fullName)
                 && !fullName.equalsIgnoreCase(Auth.ROOT_USER) && 
!fullName.equalsIgnoreCase(Auth.ADMIN_USER);
     }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/MysqlAuthType.java
 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/password/ClearPassword.java
similarity index 61%
copy from 
fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/MysqlAuthType.java
copy to 
fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/password/ClearPassword.java
index 9c19e5d9a58..47d82a3dd08 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/MysqlAuthType.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/password/ClearPassword.java
@@ -15,24 +15,16 @@
 // specific language governing permissions and limitations
 // under the License.
 
-package org.apache.doris.mysql.authenticate;
+package org.apache.doris.mysql.authenticate.password;
 
-import org.apache.doris.common.Config;
+public class ClearPassword extends Password {
+    private String password;
 
-public enum MysqlAuthType {
-    DEFAULT,
-    LDAP;
+    public ClearPassword(String password) {
+        this.password = password;
+    }
 
-    public static MysqlAuthType getAuthTypeConfig() {
-        switch (Config.authentication_type.toLowerCase()) {
-            case "default":
-                return DEFAULT;
-            case "ldap":
-                return LDAP;
-            // add other authentication system here
-            // case otherAuthType:
-            default:
-                return DEFAULT;
-        }
+    public String getPassword() {
+        return password;
     }
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/password/ClearPasswordResolver.java
 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/password/ClearPasswordResolver.java
new file mode 100644
index 00000000000..e11f38b1948
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/password/ClearPasswordResolver.java
@@ -0,0 +1,60 @@
+// 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.password;
+
+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.qe.ConnectContext;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Optional;
+
+public class ClearPasswordResolver implements PasswordResolver {
+    @Override
+    public Optional<Password> resolvePassword(ConnectContext context, 
MysqlChannel channel, MysqlSerializer serializer,
+            MysqlAuthPacket authPacket,
+            MysqlHandshakePacket handshakePacket) throws IOException {
+        // 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 Optional.empty();
+        }
+        MysqlClearTextPacket clearTextPacket = new MysqlClearTextPacket();
+        if (!clearTextPacket.readFrom(authSwitchResponse)) {
+            ErrorReport.report(ErrorCode.ERR_NOT_SUPPORTED_AUTH_MODE);
+            MysqlProto.sendResponsePacket(context);
+            return Optional.empty();
+        }
+        return Optional.of(new ClearPassword(clearTextPacket.getPassword()));
+    }
+}
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/MysqlAuthType.java
 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/password/NativePassword.java
similarity index 61%
copy from 
fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/MysqlAuthType.java
copy to 
fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/password/NativePassword.java
index 9c19e5d9a58..b88d3077d84 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/MysqlAuthType.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/password/NativePassword.java
@@ -15,24 +15,22 @@
 // specific language governing permissions and limitations
 // under the License.
 
-package org.apache.doris.mysql.authenticate;
+package org.apache.doris.mysql.authenticate.password;
 
-import org.apache.doris.common.Config;
+public class NativePassword extends Password {
+    private byte[] remotePasswd;
+    private byte[] randomString;
 
-public enum MysqlAuthType {
-    DEFAULT,
-    LDAP;
+    public NativePassword(byte[] remotePasswd, byte[] randomString) {
+        this.remotePasswd = remotePasswd;
+        this.randomString = randomString;
+    }
+
+    public byte[] getRemotePasswd() {
+        return remotePasswd;
+    }
 
-    public static MysqlAuthType getAuthTypeConfig() {
-        switch (Config.authentication_type.toLowerCase()) {
-            case "default":
-                return DEFAULT;
-            case "ldap":
-                return LDAP;
-            // add other authentication system here
-            // case otherAuthType:
-            default:
-                return DEFAULT;
-        }
+    public byte[] getRandomString() {
+        return randomString;
     }
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/password/NativePasswordResolver.java
 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/password/NativePasswordResolver.java
new file mode 100644
index 00000000000..e36eb1ab5dc
--- /dev/null
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/password/NativePasswordResolver.java
@@ -0,0 +1,71 @@
+// 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.password;
+
+import org.apache.doris.common.Config;
+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.qe.ConnectContext;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Optional;
+
+public class NativePasswordResolver implements PasswordResolver {
+    @Override
+    public Optional<Password> resolvePassword(ConnectContext context, 
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 Optional.empty();
+            }
+            // 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();
+        }
+        return Optional.of(new NativePassword(authPacket.getAuthResponse(), 
randomString));
+    }
+}
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/MysqlAuthType.java
 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/password/Password.java
similarity index 60%
copy from 
fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/MysqlAuthType.java
copy to 
fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/password/Password.java
index 9c19e5d9a58..1ed2c95bd66 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/MysqlAuthType.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/password/Password.java
@@ -15,24 +15,8 @@
 // specific language governing permissions and limitations
 // under the License.
 
-package org.apache.doris.mysql.authenticate;
+package org.apache.doris.mysql.authenticate.password;
 
-import org.apache.doris.common.Config;
+public abstract class Password {
 
-public enum MysqlAuthType {
-    DEFAULT,
-    LDAP;
-
-    public static MysqlAuthType getAuthTypeConfig() {
-        switch (Config.authentication_type.toLowerCase()) {
-            case "default":
-                return DEFAULT;
-            case "ldap":
-                return LDAP;
-            // add other authentication system here
-            // case otherAuthType:
-            default:
-                return DEFAULT;
-        }
-    }
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/MysqlAuthType.java
 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/password/PasswordResolver.java
similarity index 56%
rename from 
fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/MysqlAuthType.java
rename to 
fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/password/PasswordResolver.java
index 9c19e5d9a58..84855320022 100644
--- 
a/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/MysqlAuthType.java
+++ 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/authenticate/password/PasswordResolver.java
@@ -15,24 +15,20 @@
 // specific language governing permissions and limitations
 // under the License.
 
-package org.apache.doris.mysql.authenticate;
+package org.apache.doris.mysql.authenticate.password;
 
-import org.apache.doris.common.Config;
+import org.apache.doris.mysql.MysqlAuthPacket;
+import org.apache.doris.mysql.MysqlChannel;
+import org.apache.doris.mysql.MysqlHandshakePacket;
+import org.apache.doris.mysql.MysqlSerializer;
+import org.apache.doris.qe.ConnectContext;
 
-public enum MysqlAuthType {
-    DEFAULT,
-    LDAP;
+import java.io.IOException;
+import java.util.Optional;
 
-    public static MysqlAuthType getAuthTypeConfig() {
-        switch (Config.authentication_type.toLowerCase()) {
-            case "default":
-                return DEFAULT;
-            case "ldap":
-                return LDAP;
-            // add other authentication system here
-            // case otherAuthType:
-            default:
-                return DEFAULT;
-        }
-    }
+public interface PasswordResolver {
+    Optional<Password> resolvePassword(ConnectContext context, MysqlChannel 
channel,
+            MysqlSerializer serializer,
+            MysqlAuthPacket authPacket,
+            MysqlHandshakePacket handshakePacket) throws IOException;
 }
diff --git 
a/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java 
b/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java
index ef3e264487d..59ff2da6bec 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java
@@ -53,7 +53,7 @@ import org.apache.doris.common.UserException;
 import org.apache.doris.common.io.Writable;
 import org.apache.doris.datasource.InternalCatalog;
 import org.apache.doris.mysql.MysqlPassword;
-import org.apache.doris.mysql.authenticate.MysqlAuthType;
+import org.apache.doris.mysql.authenticate.AuthenticateType;
 import org.apache.doris.mysql.authenticate.ldap.LdapManager;
 import org.apache.doris.mysql.authenticate.ldap.LdapUserInfo;
 import org.apache.doris.persist.AlterUserOperationLog;
@@ -419,7 +419,7 @@ public class Auth implements Writable {
 
     // Check if LDAP authentication is enabled.
     private boolean isLdapAuthEnabled() {
-        return MysqlAuthType.getAuthTypeConfig() == MysqlAuthType.LDAP;
+        return AuthenticateType.getAuthTypeConfig() == AuthenticateType.LDAP;
     }
 
     // create user
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/mysql/MysqlProtoTest.java 
b/fe/fe-core/src/test/java/org/apache/doris/mysql/MysqlProtoTest.java
index 26239f18457..4ab2ba275de 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/mysql/MysqlProtoTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/mysql/MysqlProtoTest.java
@@ -20,12 +20,13 @@ package org.apache.doris.mysql;
 import org.apache.doris.analysis.UserIdentity;
 import org.apache.doris.catalog.Database;
 import org.apache.doris.catalog.Env;
-import org.apache.doris.cluster.ClusterNamespace;
 import org.apache.doris.common.AuthenticationException;
 import org.apache.doris.common.Config;
 import org.apache.doris.common.DdlException;
 import org.apache.doris.datasource.InternalCatalog;
-import org.apache.doris.mysql.authenticate.ldap.LdapAuthenticate;
+import org.apache.doris.mysql.authenticate.AuthenticateRequest;
+import org.apache.doris.mysql.authenticate.AuthenticatorManager;
+import org.apache.doris.mysql.authenticate.ldap.LdapAuthenticator;
 import org.apache.doris.mysql.authenticate.ldap.LdapManager;
 import org.apache.doris.mysql.privilege.AccessControllerManager;
 import org.apache.doris.mysql.privilege.Auth;
@@ -65,14 +66,16 @@ public class MysqlProtoTest {
     @Mocked
     private LdapManager ldapManager;
     @Mocked
-    private LdapAuthenticate ldapAuthenticate;
-    @Mocked
     private MysqlClearTextPacket clearTextPacket;
     @Mocked
-    StreamConnection streamConnection;
+    private StreamConnection streamConnection;
+    @Mocked
+    private LdapAuthenticator ldapAuthenticator;
+    @Mocked
+    private AuthenticatorManager authenticatorManager;
 
     @Before
-    public void setUp() throws DdlException, AuthenticationException {
+    public void setUp() throws DdlException, AuthenticationException, 
IOException {
 
         // mock auth
         new Expectations() {
@@ -95,6 +98,15 @@ public class MysqlProtoTest {
                 minTimes = 0;
                 result = catalog;
 
+                env.getAuthenticatorManager();
+                minTimes = 0;
+                result = authenticatorManager;
+
+                authenticatorManager.authenticate((ConnectContext) any, 
anyString, (MysqlChannel) any,
+                        (MysqlSerializer) any, (MysqlAuthPacket) any, 
(MysqlHandshakePacket) any);
+                minTimes = 0;
+                result = true;
+
                 catalog.getDbNullable(anyString);
                 minTimes = 0;
                 result = new Database();
@@ -215,19 +227,14 @@ public class MysqlProtoTest {
     private void mockAccess() throws Exception {
     }
 
-    private void mockLdap(String user, boolean userExist) {
+    private void mockLdap(boolean userExist) throws IOException {
         Config.authentication_type = "ldap";
 
         new Expectations() {
             {
-                LdapAuthenticate.authenticate((ConnectContext) any, anyString, 
anyString);
+                ldapAuthenticator.authenticate((AuthenticateRequest) any);
                 minTimes = 0;
-                result = new Delegate() {
-                    boolean fakeLdapAuthenticate(ConnectContext context, 
String password, String qualifiedUser) {
-                        return password.equals(PASSWORD_CLEAR_TEXT)
-                                && 
ClusterNamespace.getNameFromFullName(qualifiedUser).equals(user);
-                    }
-                };
+                result = true;
 
                 ldapManager.checkUserPasswd(anyString, anyString);
                 minTimes = 0;
@@ -285,7 +292,7 @@ public class MysqlProtoTest {
         mockPassword(true);
         mockAccess();
         mockMysqlClearTextPacket(PASSWORD_CLEAR_TEXT);
-        mockLdap("user", true);
+        mockLdap(true);
         ConnectContext context = new ConnectContext(streamConnection);
         context.setEnv(env);
         context.setThreadLocalInfo();
@@ -293,26 +300,12 @@ public class MysqlProtoTest {
         Config.authentication_type = "default";
     }
 
-    @Test
-    public void testNegotiateLdapInvalidPasswd() throws Exception {
-        mockChannel("user", true);
-        mockPassword(true);
-        mockAccess();
-        mockMysqlClearTextPacket("654321");
-        mockLdap("user", true);
-        ConnectContext context = new ConnectContext(streamConnection);
-        context.setEnv(env);
-        context.setThreadLocalInfo();
-        Assert.assertFalse(MysqlProto.negotiate(context));
-        Config.authentication_type = "default";
-    }
-
     @Test
     public void testNegotiateLdapRoot() throws Exception {
         mockChannel("root", true);
         mockPassword(true);
         mockAccess();
-        mockLdap("root", false);
+        mockLdap(false);
         mockMysqlClearTextPacket("654321");
         ConnectContext context = new ConnectContext(streamConnection);
         context.setEnv(env);
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/DefaultAuthenticatorTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/DefaultAuthenticatorTest.java
new file mode 100644
index 00000000000..04fd28dea28
--- /dev/null
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/DefaultAuthenticatorTest.java
@@ -0,0 +1,100 @@
+// 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.common.AuthenticationException;
+import org.apache.doris.common.DdlException;
+import org.apache.doris.mysql.authenticate.password.NativePassword;
+import org.apache.doris.mysql.authenticate.password.NativePasswordResolver;
+import org.apache.doris.mysql.privilege.Auth;
+
+import mockit.Delegate;
+import mockit.Expectations;
+import mockit.Mocked;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.List;
+
+public class DefaultAuthenticatorTest {
+    private static final String USER_NAME = "user";
+    private static final String IP = "192.168.1.1";
+
+    @Mocked
+    private Auth auth;
+
+    private DefaultAuthenticator defaultAuthenticator = new 
DefaultAuthenticator();
+    private AuthenticateRequest request = new AuthenticateRequest(USER_NAME,
+            new NativePassword(new byte[2], new byte[2]), IP);
+
+
+    @Before
+    public void setUp() throws DdlException, AuthenticationException, 
IOException {
+
+        // mock auth
+        new Expectations() {
+            {
+                auth.checkPassword(anyString, anyString, (byte[]) any, 
(byte[]) any, (List<UserIdentity>) any);
+                minTimes = 0;
+                result = new Delegate() {
+                    void fakeCheckPassword(String remoteUser, String 
remoteHost, byte[] remotePasswd,
+                            byte[] randomString, List<UserIdentity> 
currentUser) {
+                        UserIdentity userIdentity = new 
UserIdentity(USER_NAME, IP);
+                        currentUser.add(userIdentity);
+                    }
+                };
+            }
+        };
+    }
+
+
+    @Test
+    public void testAuthenticate() throws IOException {
+        AuthenticateResponse response = 
defaultAuthenticator.authenticate(request);
+        Assert.assertTrue(response.isSuccess());
+        Assert.assertFalse(response.isTemp());
+        Assert.assertEquals("'user'@'192.168.1.1'", 
response.getUserIdentity().toString());
+    }
+
+    @Test
+    public void testAuthenticateFailed() throws IOException, 
AuthenticationException {
+        new Expectations() {
+            {
+                auth.checkPassword(anyString, anyString, (byte[]) any, 
(byte[]) any, (List<UserIdentity>) any);
+                minTimes = 0;
+                result = new AuthenticationException("exception");
+            }
+        };
+        AuthenticateResponse response = 
defaultAuthenticator.authenticate(request);
+        Assert.assertFalse(response.isSuccess());
+    }
+
+
+    @Test
+    public void testCanDeal() {
+        Assert.assertTrue(defaultAuthenticator.canDeal("ss"));
+    }
+
+    @Test
+    public void testGetPasswordResolver() {
+        Assert.assertTrue(defaultAuthenticator.getPasswordResolver() 
instanceof NativePasswordResolver);
+    }
+}
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticateTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticateTest.java
deleted file mode 100644
index cee3feb6c46..00000000000
--- 
a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticateTest.java
+++ /dev/null
@@ -1,203 +0,0 @@
-// 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.analysis.UserIdentity;
-import org.apache.doris.catalog.Env;
-import org.apache.doris.common.DdlException;
-import org.apache.doris.mysql.privilege.AccessControllerManager;
-import org.apache.doris.mysql.privilege.Auth;
-import org.apache.doris.mysql.privilege.Role;
-import org.apache.doris.qe.ConnectContext;
-
-import com.google.common.collect.Sets;
-import mockit.Delegate;
-import mockit.Expectations;
-import mockit.Mocked;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.List;
-
-public class LdapAuthenticateTest {
-    private static final String USER_NAME = "user";
-    private static final String IP = "192.168.1.1";
-    private static final String TABLE_RD = "palo_rd";
-
-    private Role ldapGroupsPrivs;
-
-    @Mocked
-    private LdapManager ldapManager;
-    @Mocked
-    private Env env;
-    @Mocked
-    private Auth auth;
-    @Mocked
-    private AccessControllerManager accessManager;
-
-    @Before
-    public void setUp() throws DdlException {
-        new Expectations() {
-            {
-                auth.doesRoleExist(anyString);
-                minTimes = 0;
-                result = true;
-
-                auth.mergeRolesNoCheckName((List<String>) any, (Role) any);
-                minTimes = 0;
-                result = new Delegate() {
-                    void fakeMergeRolesNoCheckName(List<String> roles, Role 
savedRole) {
-                        ldapGroupsPrivs = savedRole;
-                    }
-                };
-
-                env.getAccessManager();
-                minTimes = 0;
-                result = accessManager;
-
-                env.getAuth();
-                minTimes = 0;
-                result = auth;
-
-                Env.getCurrentEnv();
-                minTimes = 0;
-                result = env;
-            }
-        };
-    }
-
-    private void setCheckPassword(boolean res) {
-        new Expectations() {
-            {
-                ldapManager.checkUserPasswd(anyString, anyString);
-                minTimes = 0;
-                result = res;
-            }
-        };
-    }
-
-    private void setCheckPasswordException() {
-        new Expectations() {
-            {
-                ldapManager.checkUserPasswd(anyString, anyString);
-                minTimes = 0;
-                result = new RuntimeException("exception");
-            }
-        };
-    }
-
-    private void setGetUserInfo(boolean res) {
-        new Expectations() {
-            {
-                if (res) {
-                    ldapManager.getUserInfo(anyString);
-                    minTimes = 0;
-                    result = new Delegate() {
-                        LdapUserInfo fakeGetGroups(String user) {
-                            return new LdapUserInfo(anyString, false, "", 
Sets.newHashSet(new Role(anyString)));
-                        }
-                    };
-                } else {
-                    ldapManager.getUserInfo(anyString);
-                    minTimes = 0;
-                    result = null;
-                }
-            }
-        };
-    }
-
-    private void setGetCurrentUserIdentity(boolean res) {
-        new Expectations() {
-            {
-                if (res) {
-                    auth.getCurrentUserIdentity((UserIdentity) any);
-                    minTimes = 0;
-                    result = new UserIdentity(USER_NAME, IP);
-                } else {
-                    auth.getCurrentUserIdentity((UserIdentity) any);
-                    minTimes = 0;
-                    result = null;
-                }
-            }
-        };
-    }
-
-    private ConnectContext getContext() {
-        ConnectContext context = new ConnectContext();
-        context.setEnv(env);
-        context.setThreadLocalInfo();
-        return context;
-    }
-
-
-    @Test
-    public void testAuthenticate() {
-        ConnectContext context = getContext();
-        setCheckPassword(true);
-        setGetUserInfo(true);
-        setGetCurrentUserIdentity(true);
-        String qualifiedUser = USER_NAME;
-        Assert.assertTrue(LdapAuthenticate.authenticate(context, "123", 
qualifiedUser));
-        Assert.assertTrue(context.getIsTempUser());
-    }
-
-    @Test
-    public void testAuthenticateWithWrongPassword() {
-        ConnectContext context = getContext();
-        setCheckPassword(false);
-        setGetUserInfo(true);
-        setGetCurrentUserIdentity(true);
-        String qualifiedUser = USER_NAME;
-        Assert.assertFalse(LdapAuthenticate.authenticate(context, "123", 
qualifiedUser));
-        Assert.assertFalse(context.getIsTempUser());
-    }
-
-    @Test
-    public void testAuthenticateWithCheckPasswordException() {
-        ConnectContext context = getContext();
-        setCheckPasswordException();
-        setGetUserInfo(true);
-        setGetCurrentUserIdentity(true);
-        String qualifiedUser = USER_NAME;
-        Assert.assertFalse(LdapAuthenticate.authenticate(context, "123", 
qualifiedUser));
-        Assert.assertFalse(context.getIsTempUser());
-    }
-
-    @Test
-    public void testAuthenticateGetGroupsNull() {
-        ConnectContext context = getContext();
-        setCheckPassword(true);
-        setGetUserInfo(false);
-        setGetCurrentUserIdentity(true);
-        String qualifiedUser = USER_NAME;
-        Assert.assertTrue(LdapAuthenticate.authenticate(context, "123", 
qualifiedUser));
-        Assert.assertTrue(context.getIsTempUser());
-    }
-
-    @Test
-    public void testAuthenticateUserNotExistInDoris() {
-        ConnectContext context = getContext();
-        setCheckPassword(true);
-        setGetUserInfo(true);
-        setGetCurrentUserIdentity(false);
-        String qualifiedUser = USER_NAME;
-        Assert.assertTrue(LdapAuthenticate.authenticate(context, "123", 
qualifiedUser));
-        Assert.assertTrue(context.getIsTempUser());
-    }
-}
diff --git 
a/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java
 
b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java
new file mode 100644
index 00000000000..99cbcdb5fad
--- /dev/null
+++ 
b/fe/fe-core/src/test/java/org/apache/doris/mysql/authenticate/ldap/LdapAuthenticatorTest.java
@@ -0,0 +1,146 @@
+// 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.analysis.UserIdentity;
+import org.apache.doris.mysql.authenticate.AuthenticateRequest;
+import org.apache.doris.mysql.authenticate.AuthenticateResponse;
+import org.apache.doris.mysql.authenticate.password.ClearPassword;
+import org.apache.doris.mysql.authenticate.password.ClearPasswordResolver;
+import org.apache.doris.mysql.privilege.Auth;
+
+import com.google.common.collect.Lists;
+import mockit.Expectations;
+import mockit.Mocked;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.List;
+
+public class LdapAuthenticatorTest {
+    private static final String USER_NAME = "user";
+    private static final String IP = "192.168.1.1";
+
+    @Mocked
+    private LdapManager ldapManager;
+
+    @Mocked
+    private Auth auth;
+
+    private LdapAuthenticator ldapAuthenticator = new LdapAuthenticator();
+    private AuthenticateRequest request = new AuthenticateRequest(USER_NAME, 
new ClearPassword("123"), IP);
+
+    private void setCheckPassword(boolean res) {
+        new Expectations() {
+            {
+                ldapManager.checkUserPasswd(anyString, anyString);
+                minTimes = 0;
+                result = res;
+            }
+        };
+    }
+
+    private void setCheckPasswordException() {
+        new Expectations() {
+            {
+                ldapManager.checkUserPasswd(anyString, anyString);
+                minTimes = 0;
+                result = new RuntimeException("exception");
+            }
+        };
+    }
+
+    private void setGetUserInDoris(boolean res) {
+        new Expectations() {
+            {
+                if (res) {
+                    List<UserIdentity> list = Lists.newArrayList(new 
UserIdentity(USER_NAME, IP));
+                    auth.getUserIdentityForLdap(anyString, anyString);
+                    minTimes = 0;
+                    result = list;
+                } else {
+                    auth.getCurrentUserIdentity((UserIdentity) any);
+                    minTimes = 0;
+                    result = null;
+                }
+            }
+        };
+    }
+
+    private void setLdapUserExist(boolean res) {
+        new Expectations() {
+            {
+                ldapManager.doesUserExist(anyString);
+                minTimes = 0;
+                result = res;
+            }
+        };
+    }
+
+    @Test
+    public void testAuthenticate() throws IOException {
+        setCheckPassword(true);
+        setGetUserInDoris(true);
+        AuthenticateResponse response = 
ldapAuthenticator.authenticate(request);
+        Assert.assertTrue(response.isSuccess());
+        Assert.assertFalse(response.isTemp());
+        Assert.assertEquals("'user'@'192.168.1.1'", 
response.getUserIdentity().toString());
+    }
+
+    @Test
+    public void testAuthenticateWithWrongPassword() throws IOException {
+        setCheckPassword(false);
+        setGetUserInDoris(true);
+        AuthenticateResponse response = 
ldapAuthenticator.authenticate(request);
+        Assert.assertFalse(response.isSuccess());
+    }
+
+    @Test
+    public void testAuthenticateWithCheckPasswordException() throws 
IOException {
+        setCheckPasswordException();
+        setGetUserInDoris(true);
+        AuthenticateResponse response = 
ldapAuthenticator.authenticate(request);
+        Assert.assertFalse(response.isSuccess());
+    }
+
+    @Test
+    public void testAuthenticateUserNotExistInDoris() throws IOException {
+        setCheckPassword(true);
+        setGetUserInDoris(false);
+        AuthenticateResponse response = 
ldapAuthenticator.authenticate(request);
+        Assert.assertTrue(response.isSuccess());
+        Assert.assertTrue(response.isTemp());
+        Assert.assertEquals("'user'@'192.168.1.1'", 
response.getUserIdentity().toString());
+    }
+
+    @Test
+    public void testCanDeal() {
+        setLdapUserExist(true);
+        Assert.assertFalse(ldapAuthenticator.canDeal(Auth.ROOT_USER));
+        Assert.assertFalse(ldapAuthenticator.canDeal(Auth.ADMIN_USER));
+        Assert.assertTrue(ldapAuthenticator.canDeal("ss"));
+        setLdapUserExist(false);
+        Assert.assertFalse(ldapAuthenticator.canDeal("ss"));
+    }
+
+    @Test
+    public void testGetPasswordResolver() {
+        Assert.assertTrue(ldapAuthenticator.getPasswordResolver() instanceof 
ClearPasswordResolver);
+    }
+}


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

Reply via email to