Skip to content

Commit 32ae1e5

Browse files
committed
Add support for CredentialsProvider in Mongo connections
Closes: #20277
1 parent b701076 commit 32ae1e5

File tree

2 files changed

+66
-3
lines changed

2 files changed

+66
-3
lines changed

extensions/mongodb-client/runtime/src/main/java/io/quarkus/mongodb/runtime/CredentialConfig.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
import io.quarkus.runtime.annotations.ConfigGroup;
77
import io.quarkus.runtime.annotations.ConfigItem;
8+
import io.quarkus.runtime.annotations.ConvertWith;
9+
import io.quarkus.runtime.configuration.TrimmedStringConverter;
810

911
/**
1012
* Configures the credentials and authentication mechanism to connect to the MongoDB server.
@@ -48,4 +50,23 @@ public class CredentialConfig {
4850
*/
4951
@ConfigItem
5052
public Map<String, String> authMechanismProperties;
53+
54+
/**
55+
* The credentials provider name
56+
*/
57+
@ConfigItem
58+
@ConvertWith(TrimmedStringConverter.class)
59+
public Optional<String> credentialsProvider = Optional.empty();
60+
61+
/**
62+
* The credentials provider bean name.
63+
* <p>
64+
* It is the {@code &#64;Named} value of the credentials provider bean. It is used to discriminate if multiple
65+
* CredentialsProvider beans are available.
66+
* <p>
67+
* For Vault it is: vault-credentials-provider. Not necessary if there is only one credentials provider available.
68+
*/
69+
@ConfigItem
70+
@ConvertWith(TrimmedStringConverter.class)
71+
public Optional<String> credentialsProviderName = Optional.empty();
5172
}

extensions/mongodb-client/runtime/src/main/java/io/quarkus/mongodb/runtime/MongoClients.java

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import static com.mongodb.AuthenticationMechanism.PLAIN;
77
import static com.mongodb.AuthenticationMechanism.SCRAM_SHA_1;
88
import static com.mongodb.AuthenticationMechanism.SCRAM_SHA_256;
9+
import static io.quarkus.credentials.CredentialsProvider.PASSWORD_PROPERTY_NAME;
10+
import static io.quarkus.credentials.CredentialsProvider.USER_PROPERTY_NAME;
911
import static org.bson.codecs.configuration.CodecRegistries.fromProviders;
1012
import static org.bson.codecs.configuration.CodecRegistries.fromRegistries;
1113

@@ -56,6 +58,8 @@
5658

5759
import io.quarkus.arc.Arc;
5860
import io.quarkus.arc.InstanceHandle;
61+
import io.quarkus.credentials.CredentialsProvider;
62+
import io.quarkus.credentials.runtime.CredentialsProviderFinder;
5963
import io.quarkus.mongodb.health.MongoHealthCheck;
6064
import io.quarkus.mongodb.impl.ReactiveMongoClientImpl;
6165
import io.quarkus.mongodb.reactive.ReactiveMongoClient;
@@ -381,12 +385,11 @@ public ServerAddress apply(String address) {
381385
}
382386

383387
private MongoCredential createMongoCredential(MongoClientConfig config) {
384-
String username = config.credentials.username.orElse(null);
385-
if (username == null) {
388+
UsernamePassword usernamePassword = determineUserNamePassword(config.credentials);
389+
if (usernamePassword == null) {
386390
return null;
387391
}
388392

389-
char[] password = config.credentials.password.map(String::toCharArray).orElse(null);
390393
// get the authsource, or the database from the config, or 'admin' as it is the default auth source in mongo
391394
// and null is not allowed
392395
String authSource = config.credentials.authSource.orElse(config.database.orElse("admin"));
@@ -398,6 +401,8 @@ private MongoCredential createMongoCredential(MongoClientConfig config) {
398401
}
399402

400403
// Create the MongoCredential instance.
404+
String username = usernamePassword.getUsername();
405+
char[] password = usernamePassword.getPassword();
401406
MongoCredential credential;
402407
if (mechanism == GSSAPI) {
403408
credential = MongoCredential.createGSSAPICredential(username);
@@ -427,6 +432,25 @@ private MongoCredential createMongoCredential(MongoClientConfig config) {
427432
return credential;
428433
}
429434

435+
private UsernamePassword determineUserNamePassword(CredentialConfig config) {
436+
if (config.credentialsProvider.isPresent()) {
437+
String beanName = config.credentialsProviderName.orElse(null);
438+
CredentialsProvider credentialsProvider = CredentialsProviderFinder.find(beanName);
439+
String name = config.credentialsProvider.get();
440+
Map<String, String> credentials = credentialsProvider.getCredentials(name);
441+
String user = credentials.get(USER_PROPERTY_NAME);
442+
String password = credentials.get(PASSWORD_PROPERTY_NAME);
443+
return new UsernamePassword(user, password.toCharArray());
444+
} else {
445+
String username = config.username.orElse(null);
446+
if (username == null) {
447+
return null;
448+
}
449+
char[] password = config.password.map(String::toCharArray).orElse(null);
450+
return new UsernamePassword(username, password);
451+
}
452+
}
453+
430454
private AuthenticationMechanism getAuthenticationMechanism(String authMechanism) {
431455
AuthenticationMechanism mechanism;
432456
try {
@@ -450,4 +474,22 @@ public void stop() {
450474
}
451475
}
452476
}
477+
478+
private static class UsernamePassword {
479+
private final String username;
480+
private final char[] password;
481+
482+
public UsernamePassword(String username, char[] password) {
483+
this.username = username;
484+
this.password = password;
485+
}
486+
487+
public String getUsername() {
488+
return username;
489+
}
490+
491+
public char[] getPassword() {
492+
return password;
493+
}
494+
}
453495
}

0 commit comments

Comments
 (0)