From 7100cd17be070855a7fbd6f21c848fdd696e4aed Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Mon, 13 Aug 2018 09:29:21 +0200 Subject: [PATCH] DATAMONGO-2051 - Add support for SCRAM-SHA-256 authentication mechanism to MongoCredentialPropertyEditor. Original pull request: #597. Related pull request: #598. --- .../config/MongoCredentialPropertyEditor.java | 16 ++++++++++++++++ .../data/mongodb/util/MongoClientVersion.java | 13 ++++++++++++- .../MongoCredentialPropertyEditorUnitTests.java | 17 ++++++++++++++++- 3 files changed, 44 insertions(+), 2 deletions(-) diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoCredentialPropertyEditor.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoCredentialPropertyEditor.java index ee742e21a..ce2147c25 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoCredentialPropertyEditor.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoCredentialPropertyEditor.java @@ -17,6 +17,7 @@ package org.springframework.data.mongodb.config; import java.beans.PropertyEditorSupport; import java.io.UnsupportedEncodingException; +import java.lang.reflect.Method; import java.net.URLDecoder; import java.util.ArrayList; import java.util.Arrays; @@ -26,6 +27,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import org.springframework.lang.Nullable; +import org.springframework.util.ReflectionUtils; import org.springframework.util.StringUtils; import com.mongodb.MongoCredential; @@ -100,6 +102,20 @@ public class MongoCredentialPropertyEditor extends PropertyEditorSupport { verifyDatabasePresent(database); credentials.add(MongoCredential.createScramSha1Credential(userNameAndPassword[0], database, userNameAndPassword[1].toCharArray())); + } else if ("SCRAM-SHA-256".equals(authMechanism)) { + + Method createScramSha256Credential = ReflectionUtils.findMethod(MongoCredential.class, + "createScramSha256Credential"); + + if (createScramSha256Credential == null) { + throw new IllegalArgumentException( + "SCRAM-SHA-256 auth mechanism is available as of MongoDB 4 and MongoDB Java Driver 3.8! Please make sure to use at least those versions."); + } + + verifyUsernameAndPasswordPresent(userNameAndPassword); + verifyDatabasePresent(database); + credentials.add(MongoCredential.class.cast(ReflectionUtils.invokeMethod(createScramSha256Credential, null, + userNameAndPassword[0], database, userNameAndPassword[1].toCharArray()))); } else { throw new IllegalArgumentException( String.format("Cannot create MongoCredentials for unknown auth mechanism '%s'!", authMechanism)); diff --git a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoClientVersion.java b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoClientVersion.java index 272f885a7..a640d1e94 100644 --- a/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoClientVersion.java +++ b/spring-data-mongodb/src/main/java/org/springframework/data/mongodb/util/MongoClientVersion.java @@ -32,6 +32,9 @@ public class MongoClientVersion { private static final boolean IS_MONGO_34 = ClassUtils.isPresent("org.bson.types.Decimal128", MongoClientVersion.class.getClassLoader()); + private static final boolean IS_MONGO_38 = ClassUtils.isPresent("com.mongodb.TransactionOptions", + MongoClientVersion.class.getClassLoader()); + private static final boolean IS_ASYNC_CLIENT = ClassUtils.isPresent("com.mongodb.async.client.MongoClient", MongoClientVersion.class.getClassLoader()); @@ -51,9 +54,17 @@ public class MongoClientVersion { } /** - * @return {lliteral true} if MongoDB Java driver is on classpath. + * @return {@literal true} if MongoDB Java driver is on classpath. */ public static boolean isAsyncClient() { return IS_ASYNC_CLIENT; } + + /** + * @return {@literal true} if MongoDB Java driver version 3.8 or later is on classpath. + * @since 2.10 + */ + public static boolean isMongo38Driver() { + return IS_MONGO_38; + } } diff --git a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MongoCredentialPropertyEditorUnitTests.java b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MongoCredentialPropertyEditorUnitTests.java index a2a19da66..ef7d602e6 100644 --- a/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MongoCredentialPropertyEditorUnitTests.java +++ b/spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/MongoCredentialPropertyEditorUnitTests.java @@ -16,6 +16,7 @@ package org.springframework.data.mongodb.config; import static org.assertj.core.api.Assertions.*; +import static org.assertj.core.api.Assumptions.*; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; @@ -24,6 +25,7 @@ import java.util.List; import org.junit.Before; import org.junit.Test; +import org.springframework.data.mongodb.util.MongoClientVersion; import org.springframework.util.StringUtils; import com.mongodb.MongoCredential; @@ -73,6 +75,9 @@ public class MongoCredentialPropertyEditorUnitTests { static final String USER_5_AUTH_STRING_WITH_PLAIN_AUTH_MECHANISM = USER_5_AUTH_STRING + "?uri.authMechanism=PLAIN"; static final String USER_5_AUTH_STRING_WITH_QUERY_ARGS = USER_5_AUTH_STRING + "?uri.authMechanism=PLAIN&foo=&bar"; + static final String SCRAM_SHA_256_AUTH_STRING = USER_1_NAME + ":" + USER_1_PWD + "@" + USER_1_DB + + "?uri.authMechanism=SCRAM-SHA-256"; + static final MongoCredential USER_1_CREDENTIALS = MongoCredential.createCredential(USER_1_NAME, USER_1_DB, USER_1_PWD.toCharArray()); static final MongoCredential USER_1_CREDENTIALS_PLAIN_AUTH = MongoCredential.createPlainCredential(USER_1_NAME, @@ -223,7 +228,7 @@ public class MongoCredentialPropertyEditorUnitTests { editor.setAsText("tyrion?uri.authMechanism=MONGODB-X509"); - assertThat(getValue()). contains(MongoCredential.createMongoX509Credential("tyrion")); + assertThat(getValue()).contains(MongoCredential.createMongoX509Credential("tyrion")); } @Test(expected = IllegalArgumentException.class) // DATAMONGO-1257 @@ -269,6 +274,16 @@ public class MongoCredentialPropertyEditorUnitTests { assertThat(getValue()).contains(USER_5_CREDENTIALS_PLAIN_AUTH); } + @Test // DATAMONGO-2051 + public void shouldReturnScramSha256Credentials() { + + assumeThat(MongoClientVersion.isMongo38Driver()).isTrue(); + + editor.setAsText(SCRAM_SHA_256_AUTH_STRING); + + assertThat(getValue()).isNotEmpty(); + } + @Test(expected = IllegalArgumentException.class) // DATAMONGO-2016 @SuppressWarnings("unchecked") public void failsGracefullyOnEmptyQueryArgument() {