This is an automated email from the ASF dual-hosted git repository.
duanzhengqiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
The following commit(s) were added to refs/heads/master by this push:
new d0e096ba72a Add authenticator for AuthorityRule (#24121)
d0e096ba72a is described below
commit d0e096ba72ac7af072131168d4b3602b4d6cd437
Author: Liang Zhang <[email protected]>
AuthorDate: Sun Feb 12 09:05:05 2023 +0800
Add authenticator for AuthorityRule (#24121)
* Fix java doc
* Refactor MySQLAuthenticationHandler and PostgreSQLAuthenticationHandler
* Add authenticator for AuthorityRule
---
.../infra/metadata/user/ShardingSphereUser.java | 2 +-
.../config/AuthorityRuleConfiguration.java | 21 ++++++++++++++--
.../authority/model/AuthorityRegistry.java | 2 +-
.../authority/model/ShardingSpherePrivileges.java | 2 +-
.../authority/rule/AuthorityRule.java | 22 ++++++++++++++++-
.../config/YamlAuthorityRuleConfiguration.java | 6 +++++
.../YamlAuthorityRuleConfigurationSwapper.java | 8 ++++++-
.../authentication/MySQLAuthenticationEngine.java | 4 ++--
.../authentication/MySQLAuthenticationHandler.java | 28 ++++++++++++++++++----
.../MySQLAuthenticationHandlerTest.java | 6 +++--
.../PostgreSQLAuthenticationEngine.java | 8 +++++--
.../PostgreSQLAuthenticationHandler.java | 26 ++++++++++++++++----
.../PostgreSQLAuthenticationHandlerTest.java | 6 +++--
13 files changed, 116 insertions(+), 25 deletions(-)
diff --git
a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/user/ShardingSphereUser.java
b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/user/ShardingSphereUser.java
index 2077f6d91fb..771f6be71db 100644
---
a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/user/ShardingSphereUser.java
+++
b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/user/ShardingSphereUser.java
@@ -34,7 +34,7 @@ public final class ShardingSphereUser {
private final String authenticationMethodName;
public ShardingSphereUser(final String username, final String password,
final String hostname) {
- this(username, password, hostname, null);
+ this(username, password, hostname, "");
}
public ShardingSphereUser(final String username, final String password,
final String hostname, final String authenticationMethodName) {
diff --git
a/kernel/authority/api/src/main/java/org/apache/shardingsphere/authority/config/AuthorityRuleConfiguration.java
b/kernel/authority/api/src/main/java/org/apache/shardingsphere/authority/config/AuthorityRuleConfiguration.java
index ded23337fb9..090c91ec63e 100644
---
a/kernel/authority/api/src/main/java/org/apache/shardingsphere/authority/config/AuthorityRuleConfiguration.java
+++
b/kernel/authority/api/src/main/java/org/apache/shardingsphere/authority/config/AuthorityRuleConfiguration.java
@@ -18,21 +18,38 @@
package org.apache.shardingsphere.authority.config;
import lombok.Getter;
-import lombok.RequiredArgsConstructor;
+import lombok.Setter;
import org.apache.shardingsphere.infra.config.algorithm.AlgorithmConfiguration;
import
org.apache.shardingsphere.infra.config.rule.scope.GlobalRuleConfiguration;
import org.apache.shardingsphere.infra.metadata.user.ShardingSphereUser;
import java.util.Collection;
+import java.util.LinkedHashMap;
+import java.util.Map;
/**
* Authority rule configuration.
*/
-@RequiredArgsConstructor
@Getter
+@Setter
public final class AuthorityRuleConfiguration implements
GlobalRuleConfiguration {
private final Collection<ShardingSphereUser> users;
private final AlgorithmConfiguration provider;
+
+ private final Map<String, AlgorithmConfiguration> authenticators = new
LinkedHashMap<>();
+
+ private String defaultAuthenticator;
+
+ public AuthorityRuleConfiguration(final Collection<ShardingSphereUser>
users, final AlgorithmConfiguration provider) {
+ this.users = users;
+ this.provider = provider;
+ }
+
+ public AuthorityRuleConfiguration(final Collection<ShardingSphereUser>
users, final AlgorithmConfiguration provider, final String
defaultAuthenticator) {
+ this.users = users;
+ this.provider = provider;
+ this.defaultAuthenticator = defaultAuthenticator;
+ }
}
diff --git
a/kernel/authority/api/src/main/java/org/apache/shardingsphere/authority/model/AuthorityRegistry.java
b/kernel/authority/api/src/main/java/org/apache/shardingsphere/authority/model/AuthorityRegistry.java
index 4bdb833e8c1..8c73f9a77bc 100644
---
a/kernel/authority/api/src/main/java/org/apache/shardingsphere/authority/model/AuthorityRegistry.java
+++
b/kernel/authority/api/src/main/java/org/apache/shardingsphere/authority/model/AuthorityRegistry.java
@@ -27,7 +27,7 @@ import java.util.Optional;
public interface AuthorityRegistry {
/**
- * Find Privileges.
+ * Find privileges.
*
* @param grantee grantee
* @return found privileges
diff --git
a/kernel/authority/api/src/main/java/org/apache/shardingsphere/authority/model/ShardingSpherePrivileges.java
b/kernel/authority/api/src/main/java/org/apache/shardingsphere/authority/model/ShardingSpherePrivileges.java
index d8fc42341ca..daabf949f64 100644
---
a/kernel/authority/api/src/main/java/org/apache/shardingsphere/authority/model/ShardingSpherePrivileges.java
+++
b/kernel/authority/api/src/main/java/org/apache/shardingsphere/authority/model/ShardingSpherePrivileges.java
@@ -20,7 +20,7 @@ package org.apache.shardingsphere.authority.model;
import java.util.Collection;
/**
- * ShardingSphere Privileges.
+ * ShardingSphere privileges.
*/
public interface ShardingSpherePrivileges {
diff --git
a/kernel/authority/core/src/main/java/org/apache/shardingsphere/authority/rule/AuthorityRule.java
b/kernel/authority/core/src/main/java/org/apache/shardingsphere/authority/rule/AuthorityRule.java
index 714bf2ebb63..45e6b43d2ca 100644
---
a/kernel/authority/core/src/main/java/org/apache/shardingsphere/authority/rule/AuthorityRule.java
+++
b/kernel/authority/core/src/main/java/org/apache/shardingsphere/authority/rule/AuthorityRule.java
@@ -22,6 +22,7 @@ import
org.apache.shardingsphere.authority.config.AuthorityRuleConfiguration;
import org.apache.shardingsphere.authority.model.AuthorityRegistry;
import org.apache.shardingsphere.authority.model.ShardingSpherePrivileges;
import org.apache.shardingsphere.authority.spi.AuthorityProvider;
+import org.apache.shardingsphere.infra.config.algorithm.AlgorithmConfiguration;
import
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import org.apache.shardingsphere.infra.metadata.user.Grantee;
import org.apache.shardingsphere.infra.metadata.user.ShardingSphereUser;
@@ -29,6 +30,7 @@ import
org.apache.shardingsphere.infra.rule.identifier.scope.GlobalRule;
import org.apache.shardingsphere.infra.util.spi.type.typed.TypedSPILoader;
import java.util.Collection;
+import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
@@ -46,16 +48,22 @@ public final class AuthorityRule implements GlobalRule {
private volatile AuthorityRegistry authorityRegistry;
+ private final Map<String, AlgorithmConfiguration> authenticatorConfig =
new LinkedHashMap<>();
+
+ private final String defaultAuthenticator;
+
public AuthorityRule(final AuthorityRuleConfiguration ruleConfig, final
Map<String, ShardingSphereDatabase> databases) {
configuration = ruleConfig;
users = ruleConfig.getUsers();
provider = TypedSPILoader.getService(AuthorityProvider.class,
ruleConfig.getProvider().getType(), ruleConfig.getProvider().getProps());
authorityRegistry = provider.buildAuthorityRegistry(databases,
ruleConfig.getUsers());
+ authenticatorConfig.putAll(ruleConfig.getAuthenticators());
+ defaultAuthenticator = ruleConfig.getDefaultAuthenticator();
}
/**
* Find user.
- *
+ *
* @param grantee grantee user
* @return user
*/
@@ -83,6 +91,18 @@ public final class AuthorityRule implements GlobalRule {
authorityRegistry = provider.buildAuthorityRegistry(databases, users);
}
+ /**
+ * Get authenticator type.
+ *
+ * @param user user
+ * @return authenticator type
+ */
+ public String getAuthenticatorType(final ShardingSphereUser user) {
+ return
authenticatorConfig.containsKey(user.getAuthenticationMethodName())
+ ?
authenticatorConfig.get(user.getAuthenticationMethodName()).getType()
+ : Optional.ofNullable(defaultAuthenticator).orElse("");
+ }
+
@Override
public String getType() {
return AuthorityRule.class.getSimpleName();
diff --git
a/kernel/authority/core/src/main/java/org/apache/shardingsphere/authority/yaml/config/YamlAuthorityRuleConfiguration.java
b/kernel/authority/core/src/main/java/org/apache/shardingsphere/authority/yaml/config/YamlAuthorityRuleConfiguration.java
index d3395a9ea3f..bd876836e6f 100644
---
a/kernel/authority/core/src/main/java/org/apache/shardingsphere/authority/yaml/config/YamlAuthorityRuleConfiguration.java
+++
b/kernel/authority/core/src/main/java/org/apache/shardingsphere/authority/yaml/config/YamlAuthorityRuleConfiguration.java
@@ -25,7 +25,9 @@ import
org.apache.shardingsphere.infra.yaml.config.pojo.algorithm.YamlAlgorithmC
import
org.apache.shardingsphere.infra.yaml.config.pojo.rule.YamlGlobalRuleConfiguration;
import java.util.Collection;
+import java.util.LinkedHashMap;
import java.util.LinkedList;
+import java.util.Map;
/**
* Authority rule configuration for YAML.
@@ -38,6 +40,10 @@ public final class YamlAuthorityRuleConfiguration implements
YamlGlobalRuleConfi
private YamlAlgorithmConfiguration privilege;
+ private Map<String, YamlAlgorithmConfiguration> authenticators = new
LinkedHashMap<>();
+
+ private String defaultAuthenticator;
+
@Override
public Class<AuthorityRuleConfiguration> getRuleConfigurationType() {
return AuthorityRuleConfiguration.class;
diff --git
a/kernel/authority/core/src/main/java/org/apache/shardingsphere/authority/yaml/swapper/YamlAuthorityRuleConfigurationSwapper.java
b/kernel/authority/core/src/main/java/org/apache/shardingsphere/authority/yaml/swapper/YamlAuthorityRuleConfigurationSwapper.java
index df0ed9a430f..beec7892d27 100644
---
a/kernel/authority/core/src/main/java/org/apache/shardingsphere/authority/yaml/swapper/YamlAuthorityRuleConfigurationSwapper.java
+++
b/kernel/authority/core/src/main/java/org/apache/shardingsphere/authority/yaml/swapper/YamlAuthorityRuleConfigurationSwapper.java
@@ -41,6 +41,10 @@ public final class YamlAuthorityRuleConfigurationSwapper
implements YamlRuleConf
YamlAuthorityRuleConfiguration result = new
YamlAuthorityRuleConfiguration();
result.setPrivilege(algorithmSwapper.swapToYamlConfiguration(data.getProvider()));
result.setUsers(YamlUsersConfigurationConverter.convertToYamlUserConfiguration(data.getUsers()));
+ result.setDefaultAuthenticator(data.getDefaultAuthenticator());
+ if (!data.getAuthenticators().isEmpty()) {
+ data.getAuthenticators().forEach((key, value) ->
result.getAuthenticators().put(key,
algorithmSwapper.swapToYamlConfiguration(value)));
+ }
return result;
}
@@ -51,7 +55,9 @@ public final class YamlAuthorityRuleConfigurationSwapper
implements YamlRuleConf
if (null == provider) {
provider = new
DefaultAuthorityRuleConfigurationBuilder().build().getProvider();
}
- return new AuthorityRuleConfiguration(users, provider);
+ AuthorityRuleConfiguration result = new
AuthorityRuleConfiguration(users, provider,
yamlConfig.getDefaultAuthenticator());
+ yamlConfig.getAuthenticators().forEach((key, value) ->
result.getAuthenticators().put(key, algorithmSwapper.swapToObject(value)));
+ return result;
}
@Override
diff --git
a/proxy/frontend/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationEngine.java
b/proxy/frontend/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationEngine.java
index c9517ec843d..eca0d2c44aa 100644
---
a/proxy/frontend/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationEngine.java
+++
b/proxy/frontend/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationEngine.java
@@ -35,7 +35,7 @@ import
org.apache.shardingsphere.db.protocol.mysql.packet.handshake.MySQLHandsha
import org.apache.shardingsphere.db.protocol.mysql.payload.MySQLPacketPayload;
import org.apache.shardingsphere.db.protocol.payload.PacketPayload;
import org.apache.shardingsphere.dialect.mysql.vendor.MySQLVendorError;
-import org.apache.shardingsphere.infra.metadata.user.Grantee;
+import org.apache.shardingsphere.infra.metadata.user.ShardingSphereUser;
import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
import
org.apache.shardingsphere.proxy.frontend.authentication.AuthenticationEngine;
import
org.apache.shardingsphere.proxy.frontend.authentication.AuthenticationResult;
@@ -104,7 +104,7 @@ public final class MySQLAuthenticationEngine implements
AuthenticationEngine {
return AuthenticationResultBuilder.continued();
}
AuthorityRule rule =
ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getSingleRule(AuthorityRule.class);
- MySQLAuthenticator authenticator =
authenticationHandler.getAuthenticator(rule, new Grantee(packet.getUsername(),
getHostAddress(context)));
+ MySQLAuthenticator authenticator =
authenticationHandler.getAuthenticator(rule, new
ShardingSphereUser(packet.getUsername(), "", getHostAddress(context)));
if (isClientPluginAuth(packet) &&
!authenticator.getAuthenticationMethodName().equals(packet.getAuthPluginName()))
{
connectionPhase =
MySQLConnectionPhase.AUTHENTICATION_METHOD_MISMATCH;
context.writeAndFlush(new
MySQLAuthSwitchRequestPacket(authenticator.getAuthenticationMethodName(),
authenticationHandler.getAuthPluginData()));
diff --git
a/proxy/frontend/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationHandler.java
b/proxy/frontend/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationHandler.java
index 609acf5fa94..6557629da69 100644
---
a/proxy/frontend/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationHandler.java
+++
b/proxy/frontend/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationHandler.java
@@ -20,12 +20,14 @@ package
org.apache.shardingsphere.proxy.frontend.mysql.authentication;
import lombok.Getter;
import org.apache.shardingsphere.authority.checker.AuthorityChecker;
import org.apache.shardingsphere.authority.rule.AuthorityRule;
+import
org.apache.shardingsphere.db.protocol.mysql.constant.MySQLAuthenticationMethod;
import
org.apache.shardingsphere.db.protocol.mysql.packet.handshake.MySQLAuthPluginData;
import org.apache.shardingsphere.dialect.mysql.vendor.MySQLVendorError;
import org.apache.shardingsphere.infra.metadata.user.Grantee;
import org.apache.shardingsphere.infra.metadata.user.ShardingSphereUser;
import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
import
org.apache.shardingsphere.proxy.frontend.mysql.authentication.authenticator.MySQLAuthenticator;
+import
org.apache.shardingsphere.proxy.frontend.mysql.authentication.authenticator.MySQLClearPasswordAuthenticator;
import
org.apache.shardingsphere.proxy.frontend.mysql.authentication.authenticator.MySQLNativePasswordAuthenticator;
import java.util.Optional;
@@ -51,7 +53,7 @@ public final class MySQLAuthenticationHandler {
AuthorityRule rule =
ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getSingleRule(AuthorityRule.class);
Grantee grantee = new Grantee(username, hostname);
Optional<ShardingSphereUser> user = rule.findUser(grantee);
- if (!user.isPresent() || !getAuthenticator(rule,
grantee).authenticate(user.get(), authenticationResponse)) {
+ if (!user.isPresent() || !getAuthenticator(rule,
user.get()).authenticate(user.get(), authenticationResponse)) {
return Optional.of(MySQLVendorError.ER_ACCESS_DENIED_ERROR);
}
return null == databaseName || new AuthorityChecker(rule,
grantee).isAuthorized(databaseName) ? Optional.empty() :
Optional.of(MySQLVendorError.ER_DBACCESS_DENIED_ERROR);
@@ -61,11 +63,27 @@ public final class MySQLAuthenticationHandler {
* Get authenticator.
*
* @param rule authority rule
- * @param grantee grantee
+ * @param user user
* @return authenticator
*/
- public MySQLAuthenticator getAuthenticator(final AuthorityRule rule, final
Grantee grantee) {
- // TODO use authority rule and grantee to determine authentication
method
- return new MySQLNativePasswordAuthenticator(authPluginData);
+ public MySQLAuthenticator getAuthenticator(final AuthorityRule rule, final
ShardingSphereUser user) {
+ MySQLAuthenticationMethod authenticationMethod;
+ try {
+ authenticationMethod =
MySQLAuthenticationMethod.valueOf(rule.getAuthenticatorType(user).toUpperCase());
+ } catch (final IllegalArgumentException ignored) {
+ return new MySQLNativePasswordAuthenticator(authPluginData);
+ }
+ switch (authenticationMethod) {
+ case SECURE_PASSWORD_AUTHENTICATION:
+ return new MySQLNativePasswordAuthenticator(authPluginData);
+ case CLEAR_TEXT_AUTHENTICATION:
+ return new MySQLClearPasswordAuthenticator();
+ // TODO add other Authenticator
+ case OLD_PASSWORD_AUTHENTICATION:
+ case WINDOWS_NATIVE_AUTHENTICATION:
+ case SHA256:
+ default:
+ return new MySQLNativePasswordAuthenticator(authPluginData);
+ }
}
}
diff --git
a/proxy/frontend/mysql/src/test/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationHandlerTest.java
b/proxy/frontend/mysql/src/test/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationHandlerTest.java
index 8041a668779..982c0746f8c 100644
---
a/proxy/frontend/mysql/src/test/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationHandlerTest.java
+++
b/proxy/frontend/mysql/src/test/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationHandlerTest.java
@@ -31,7 +31,6 @@ import
org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
import
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import
org.apache.shardingsphere.infra.metadata.database.rule.ShardingSphereRuleMetaData;
-import org.apache.shardingsphere.infra.metadata.user.Grantee;
import org.apache.shardingsphere.infra.metadata.user.ShardingSphereUser;
import org.apache.shardingsphere.mode.manager.ContextManager;
import org.apache.shardingsphere.mode.metadata.MetaDataContexts;
@@ -121,7 +120,10 @@ public final class MySQLAuthenticationHandlerTest extends
ProxyContextRestorer {
@Test
public void assertGetAuthenticator() {
- MySQLAuthenticator authenticator =
authenticationHandler.getAuthenticator(mock(AuthorityRule.class), new
Grantee("root", ""));
+ ShardingSphereUser user = new ShardingSphereUser("root", "", "");
+ AuthorityRule rule = mock(AuthorityRule.class);
+ when(rule.getAuthenticatorType(user)).thenReturn("");
+ MySQLAuthenticator authenticator =
authenticationHandler.getAuthenticator(rule, user);
assertThat(authenticator,
instanceOf(MySQLNativePasswordAuthenticator.class));
assertThat(authenticator.getAuthenticationMethodName(),
is(MySQLAuthenticationMethod.SECURE_PASSWORD_AUTHENTICATION.getMethodName()));
}
diff --git
a/proxy/frontend/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngine.java
b/proxy/frontend/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngine.java
index 564b11ffacb..62ed7a39348 100644
---
a/proxy/frontend/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngine.java
+++
b/proxy/frontend/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngine.java
@@ -39,6 +39,7 @@ import
org.apache.shardingsphere.db.protocol.postgresql.payload.PostgreSQLPacket
import
org.apache.shardingsphere.dialect.postgresql.exception.authority.EmptyUsernameException;
import
org.apache.shardingsphere.dialect.postgresql.exception.protocol.ProtocolViolationException;
import org.apache.shardingsphere.infra.metadata.user.Grantee;
+import org.apache.shardingsphere.infra.metadata.user.ShardingSphereUser;
import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
import
org.apache.shardingsphere.proxy.backend.handler.admin.postgresql.PostgreSQLCharacterSets;
import
org.apache.shardingsphere.proxy.frontend.authentication.AuthenticationEngine;
@@ -47,6 +48,8 @@ import
org.apache.shardingsphere.proxy.frontend.authentication.AuthenticationRes
import
org.apache.shardingsphere.proxy.frontend.connection.ConnectionIdGenerator;
import
org.apache.shardingsphere.proxy.frontend.postgresql.authentication.authenticator.PostgreSQLAuthenticator;
+import java.util.Optional;
+
/**
* Authentication engine for PostgreSQL.
*/
@@ -115,8 +118,9 @@ public final class PostgreSQLAuthenticationEngine
implements AuthenticationEngin
private PostgreSQLIdentifierPacket getIdentifierPacket(final String
username) {
AuthorityRule rule =
ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getSingleRule(AuthorityRule.class);
- PostgreSQLAuthenticator authenticator =
authenticationHandler.getAuthenticator(rule, new Grantee(username, ""));
- if
(PostgreSQLAuthenticationMethod.PASSWORD.getMethodName().equals(authenticator.getAuthenticationMethodName()))
{
+ Optional<ShardingSphereUser> user = rule.findUser(new
Grantee(username, ""));
+ Optional<PostgreSQLAuthenticator> authenticator = user.map(optional ->
authenticationHandler.getAuthenticator(rule, optional));
+ if (authenticator.isPresent() &&
PostgreSQLAuthenticationMethod.PASSWORD.getMethodName().equals(authenticator.get().getAuthenticationMethodName()))
{
return new PostgreSQLPasswordAuthenticationPacket();
}
md5Salt =
PostgreSQLRandomGenerator.getInstance().generateRandomBytes(4);
diff --git
a/proxy/frontend/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationHandler.java
b/proxy/frontend/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationHandler.java
index 5591b96e6f5..ecbadb10c05 100644
---
a/proxy/frontend/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationHandler.java
+++
b/proxy/frontend/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationHandler.java
@@ -20,6 +20,7 @@ package
org.apache.shardingsphere.proxy.frontend.postgresql.authentication;
import com.google.common.base.Strings;
import org.apache.shardingsphere.authority.checker.AuthorityChecker;
import org.apache.shardingsphere.authority.rule.AuthorityRule;
+import
org.apache.shardingsphere.db.protocol.postgresql.constant.PostgreSQLAuthenticationMethod;
import
org.apache.shardingsphere.db.protocol.postgresql.packet.handshake.PostgreSQLPasswordMessagePacket;
import
org.apache.shardingsphere.dialect.exception.syntax.database.UnknownDatabaseException;
import
org.apache.shardingsphere.dialect.postgresql.exception.authority.InvalidPasswordException;
@@ -31,6 +32,7 @@ import
org.apache.shardingsphere.infra.util.exception.ShardingSpherePrecondition
import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
import
org.apache.shardingsphere.proxy.frontend.postgresql.authentication.authenticator.PostgreSQLAuthenticator;
import
org.apache.shardingsphere.proxy.frontend.postgresql.authentication.authenticator.PostgreSQLMD5PasswordAuthenticator;
+import
org.apache.shardingsphere.proxy.frontend.postgresql.authentication.authenticator.PostgreSQLPasswordAuthenticator;
import java.util.Optional;
@@ -53,7 +55,7 @@ public final class PostgreSQLAuthenticationHandler {
Grantee grantee = new Grantee(username, "%");
Optional<ShardingSphereUser> user = rule.findUser(grantee);
ShardingSpherePreconditions.checkState(user.isPresent(), () -> new
UnknownUsernameException(username));
- ShardingSpherePreconditions.checkState(getAuthenticator(rule,
grantee).authenticate(user.get(), new
Object[]{passwordMessagePacket.getDigest(), md5Salt}),
+ ShardingSpherePreconditions.checkState(getAuthenticator(rule,
user.get()).authenticate(user.get(), new
Object[]{passwordMessagePacket.getDigest(), md5Salt}),
() -> new InvalidPasswordException(username));
ShardingSpherePreconditions.checkState(null == databaseName || new
AuthorityChecker(rule, grantee).isAuthorized(databaseName),
() -> new PrivilegeNotGrantedException(username,
databaseName));
@@ -63,11 +65,25 @@ public final class PostgreSQLAuthenticationHandler {
* Get authenticator.
*
* @param rule authority rule
- * @param grantee username
+ * @param user user
* @return authenticator
*/
- public PostgreSQLAuthenticator getAuthenticator(final AuthorityRule rule,
final Grantee grantee) {
- // TODO use authority rule and grantee to determine authentication
method
- return new PostgreSQLMD5PasswordAuthenticator();
+ public PostgreSQLAuthenticator getAuthenticator(final AuthorityRule rule,
final ShardingSphereUser user) {
+ PostgreSQLAuthenticationMethod authenticationMethod;
+ try {
+ authenticationMethod =
PostgreSQLAuthenticationMethod.valueOf(rule.getAuthenticatorType(user).toUpperCase());
+ } catch (final IllegalArgumentException ignored) {
+ return new PostgreSQLMD5PasswordAuthenticator();
+ }
+ switch (authenticationMethod) {
+ case MD5:
+ return new PostgreSQLMD5PasswordAuthenticator();
+ case PASSWORD:
+ return new PostgreSQLPasswordAuthenticator();
+ case SCRAM_SHA256:
+ // TODO add SCRAM_SHA256 Authenticator
+ default:
+ return new PostgreSQLMD5PasswordAuthenticator();
+ }
}
}
diff --git
a/proxy/frontend/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationHandlerTest.java
b/proxy/frontend/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationHandlerTest.java
index 784b2f702de..f57e125c26a 100644
---
a/proxy/frontend/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationHandlerTest.java
+++
b/proxy/frontend/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationHandlerTest.java
@@ -37,7 +37,6 @@ import
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import
org.apache.shardingsphere.infra.metadata.database.resource.ShardingSphereResourceMetaData;
import
org.apache.shardingsphere.infra.metadata.database.rule.ShardingSphereRuleMetaData;
import
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
-import org.apache.shardingsphere.infra.metadata.user.Grantee;
import org.apache.shardingsphere.infra.metadata.user.ShardingSphereUser;
import org.apache.shardingsphere.mode.manager.ContextManager;
import org.apache.shardingsphere.mode.metadata.MetaDataContexts;
@@ -112,7 +111,10 @@ public final class PostgreSQLAuthenticationHandlerTest
extends ProxyContextResto
@Test
public void assertGetAuthenticator() {
- PostgreSQLAuthenticator authenticator = new
PostgreSQLAuthenticationHandler().getAuthenticator(mock(AuthorityRule.class),
new Grantee(username, ""));
+ ShardingSphereUser user = new ShardingSphereUser(username, "", "");
+ AuthorityRule rule = mock(AuthorityRule.class);
+ when(rule.getAuthenticatorType(user)).thenReturn("");
+ PostgreSQLAuthenticator authenticator = new
PostgreSQLAuthenticationHandler().getAuthenticator(rule, user);
assertThat(authenticator,
instanceOf(PostgreSQLMD5PasswordAuthenticator.class));
assertThat(authenticator.getAuthenticationMethodName(),
is(PostgreSQLAuthenticationMethod.MD5.getMethodName()));
}