Skip to content

Commit 6d038d6

Browse files
[client] Simply username and password config for client. (#1072)
1 parent 01417d7 commit 6d038d6

File tree

3 files changed

+60
-5
lines changed

3 files changed

+60
-5
lines changed

fluss-common/src/main/java/com/alibaba/fluss/config/ConfigOptions.java

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
import static com.alibaba.fluss.config.ConfigOptions.InfoLogLevel.INFO_LEVEL;
4141
import static com.alibaba.fluss.config.ConfigOptions.NoKeyAssigner.ROUND_ROBIN;
4242
import static com.alibaba.fluss.config.ConfigOptions.NoKeyAssigner.STICKY;
43-
import static com.alibaba.fluss.security.auth.sasl.jaas.JaasContext.SASL_JAAS_CONFIG;
4443

4544
/**
4645
* Config options for Fluss.
@@ -1096,17 +1095,35 @@ public class ConfigOptions {
10961095
public static final ConfigOption<String> CLIENT_MECHANISM =
10971096
key("client.security.sasl.mechanism")
10981097
.stringType()
1099-
.noDefaultValue()
1098+
.defaultValue("PLAIN")
11001099
.withDescription(
11011100
"SASL mechanism to use for authentication.Currently, we only support plain.");
11021101

11031102
public static final ConfigOption<String> CLIENT_SASL_JAAS_CONFIG =
1104-
key("client.security.sasl." + SASL_JAAS_CONFIG)
1103+
key("client.security.sasl.jaas.config")
11051104
.stringType()
11061105
.noDefaultValue()
11071106
.withDescription(
11081107
"JAAS configuration string for the client. If not provided, uses the JVM option -Djava.security.auth.login.config. \n"
1109-
+ "Example: com.alibaba.fluss.security.auth.sasl.plain.PlainLoginModule required username=\"admin\" password=\"admin-secret\")");
1108+
+ "Example: com.alibaba.fluss.security.auth.sasl.plain.PlainLoginModule required username=\"admin\" password=\"admin-secret\";");
1109+
1110+
public static final ConfigOption<String> CLIENT_SASL_JAAS_USERNAME =
1111+
key("client.security.sasl.username")
1112+
.stringType()
1113+
.noDefaultValue()
1114+
.withDescription(
1115+
"The password to use for client-side SASL JAAS authentication. "
1116+
+ "This is used when the client connects to the Fluss cluster with SASL authentication enabled. "
1117+
+ "If not provided, the username will be read from the JAAS configuration string specified by `client.security.sasl.jaas.config`.");
1118+
1119+
public static final ConfigOption<String> CLIENT_SASL_JAAS_PASSWORD =
1120+
key("client.security.sasl.password")
1121+
.stringType()
1122+
.noDefaultValue()
1123+
.withDescription(
1124+
"The username to use for client-side SASL JAAS authentication. "
1125+
+ "This is used when the client connects to the Fluss cluster with SASL authentication enabled. "
1126+
+ "If not provided, the password will be read from the JAAS configuration string specified by `client.security.sasl.jaas.config`.");
11101127

11111128
// ------------------------------------------------------------------------
11121129
// ConfigOptions for Fluss Table

fluss-common/src/main/java/com/alibaba/fluss/security/auth/sasl/authenticator/SaslClientAuthenticator.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.alibaba.fluss.security.auth.ClientAuthenticator;
2222
import com.alibaba.fluss.security.auth.sasl.jaas.JaasContext;
2323
import com.alibaba.fluss.security.auth.sasl.jaas.LoginManager;
24+
import com.alibaba.fluss.security.auth.sasl.plain.PlainSaslServer;
2425

2526
import javax.annotation.Nullable;
2627
import javax.security.auth.login.LoginException;
@@ -30,10 +31,14 @@
3031

3132
import static com.alibaba.fluss.config.ConfigOptions.CLIENT_MECHANISM;
3233
import static com.alibaba.fluss.config.ConfigOptions.CLIENT_SASL_JAAS_CONFIG;
34+
import static com.alibaba.fluss.config.ConfigOptions.CLIENT_SASL_JAAS_PASSWORD;
35+
import static com.alibaba.fluss.config.ConfigOptions.CLIENT_SASL_JAAS_USERNAME;
3336
import static com.alibaba.fluss.security.auth.sasl.jaas.SaslServerFactory.createSaslClient;
3437

3538
/** An authenticator that uses SASL to authenticate with a server. */
3639
public class SaslClientAuthenticator implements ClientAuthenticator {
40+
private static final String JAAS_CONF_FORMAT =
41+
"com.alibaba.fluss.security.auth.sasl.plain.PlainLoginModule required username=\"%s\" password=\"%s\";";
3742
private final String mechanism;
3843
private final Map<String, String> pros;
3944
private final String jaasConfig;
@@ -43,7 +48,22 @@ public class SaslClientAuthenticator implements ClientAuthenticator {
4348

4449
public SaslClientAuthenticator(Configuration configuration) {
4550
this.mechanism = configuration.get(CLIENT_MECHANISM).toUpperCase();
46-
this.jaasConfig = configuration.getString(CLIENT_SASL_JAAS_CONFIG);
51+
String jaasConfigStr = configuration.getString(CLIENT_SASL_JAAS_CONFIG);
52+
if (jaasConfigStr == null && mechanism.equals(PlainSaslServer.PLAIN_MECHANISM)) {
53+
String username = configuration.get(CLIENT_SASL_JAAS_USERNAME);
54+
String password = configuration.get(CLIENT_SASL_JAAS_PASSWORD);
55+
if (username != null || password != null) {
56+
if (username == null || password == null) {
57+
throw new AuthenticationException(
58+
String.format(
59+
"Configuration '%s' and '%s' must be set together for SASL JAAS authentication",
60+
CLIENT_SASL_JAAS_USERNAME.key(),
61+
CLIENT_SASL_JAAS_PASSWORD.key()));
62+
}
63+
jaasConfigStr = String.format(JAAS_CONF_FORMAT, username, password);
64+
}
65+
}
66+
this.jaasConfig = jaasConfigStr;
4767
this.pros = configuration.toMap();
4868
}
4969

fluss-rpc/src/test/java/com/alibaba/fluss/rpc/netty/authenticate/SaslAuthenticationITCase.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,24 @@ void testLoadJassConfigFallBackToJvmOptions() throws Exception {
161161
testAuthentication(clientConfig, serverConfig);
162162
}
163163

164+
@Test
165+
void testSimplifyUsernameAndPassword() throws Exception {
166+
Configuration clientConfig = new Configuration();
167+
clientConfig.setString("client.security.protocol", "sasl");
168+
clientConfig.setString("client.security.sasl.username", "alice");
169+
assertThatThrownBy(() -> testAuthentication(clientConfig))
170+
.isExactlyInstanceOf(AuthenticationException.class)
171+
.hasMessage(
172+
"Configuration 'client.security.sasl.username' and 'client.security.sasl.password' must be set together for SASL JAAS authentication");
173+
clientConfig.setString("client.security.sasl.password", "wrong-secret");
174+
assertThatThrownBy(() -> testAuthentication(clientConfig))
175+
.cause()
176+
.isExactlyInstanceOf(AuthenticationException.class)
177+
.hasMessage("Authentication failed: Invalid username or password");
178+
clientConfig.setString("client.security.sasl.password", "alice-secret");
179+
testAuthentication(clientConfig);
180+
}
181+
164182
private void testAuthentication(Configuration clientConfig) throws Exception {
165183
testAuthentication(clientConfig, getDefaultServerConfig());
166184
}

0 commit comments

Comments
 (0)