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 a008d1a6b..853852593 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 @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,8 @@ package org.springframework.data.mongodb.config; import java.beans.PropertyEditorSupport; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -136,7 +138,12 @@ public class MongoCredentialPropertyEditor extends PropertyEditorSupport { index = index != -1 ? index : text.lastIndexOf(OPTIONS_DELIMINATOR); - return index == -1 ? new String[] {} : text.substring(0, index).split(USERNAME_PASSWORD_DELIMINATOR); + if (index == -1) { + return new String[] {}; + } + + return Arrays.asList(text.substring(0, index).split(USERNAME_PASSWORD_DELIMINATOR)).stream() + .map(MongoCredentialPropertyEditor::decodeParameter).toArray(String[]::new); } private static String extractDB(String text) { @@ -195,4 +202,12 @@ public class MongoCredentialPropertyEditor extends PropertyEditorSupport { throw new IllegalArgumentException("Credentials need to specify username!"); } } + + private static String decodeParameter(String it) { + try { + return URLDecoder.decode(it, "UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new IllegalArgumentException("o_O UTF-8 not supported!", e); + } + } } 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 bcebbce44..fe8e4effc 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 @@ -19,6 +19,8 @@ import static org.hamcrest.collection.IsIterableContainingInOrder.*; import static org.hamcrest.core.IsNull.*; import static org.junit.Assert.*; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; import java.util.Arrays; import java.util.List; @@ -46,6 +48,12 @@ public class MongoCredentialPropertyEditorUnitTests { static final String USER_3_NAME = "CN=myName,OU=myOrgUnit,O=myOrg,L=myLocality,ST=myState,C=myCountry"; static final String USER_3_DB = "stark"; + static final String USER_4_PLAIN_NAME = "m0ng0@dmin"; + static final String USER_4_ENCODED_NAME; + static final String USER_4_PLAIN_PWD = "mo_res:bw6},Qsdxx@admin"; + static final String USER_4_ENCODED_PWD; + static final String USER_4_DB = "targaryen"; + static final String USER_1_AUTH_STRING = USER_1_NAME + ":" + USER_1_PWD + "@" + USER_1_DB; static final String USER_1_AUTH_STRING_WITH_PLAIN_AUTH_MECHANISM = USER_1_AUTH_STRING + "?uri.authMechanism=PLAIN"; @@ -56,6 +64,8 @@ public class MongoCredentialPropertyEditorUnitTests { static final String USER_3_AUTH_STRING_WITH_X509_AUTH_MECHANISM = "'" + USER_3_NAME + "@" + USER_3_DB + "?uri.authMechanism=MONGODB-X509'"; + static final String USER_4_AUTH_STRING; + 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, @@ -68,8 +78,26 @@ public class MongoCredentialPropertyEditorUnitTests { static final MongoCredential USER_3_CREDENTIALS_X509_AUTH = MongoCredential.createMongoX509Credential(USER_3_NAME); + static final MongoCredential USER_4_CREDENTIALS = MongoCredential.createCredential(USER_4_PLAIN_NAME, USER_4_DB, + USER_4_PLAIN_PWD.toCharArray()); + MongoCredentialPropertyEditor editor; + static { + + String encodedUserName = null; + String encodedUserPassword = null; + try { + encodedUserName = URLEncoder.encode(USER_4_PLAIN_NAME, "UTF-8"); + encodedUserPassword = URLEncoder.encode(USER_4_PLAIN_PWD, "UTF-8"); + } catch (UnsupportedEncodingException e) {} + + USER_4_ENCODED_NAME = encodedUserName; + USER_4_ENCODED_PWD = encodedUserPassword; + USER_4_AUTH_STRING = USER_4_ENCODED_NAME + ":" + USER_4_ENCODED_PWD + "@" + USER_4_DB; + + } + @Before public void setUp() { this.editor = new MongoCredentialPropertyEditor(); @@ -202,4 +230,15 @@ public class MongoCredentialPropertyEditorUnitTests { editor.getValue(); } + + @Test // DATAMONGO-1317 + @SuppressWarnings("unchecked") + public void encodedUserNameAndPasswrodShouldBeDecoded() throws UnsupportedEncodingException { + + editor.setAsText(USER_4_AUTH_STRING); + + System.out.println("USER_4_AUTH_STRING: " + USER_4_AUTH_STRING); + + assertThat((List) editor.getValue(), contains(USER_4_CREDENTIALS)); + } } diff --git a/src/main/asciidoc/reference/mongodb.adoc b/src/main/asciidoc/reference/mongodb.adoc index 32d10acf4..95ad516ce 100644 --- a/src/main/asciidoc/reference/mongodb.adoc +++ b/src/main/asciidoc/reference/mongodb.adoc @@ -362,6 +362,9 @@ public class ApplicationContextEventTestsAppConfig extends AbstractMongoConfigur In order to use authentication with XML configuration use the `credentials` attribue on ``. +NOTE: When using XML configuration along with username/password containing reserved characters `:`, `@`, `,` need to be URL encoded. +Example: `m0ng0@dmin:mo_res:bw6},Qsdxx@admin@database` -> `m0ng0%40dmin:mo_res%3Abw6%7D%2CQsdxx%40admin@database` + [[mongo.mongo-db-factory-xml]] === Registering a MongoDbFactory instance using XML based metadata