You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by du...@apache.org on 2023/02/11 10:47:36 UTC
[shardingsphere] branch master updated: Add authority rule on XXXAuthenticationHandler.getAuthenticator (#24119)
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 04b6898c92d Add authority rule on XXXAuthenticationHandler.getAuthenticator (#24119)
04b6898c92d is described below
commit 04b6898c92d2fd99db0d2dce55c14cd97dbc341e
Author: Liang Zhang <zh...@apache.org>
AuthorDate: Sat Feb 11 18:47:28 2023 +0800
Add authority rule on XXXAuthenticationHandler.getAuthenticator (#24119)
---
.../swapper/YamlPluginsConfigurationSwapperTest.java | 17 +++++++++--------
.../mysql/authentication/MySQLAuthenticationEngine.java | 4 +++-
.../authentication/MySQLAuthenticationHandler.java | 12 +++++++-----
.../authentication/MySQLAuthenticationEngineTest.java | 3 ++-
.../authentication/MySQLAuthenticationHandlerTest.java | 2 +-
.../authentication/PostgreSQLAuthenticationEngine.java | 5 ++++-
.../authentication/PostgreSQLAuthenticationHandler.java | 12 +++++++-----
.../PostgreSQLAuthenticationEngineTest.java | 14 +++++++-------
.../PostgreSQLAuthenticationHandlerTest.java | 2 +-
9 files changed, 41 insertions(+), 30 deletions(-)
diff --git a/agent/core/src/test/java/org/apache/shardingsphere/agent/core/advisor/config/yaml/swapper/YamlPluginsConfigurationSwapperTest.java b/agent/core/src/test/java/org/apache/shardingsphere/agent/core/advisor/config/yaml/swapper/YamlPluginsConfigurationSwapperTest.java
index e04ad486473..8f21a54e4ec 100644
--- a/agent/core/src/test/java/org/apache/shardingsphere/agent/core/advisor/config/yaml/swapper/YamlPluginsConfigurationSwapperTest.java
+++ b/agent/core/src/test/java/org/apache/shardingsphere/agent/core/advisor/config/yaml/swapper/YamlPluginsConfigurationSwapperTest.java
@@ -39,9 +39,9 @@ import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertNull;
public final class YamlPluginsConfigurationSwapperTest {
-
+
private static final String CONFIG_PATH = "/conf/agent.yaml";
-
+
@Test
public void assertSwap() throws IOException {
YamlAgentConfiguration yamlAgentConfiguration = getAgentConfiguration();
@@ -52,19 +52,20 @@ public final class YamlPluginsConfigurationSwapperTest {
assertMetricsPluginConfiguration(pluginConfigurationMap.get("MetricsFixture"));
assertTracingPluginConfiguration(pluginConfigurationMap.get("TracingFixture"));
}
-
+
private YamlAgentConfiguration getAgentConfiguration() throws UnsupportedEncodingException, FileNotFoundException {
FileInputStream fileInputStream = new FileInputStream(new File(getResourceURL(), CONFIG_PATH));
InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream);
return new Yaml().loadAs(inputStreamReader, YamlAgentConfiguration.class);
}
-
+
private String getResourceURL() throws UnsupportedEncodingException {
return URLDecoder.decode(
Objects.requireNonNull(YamlPluginsConfigurationSwapper.class.getClassLoader().getResource(""))
- .getFile(), "UTF8");
+ .getFile(),
+ "UTF8");
}
-
+
private void assertLogFixturePluginConfiguration(final PluginConfiguration pluginConfiguration) {
assertNull(pluginConfiguration.getHost());
assertThat(pluginConfiguration.getPort(), is(0));
@@ -72,7 +73,7 @@ public final class YamlPluginsConfigurationSwapperTest {
assertThat(pluginConfiguration.getProps().size(), is(1));
assertThat(pluginConfiguration.getProps().getProperty("logging_key"), is("logging_value"));
}
-
+
private void assertMetricsPluginConfiguration(final PluginConfiguration pluginConfiguration) {
assertThat(pluginConfiguration.getHost(), is("metrics.host"));
assertThat(pluginConfiguration.getPort(), is(1));
@@ -80,7 +81,7 @@ public final class YamlPluginsConfigurationSwapperTest {
assertThat(pluginConfiguration.getProps().size(), is(1));
assertThat(pluginConfiguration.getProps().getProperty("metrics_key"), is("metrics_value"));
}
-
+
private void assertTracingPluginConfiguration(final PluginConfiguration pluginConfiguration) {
assertThat(pluginConfiguration.getHost(), is("tracing.host"));
assertThat(pluginConfiguration.getPort(), is(2));
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 08550808cbd..c9517ec843d 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
@@ -19,6 +19,7 @@ package org.apache.shardingsphere.proxy.frontend.mysql.authentication;
import com.google.common.base.Strings;
import io.netty.channel.ChannelHandlerContext;
+import org.apache.shardingsphere.authority.rule.AuthorityRule;
import org.apache.shardingsphere.db.protocol.CommonConstants;
import org.apache.shardingsphere.db.protocol.mysql.constant.MySQLCapabilityFlag;
import org.apache.shardingsphere.db.protocol.mysql.constant.MySQLCharacterSet;
@@ -102,7 +103,8 @@ public final class MySQLAuthenticationEngine implements AuthenticationEngine {
context.close();
return AuthenticationResultBuilder.continued();
}
- MySQLAuthenticator authenticator = authenticationHandler.getAuthenticator(new Grantee(packet.getUsername(), getHostAddress(context)));
+ AuthorityRule rule = ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getSingleRule(AuthorityRule.class);
+ MySQLAuthenticator authenticator = authenticationHandler.getAuthenticator(rule, new Grantee(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 8cf729cbf0b..609acf5fa94 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
@@ -48,22 +48,24 @@ public final class MySQLAuthenticationHandler {
* @return login success or failure
*/
public Optional<MySQLVendorError> login(final String username, final String hostname, final byte[] authenticationResponse, final String databaseName) {
- AuthorityRule authorityRule = ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getSingleRule(AuthorityRule.class);
+ AuthorityRule rule = ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getSingleRule(AuthorityRule.class);
Grantee grantee = new Grantee(username, hostname);
- Optional<ShardingSphereUser> user = authorityRule.findUser(grantee);
- if (!user.isPresent() || !getAuthenticator(grantee).authenticate(user.get(), authenticationResponse)) {
+ Optional<ShardingSphereUser> user = rule.findUser(grantee);
+ if (!user.isPresent() || !getAuthenticator(rule, grantee).authenticate(user.get(), authenticationResponse)) {
return Optional.of(MySQLVendorError.ER_ACCESS_DENIED_ERROR);
}
- return null == databaseName || new AuthorityChecker(authorityRule, grantee).isAuthorized(databaseName) ? Optional.empty() : Optional.of(MySQLVendorError.ER_DBACCESS_DENIED_ERROR);
+ return null == databaseName || new AuthorityChecker(rule, grantee).isAuthorized(databaseName) ? Optional.empty() : Optional.of(MySQLVendorError.ER_DBACCESS_DENIED_ERROR);
}
/**
* Get authenticator.
*
+ * @param rule authority rule
* @param grantee grantee
* @return authenticator
*/
- public MySQLAuthenticator getAuthenticator(final Grantee grantee) {
+ public MySQLAuthenticator getAuthenticator(final AuthorityRule rule, final Grantee grantee) {
+ // TODO use authority rule and grantee to determine authentication method
return new MySQLNativePasswordAuthenticator(authPluginData);
}
}
diff --git a/proxy/frontend/mysql/src/test/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationEngineTest.java b/proxy/frontend/mysql/src/test/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationEngineTest.java
index 39a4e6de662..6099b4834c6 100644
--- a/proxy/frontend/mysql/src/test/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationEngineTest.java
+++ b/proxy/frontend/mysql/src/test/java/org/apache/shardingsphere/proxy/frontend/mysql/authentication/MySQLAuthenticationEngineTest.java
@@ -92,6 +92,7 @@ public final class MySQLAuthenticationEngineTest extends ProxyContextRestorer {
@SuppressWarnings("unchecked")
@Test
public void assertAuthenticationMethodMismatch() {
+ setMetaDataContexts();
setConnectionPhase(MySQLConnectionPhase.AUTH_PHASE_FAST_PATH);
MySQLPacketPayload payload = mock(MySQLPacketPayload.class);
ChannelHandlerContext channelHandlerContext = mock(ChannelHandlerContext.class);
@@ -104,7 +105,7 @@ public final class MySQLAuthenticationEngineTest extends ProxyContextRestorer {
when(payload.readInt1()).thenReturn(1);
when(payload.readInt4()).thenReturn(MySQLCapabilityFlag.CLIENT_PLUGIN_AUTH.getValue());
when(payload.readStringNul()).thenReturn("root");
- when(authenticationHandler.getAuthenticator(any())).thenReturn(new MySQLNativePasswordAuthenticator(mock(MySQLAuthPluginData.class)));
+ when(authenticationHandler.getAuthenticator(any(), any())).thenReturn(new MySQLNativePasswordAuthenticator(mock(MySQLAuthPluginData.class)));
authenticationEngine.authenticate(channelHandlerContext, payload);
assertThat(getConnectionPhase(), is(MySQLConnectionPhase.AUTHENTICATION_METHOD_MISMATCH));
}
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 bc2d121e4ae..8041a668779 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
@@ -121,7 +121,7 @@ public final class MySQLAuthenticationHandlerTest extends ProxyContextRestorer {
@Test
public void assertGetAuthenticator() {
- MySQLAuthenticator authenticator = authenticationHandler.getAuthenticator(new Grantee("root", ""));
+ MySQLAuthenticator authenticator = authenticationHandler.getAuthenticator(mock(AuthorityRule.class), new Grantee("root", ""));
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 af527b83d49..564b11ffacb 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
@@ -19,6 +19,7 @@ package org.apache.shardingsphere.proxy.frontend.postgresql.authentication;
import com.google.common.base.Strings;
import io.netty.channel.ChannelHandlerContext;
+import org.apache.shardingsphere.authority.rule.AuthorityRule;
import org.apache.shardingsphere.db.protocol.CommonConstants;
import org.apache.shardingsphere.db.protocol.payload.PacketPayload;
import org.apache.shardingsphere.db.protocol.postgresql.constant.PostgreSQLAuthenticationMethod;
@@ -38,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.proxy.backend.context.ProxyContext;
import org.apache.shardingsphere.proxy.backend.handler.admin.postgresql.PostgreSQLCharacterSets;
import org.apache.shardingsphere.proxy.frontend.authentication.AuthenticationEngine;
import org.apache.shardingsphere.proxy.frontend.authentication.AuthenticationResult;
@@ -112,7 +114,8 @@ public final class PostgreSQLAuthenticationEngine implements AuthenticationEngin
}
private PostgreSQLIdentifierPacket getIdentifierPacket(final String username) {
- PostgreSQLAuthenticator authenticator = authenticationHandler.getAuthenticator(new Grantee(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())) {
return new PostgreSQLPasswordAuthenticationPacket();
}
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 58b8bd52cbe..5591b96e6f5 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
@@ -49,23 +49,25 @@ public final class PostgreSQLAuthenticationHandler {
*/
public void login(final String username, final String databaseName, final byte[] md5Salt, final PostgreSQLPasswordMessagePacket passwordMessagePacket) {
ShardingSpherePreconditions.checkState(Strings.isNullOrEmpty(databaseName) || ProxyContext.getInstance().databaseExists(databaseName), () -> new UnknownDatabaseException(databaseName));
- AuthorityRule authorityRule = ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getSingleRule(AuthorityRule.class);
+ AuthorityRule rule = ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getSingleRule(AuthorityRule.class);
Grantee grantee = new Grantee(username, "%");
- Optional<ShardingSphereUser> user = authorityRule.findUser(grantee);
+ Optional<ShardingSphereUser> user = rule.findUser(grantee);
ShardingSpherePreconditions.checkState(user.isPresent(), () -> new UnknownUsernameException(username));
- ShardingSpherePreconditions.checkState(getAuthenticator(grantee).authenticate(user.get(), new Object[]{passwordMessagePacket.getDigest(), md5Salt}),
+ ShardingSpherePreconditions.checkState(getAuthenticator(rule, grantee).authenticate(user.get(), new Object[]{passwordMessagePacket.getDigest(), md5Salt}),
() -> new InvalidPasswordException(username));
- ShardingSpherePreconditions.checkState(null == databaseName || new AuthorityChecker(authorityRule, grantee).isAuthorized(databaseName),
+ ShardingSpherePreconditions.checkState(null == databaseName || new AuthorityChecker(rule, grantee).isAuthorized(databaseName),
() -> new PrivilegeNotGrantedException(username, databaseName));
}
/**
* Get authenticator.
*
+ * @param rule authority rule
* @param grantee username
* @return authenticator
*/
- public PostgreSQLAuthenticator getAuthenticator(final Grantee grantee) {
+ public PostgreSQLAuthenticator getAuthenticator(final AuthorityRule rule, final Grantee grantee) {
+ // TODO use authority rule and grantee to determine authentication method
return new PostgreSQLMD5PasswordAuthenticator();
}
}
diff --git a/proxy/frontend/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngineTest.java b/proxy/frontend/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngineTest.java
index 2f54ae9bdd5..4351fb62d9b 100644
--- a/proxy/frontend/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngineTest.java
+++ b/proxy/frontend/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngineTest.java
@@ -59,7 +59,6 @@ import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Properties;
-import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertFalse;
@@ -129,14 +128,9 @@ public final class PostgreSQLAuthenticationEngineTest extends ProxyContextRestor
assertLogin("wrong" + password);
}
- @Test
- public void assertGetIdentifierPacket() throws ReflectiveOperationException {
- assertThat(Plugins.getMemberAccessor().invoke(PostgreSQLAuthenticationEngine.class.getDeclaredMethod("getIdentifierPacket", String.class), new PostgreSQLAuthenticationEngine(), username),
- instanceOf(PostgreSQLMD5PasswordAuthenticationPacket.class));
- }
-
@SneakyThrows(ReflectiveOperationException.class)
private void assertLogin(final String inputPassword) {
+ mockInitProxyContext();
PostgreSQLPacketPayload payload = new PostgreSQLPacketPayload(createByteBuf(16, 128), StandardCharsets.UTF_8);
payload.writeInt4(64);
payload.writeInt4(196608);
@@ -166,6 +160,12 @@ public final class PostgreSQLAuthenticationEngineTest extends ProxyContextRestor
assertThat(actual.isFinished(), is(password.equals(inputPassword)));
}
+ private void mockInitProxyContext() {
+ ContextManager contextManager = mock(ContextManager.class, RETURNS_DEEP_STUBS);
+ when(contextManager.getMetaDataContexts().getMetaData().getGlobalRuleMetaData()).thenReturn(new ShardingSphereRuleMetaData(Collections.singleton(mock(AuthorityRule.class))));
+ ProxyContext.init(contextManager);
+ }
+
private ByteBuf createByteBuf(final int initialCapacity, final int maxCapacity) {
return new UnpooledHeapByteBuf(UnpooledByteBufAllocator.DEFAULT, initialCapacity, maxCapacity);
}
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 6835b026cf2..784b2f702de 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
@@ -112,7 +112,7 @@ public final class PostgreSQLAuthenticationHandlerTest extends ProxyContextResto
@Test
public void assertGetAuthenticator() {
- PostgreSQLAuthenticator authenticator = new PostgreSQLAuthenticationHandler().getAuthenticator(new Grantee(username, ""));
+ PostgreSQLAuthenticator authenticator = new PostgreSQLAuthenticationHandler().getAuthenticator(mock(AuthorityRule.class), new Grantee(username, ""));
assertThat(authenticator, instanceOf(PostgreSQLMD5PasswordAuthenticator.class));
assertThat(authenticator.getAuthenticationMethodName(), is(PostgreSQLAuthenticationMethod.MD5.getMethodName()));
}