Make Jackson operational.
Resolves https://github.com/spring-projects/spring-session/issues/913
This commit is contained in:
5
pom.xml
5
pom.xml
@@ -512,15 +512,14 @@
|
||||
<artifactId>reactor-core</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<!-- Test dependencies -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-core</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Test dependencies -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-web</artifactId>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user