diff --git a/pom.xml b/pom.xml
index 5f260f6..ca4a7e4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -512,15 +512,14 @@
reactor-core
true
-
-
org.springframework.security
spring-security-core
- test
+
+
org.springframework
spring-web
diff --git a/src/main/java/org/springframework/session/data/mongo/AbstractMongoSessionConverter.java b/src/main/java/org/springframework/session/data/mongo/AbstractMongoSessionConverter.java
index 276b287..45767fb 100644
--- a/src/main/java/org/springframework/session/data/mongo/AbstractMongoSessionConverter.java
+++ b/src/main/java/org/springframework/session/data/mongo/AbstractMongoSessionConverter.java
@@ -22,7 +22,6 @@ import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.bson.Document;
-
import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.convert.converter.GenericConverter;
import org.springframework.data.domain.Sort;
diff --git a/src/main/java/org/springframework/session/data/mongo/JacksonMongoSessionConverter.java b/src/main/java/org/springframework/session/data/mongo/JacksonMongoSessionConverter.java
index 30cd329..6aa2c7a 100644
--- a/src/main/java/org/springframework/session/data/mongo/JacksonMongoSessionConverter.java
+++ b/src/main/java/org/springframework/session/data/mongo/JacksonMongoSessionConverter.java
@@ -17,13 +17,16 @@ package org.springframework.session.data.mongo;
import java.io.IOException;
import java.util.Collections;
+import java.util.HashMap;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.bson.Document;
-
+import org.bson.json.JsonMode;
+import org.bson.json.JsonWriterSettings;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.security.jackson2.SecurityJackson2Modules;
import org.springframework.session.FindByIndexNameSessionRepository;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
@@ -85,9 +88,27 @@ public class JacksonMongoSessionConverter extends AbstractMongoSessionConverter
objectMapper.setPropertyNamingStrategy(new MongoIdNamingStrategy());
+ objectMapper.registerModules(SecurityJackson2Modules.getModules(getClass().getClassLoader()));
+ objectMapper.addMixIn(MongoSession.class, MongoSessionMixin.class);
+ objectMapper.addMixIn(HashMap.class, HashMapMixin.class);
+
return objectMapper;
}
+ /**
+ * Used to whitelist {@link MongoSession} for {@link SecurityJackson2Modules}.
+ */
+ private static class MongoSessionMixin {
+ // Nothing special
+ }
+
+ /**
+ * Used to whitelist {@link HashMap} for {@link SecurityJackson2Modules}.
+ */
+ private static class HashMapMixin {
+ // Nothing special
+ }
+
@Override
protected DBObject convert(MongoSession source) {
@@ -103,8 +124,8 @@ public class JacksonMongoSessionConverter extends AbstractMongoSessionConverter
@Override
protected MongoSession convert(Document source) {
- String json = JSON.serialize(source);
-
+ String json = source.toJson(JsonWriterSettings.builder().outputMode(JsonMode.RELAXED).build());
+
try {
return this.objectMapper.readValue(json, MongoSession.class);
} catch (IOException e) {
diff --git a/src/test/java/org/springframework/session/data/mongo/AbstractMongoSessionConverterTest.java b/src/test/java/org/springframework/session/data/mongo/AbstractMongoSessionConverterTest.java
new file mode 100644
index 0000000..c641612
--- /dev/null
+++ b/src/test/java/org/springframework/session/data/mongo/AbstractMongoSessionConverterTest.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.session.data.mongo;
+
+import static org.assertj.core.api.Assertions.*;
+
+import java.time.Duration;
+
+import org.bson.Document;
+import org.junit.Test;
+import org.springframework.core.convert.TypeDescriptor;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.context.SecurityContextImpl;
+import org.springframework.session.FindByIndexNameSessionRepository;
+
+import com.mongodb.DBObject;
+
+/**
+ * @author Greg Turnquist
+ */
+public abstract class AbstractMongoSessionConverterTest {
+
+ abstract AbstractMongoSessionConverter getMongoSessionConverter();
+
+ @Test
+ public void verifyRoundTripSerialization() throws Exception {
+
+ // given
+ MongoSession toSerialize = new MongoSession();
+ toSerialize.setAttribute("username", "john_the_springer");
+
+ // when
+ DBObject dbObject = convertToDBObject(toSerialize);
+ MongoSession deserialized = convertToSession(dbObject);
+
+ // then
+ assertThat(deserialized).isEqualToComparingFieldByField(toSerialize);
+ }
+
+ @Test
+ public void verifyRoundTripSecuritySerialization() {
+
+ // given
+ MongoSession toSerialize = new MongoSession();
+ String principalName = "john_the_springer";
+ SecurityContextImpl context = new SecurityContextImpl();
+ context.setAuthentication(
+ new UsernamePasswordAuthenticationToken(principalName, null));
+ toSerialize.setAttribute("SPRING_SECURITY_CONTEXT", context);
+
+ // when
+ DBObject serialized = convertToDBObject(toSerialize);
+ MongoSession deserialized = convertToSession(serialized);
+
+ // then
+ assertThat(deserialized).isEqualToComparingOnlyGivenFields(toSerialize,
+ "id", "createdMillis", "accessedMillis", "intervalSeconds", "expireAt");
+
+ SecurityContextImpl springSecurityContextBefore = toSerialize.getAttribute("SPRING_SECURITY_CONTEXT");
+ SecurityContextImpl springSecurityContextAfter = deserialized.getAttribute("SPRING_SECURITY_CONTEXT");
+
+ assertThat(springSecurityContextBefore).isEqualToComparingOnlyGivenFields(springSecurityContextAfter,
+ "authentication.principal", "authentication.authorities", "authentication.authenticated");
+ assertThat(springSecurityContextAfter.getAuthentication().getPrincipal()).isEqualTo("john_the_springer");
+ assertThat(springSecurityContextAfter.getAuthentication().getCredentials()).isNull();
+ }
+
+ @Test
+ public void shouldExtractPrincipalNameFromAttributes() throws Exception {
+
+ // given
+ MongoSession toSerialize = new MongoSession();
+ String principalName = "john_the_springer";
+ toSerialize.setAttribute(
+ FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME,
+ principalName);
+
+ // when
+ DBObject dbObject = convertToDBObject(toSerialize);
+
+ // then
+ assertThat(dbObject.get("principal")).isEqualTo(principalName);
+ }
+
+ @Test
+ public void shouldExtractPrincipalNameFromAuthentication() throws Exception {
+
+ // given
+ MongoSession toSerialize = new MongoSession();
+ String principalName = "john_the_springer";
+ SecurityContextImpl context = new SecurityContextImpl();
+ context.setAuthentication(
+ new UsernamePasswordAuthenticationToken(principalName, null));
+ toSerialize.setAttribute("SPRING_SECURITY_CONTEXT", context);
+
+ // when
+ DBObject dbObject = convertToDBObject(toSerialize);
+
+ // then
+ assertThat(dbObject.get("principal")).isEqualTo(principalName);
+ }
+
+ @Test
+ public void sessionWrapperWithNoMaxIntervalShouldFallbackToDefaultValues() {
+
+ // given
+ MongoSession toSerialize = new MongoSession();
+ DBObject dbObject = convertToDBObject(toSerialize);
+ Document document = new Document(dbObject.toMap());
+ document.remove("interval");
+
+ // when
+ MongoSession convertedSession = getMongoSessionConverter().convert(document);
+
+ // then
+ assertThat(convertedSession.getMaxInactiveInterval()).isEqualTo(Duration.ofMinutes(30));
+ }
+
+ MongoSession convertToSession(DBObject session) {
+ return (MongoSession) getMongoSessionConverter().convert(session,
+ TypeDescriptor.valueOf(DBObject.class),
+ TypeDescriptor.valueOf(MongoSession.class));
+ }
+
+ DBObject convertToDBObject(MongoSession session) {
+ return (DBObject) getMongoSessionConverter().convert(session,
+ TypeDescriptor.valueOf(MongoSession.class),
+ TypeDescriptor.valueOf(DBObject.class));
+ }
+
+
+}
diff --git a/src/test/java/org/springframework/session/data/mongo/JacksonMongoSessionConverterTest.java b/src/test/java/org/springframework/session/data/mongo/JacksonMongoSessionConverterTest.java
index 6921433..63e9c53 100644
--- a/src/test/java/org/springframework/session/data/mongo/JacksonMongoSessionConverterTest.java
+++ b/src/test/java/org/springframework/session/data/mongo/JacksonMongoSessionConverterTest.java
@@ -18,7 +18,6 @@ package org.springframework.session.data.mongo;
import static org.assertj.core.api.Assertions.*;
import org.junit.Test;
-
import org.springframework.data.mongodb.core.query.Query;
import com.mongodb.DBObject;
@@ -27,9 +26,14 @@ import com.mongodb.DBObject;
* @author Jakub Kubrynski
* @author Greg Turnquist
*/
-public class JacksonMongoSessionConverterTest {
+public class JacksonMongoSessionConverterTest extends AbstractMongoSessionConverterTest {
- JacksonMongoSessionConverter sut = new JacksonMongoSessionConverter();
+ JacksonMongoSessionConverter mongoSessionConverter = new JacksonMongoSessionConverter();
+
+ @Override
+ AbstractMongoSessionConverter getMongoSessionConverter() {
+ return this.mongoSessionConverter;
+ }
@Test
public void shouldSaveIdField() throws Exception {
@@ -38,7 +42,7 @@ public class JacksonMongoSessionConverterTest {
MongoSession session = new MongoSession();
//when
- DBObject convert = this.sut.convert(session);
+ DBObject convert = this.mongoSessionConverter.convert(session);
//then
assertThat(convert.get("_id")).isEqualTo(session.getId());
@@ -49,9 +53,11 @@ public class JacksonMongoSessionConverterTest {
public void shouldQueryAgainstAttribute() throws Exception {
//when
- Query cart = this.sut.getQueryForIndex("cart", "my-cart");
+ Query cart = this.mongoSessionConverter.getQueryForIndex("cart", "my-cart");
//then
assertThat(cart.getQueryObject().get("attrs.cart")).isEqualTo("my-cart");
}
+
+
}
diff --git a/src/test/java/org/springframework/session/data/mongo/JdkMongoSessionConverterTest.java b/src/test/java/org/springframework/session/data/mongo/JdkMongoSessionConverterTest.java
index 54b0fde..f03e519 100644
--- a/src/test/java/org/springframework/session/data/mongo/JdkMongoSessionConverterTest.java
+++ b/src/test/java/org/springframework/session/data/mongo/JdkMongoSessionConverterTest.java
@@ -15,31 +15,27 @@
*/
package org.springframework.session.data.mongo;
-import static org.assertj.core.api.Assertions.*;
-
import java.time.Duration;
-import org.bson.Document;
import org.junit.Test;
-import org.springframework.core.convert.TypeDescriptor;
import org.springframework.core.serializer.support.DeserializingConverter;
import org.springframework.core.serializer.support.SerializingConverter;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.context.SecurityContextImpl;
-import org.springframework.session.FindByIndexNameSessionRepository;
-
-import com.mongodb.DBObject;
/**
* @author Jakub Kubrynski
* @author Rob Winch
* @author Greg Turnquist
*/
-public class JdkMongoSessionConverterTest {
+public class JdkMongoSessionConverterTest extends AbstractMongoSessionConverterTest {
Duration inactiveInterval = Duration.ofMinutes(30);
JdkMongoSessionConverter mongoSessionConverter = new JdkMongoSessionConverter(inactiveInterval);
+ @Override
+ AbstractMongoSessionConverter getMongoSessionConverter() {
+ return this.mongoSessionConverter;
+ }
+
@Test(expected = IllegalArgumentException.class)
public void constructorNullSerializer() {
new JdkMongoSessionConverter(null, new DeserializingConverter(), inactiveInterval);
@@ -49,82 +45,4 @@ public class JdkMongoSessionConverterTest {
public void constructorNullDeserializer() {
new JdkMongoSessionConverter(new SerializingConverter(), null, inactiveInterval);
}
-
- @Test
- public void verifyRoundTripSerialization() throws Exception {
-
- // given
- MongoSession toSerialize = new MongoSession();
- toSerialize.setAttribute("username", "john_the_springer");
-
- // when
- DBObject dbObject = convertToDBObject(toSerialize);
- MongoSession deserialized = convertToSession(dbObject);
-
- // then
- assertThat(deserialized).isEqualToComparingFieldByField(toSerialize);
- }
-
- @Test
- public void shouldExtractPrincipalNameFromAttributes() throws Exception {
-
- // given
- MongoSession toSerialize = new MongoSession();
- String principalName = "john_the_springer";
- toSerialize.setAttribute(
- FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME,
- principalName);
-
- // when
- DBObject dbObject = convertToDBObject(toSerialize);
-
- // then
- assertThat(dbObject.get("principal")).isEqualTo(principalName);
- }
-
- @Test
- public void shouldExtractPrincipalNameFromAuthentication() throws Exception {
-
- // given
- MongoSession toSerialize = new MongoSession();
- String principalName = "john_the_springer";
- SecurityContextImpl context = new SecurityContextImpl();
- context.setAuthentication(
- new UsernamePasswordAuthenticationToken(principalName, null));
- toSerialize.setAttribute("SPRING_SECURITY_CONTEXT", context);
-
- // when
- DBObject dbObject = convertToDBObject(toSerialize);
-
- // then
- assertThat(dbObject.get("principal")).isEqualTo(principalName);
- }
-
- @Test
- public void sessionWrapperWithNoMaxIntervalShouldFallbackToDefaultValues() {
-
- // given
- MongoSession toSerialize = new MongoSession();
- DBObject dbObject = convertToDBObject(toSerialize);
- Document document = new Document(dbObject.toMap());
- document.remove("interval");
-
- // when
- MongoSession convertedSession = this.mongoSessionConverter.convert(document);
-
- // then
- assertThat(convertedSession.getMaxInactiveInterval()).isEqualTo(Duration.ofMinutes(30));
- }
-
- MongoSession convertToSession(DBObject session) {
- return (MongoSession) this.mongoSessionConverter.convert(session,
- TypeDescriptor.valueOf(DBObject.class),
- TypeDescriptor.valueOf(MongoSession.class));
- }
-
- DBObject convertToDBObject(MongoSession session) {
- return (DBObject) this.mongoSessionConverter.convert(session,
- TypeDescriptor.valueOf(MongoSession.class),
- TypeDescriptor.valueOf(DBObject.class));
- }
}