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 <[email protected]>
AuthorDate: Mon Apr 22 14:47:59 2024 +0800
[enhance](auth)Abstract authentication interface (#33668) (#33961)
bp #33668
Co-authored-by: zhangdong <[email protected]>
---
.../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: [email protected]
For additional commands, e-mail: [email protected]