DATAMONGO-1713 - Allow using URL encoded username/password for <mongo-client credentials=… />.

We now URL decode username & password before creating MongoCredentials. This allows usage of reserved characters in the credentials string.

Original pull request: #477.
This commit is contained in:
Christoph Strobl
2017-07-05 13:23:03 +02:00
committed by Mark Paluch
parent b9282c8d32
commit 1aa2ee5f54
3 changed files with 59 additions and 2 deletions

View File

@@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -16,6 +16,8 @@
package org.springframework.data.mongodb.config; package org.springframework.data.mongodb.config;
import java.beans.PropertyEditorSupport; import java.beans.PropertyEditorSupport;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@@ -136,7 +138,12 @@ public class MongoCredentialPropertyEditor extends PropertyEditorSupport {
index = index != -1 ? index : text.lastIndexOf(OPTIONS_DELIMINATOR); 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) { private static String extractDB(String text) {
@@ -195,4 +202,12 @@ public class MongoCredentialPropertyEditor extends PropertyEditorSupport {
throw new IllegalArgumentException("Credentials need to specify username!"); 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);
}
}
} }

View File

@@ -19,6 +19,8 @@ import static org.hamcrest.collection.IsIterableContainingInOrder.*;
import static org.hamcrest.core.IsNull.*; import static org.hamcrest.core.IsNull.*;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; 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_NAME = "CN=myName,OU=myOrgUnit,O=myOrg,L=myLocality,ST=myState,C=myCountry";
static final String USER_3_DB = "stark"; 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 = 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"; 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 static final String USER_3_AUTH_STRING_WITH_X509_AUTH_MECHANISM = "'" + USER_3_NAME + "@" + USER_3_DB
+ "?uri.authMechanism=MONGODB-X509'"; + "?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, static final MongoCredential USER_1_CREDENTIALS = MongoCredential.createCredential(USER_1_NAME, USER_1_DB,
USER_1_PWD.toCharArray()); USER_1_PWD.toCharArray());
static final MongoCredential USER_1_CREDENTIALS_PLAIN_AUTH = MongoCredential.createPlainCredential(USER_1_NAME, 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_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; 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 @Before
public void setUp() { public void setUp() {
this.editor = new MongoCredentialPropertyEditor(); this.editor = new MongoCredentialPropertyEditor();
@@ -202,4 +230,15 @@ public class MongoCredentialPropertyEditorUnitTests {
editor.getValue(); 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<MongoCredential>) editor.getValue(), contains(USER_4_CREDENTIALS));
}
} }

View File

@@ -362,6 +362,9 @@ public class ApplicationContextEventTestsAppConfig extends AbstractMongoConfigur
In order to use authentication with XML configuration use the `credentials` attribue on `<mongo-client>`. In order to use authentication with XML configuration use the `credentials` attribue on `<mongo-client>`.
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]] [[mongo.mongo-db-factory-xml]]
=== Registering a MongoDbFactory instance using XML based metadata === Registering a MongoDbFactory instance using XML based metadata