Browse Source

Add collection variable to @Encrypted SpEL context.

Supply the collection name as a #collection variable in the SpEL
evaluation context for @Encrypted keyId expressions. This allows
using different encryption keys per collection.

The #collection variable is now available in both entity-level and
property-level @Encrypted annotations.

Closes #4304

Signed-off-by: seonghyeoklee <dltjdgur327@gmail.com>
pull/5173/head
seonghyeoklee 2 weeks ago
parent
commit
a83ae2f92d
  1. 1
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentEntity.java
  2. 3
      spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentProperty.java
  3. 65
      spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MappingMongoJsonSchemaCreatorUnitTests.java

1
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentEntity.java

@ -382,6 +382,7 @@ public class BasicMongoPersistentEntity<T> extends BasicPersistentEntity<T, Mong @@ -382,6 +382,7 @@ public class BasicMongoPersistentEntity<T> extends BasicPersistentEntity<T, Mong
EvaluationContext ctx = getEvaluationContext(null);
ctx.setVariable("target", getType().getSimpleName());
ctx.setVariable("collection", getCollection());
return ctx;
});

3
spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/mapping/BasicMongoPersistentProperty.java

@ -270,6 +270,9 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope @@ -270,6 +270,9 @@ public class BasicMongoPersistentProperty extends AnnotationBasedPersistentPrope
Lazy<EvaluationContext> evaluationContext = Lazy.of(() -> {
EvaluationContext ctx = getEvaluationContext(null);
ctx.setVariable("target", getOwner().getType().getSimpleName() + "." + getName());
if (getOwner() instanceof MongoPersistentEntity<?> mongoPersistentEntity) {
ctx.setVariable("collection", mongoPersistentEntity.getCollection());
}
return ctx;
});

65
spring-data-mongodb/src/test/java/org/springframework/data/mongodb/core/MappingMongoJsonSchemaCreatorUnitTests.java

@ -164,6 +164,24 @@ class MappingMongoJsonSchemaCreatorUnitTests { @@ -164,6 +164,24 @@ class MappingMongoJsonSchemaCreatorUnitTests {
assertThat(schema.schemaDocument().toBsonDocument()).isEqualTo(BsonDocument.parse(ENC_FROM_METHOD_SCHEMA));
}
@Test // GH-4304
void csfleWithKeyFromCollection() {
GenericApplicationContext applicationContext = new GenericApplicationContext();
applicationContext.registerBean("encryptionExtension", EncryptionExtension.class, () -> new EncryptionExtension());
applicationContext.refresh();
MongoMappingContext mappingContext = new MongoMappingContext();
mappingContext.setApplicationContext(applicationContext);
mappingContext.afterPropertiesSet();
MongoJsonSchema schema = MongoJsonSchemaCreator.create(mappingContext) //
.filter(MongoJsonSchemaCreator.encryptedOnly()) //
.createSchemaFor(EncryptionMetadataWithCollection.class);
assertThat(schema.schemaDocument().toBsonDocument()).isEqualTo(BsonDocument.parse(ENC_FROM_COLLECTION_SCHEMA));
}
// --> Combining Schemas and Properties
@Test // GH-3870
@ -648,6 +666,49 @@ class MappingMongoJsonSchemaCreatorUnitTests { @@ -648,6 +666,49 @@ class MappingMongoJsonSchemaCreatorUnitTests {
String provider;
}
static final String ENC_FROM_COLLECTION_KEY = "R2Vkm1DOCM6sBplG+MZYOQ==";
static final String ENC_FROM_COLLECTION_SCHEMA = "{" + //
" 'encryptMetadata': {" + //
" 'keyId': [" + //
" {" + //
" '$binary': {" + //
" 'base64': '" + ENC_FROM_COLLECTION_KEY + "'," + //
" 'subType': '04'" + //
" }" + //
" }" + //
" ]" + //
" }," + //
" 'type': 'object'," + //
" 'properties': {" + //
" 'policyNumber': {" + //
" 'encrypt': {" + //
" 'keyId': [" + //
" [" + //
" {" + //
" '$binary': {" + //
" 'base64': '" + ENC_FROM_COLLECTION_KEY + "'," + //
" 'subType': '04'" + //
" }" + //
" }" + //
" ]" + //
" ]," + //
" 'bsonType': 'int'," + //
" 'algorithm': 'AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic'" + //
" }" + //
" }" + //
" }" + //
"}";
@org.springframework.data.mongodb.core.mapping.Document("patients")
@Encrypted(keyId = "#{mongocrypt.keyId(#collection)}")
static class EncryptionMetadataWithCollection {
@Encrypted(keyId = "#{mongocrypt.keyId(#collection)}", algorithm = "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic") //
Integer policyNumber;
String provider;
}
public static class EncryptionExtension implements EvaluationContextExtension {
@Override
@ -685,6 +746,10 @@ class MappingMongoJsonSchemaCreatorUnitTests { @@ -685,6 +746,10 @@ class MappingMongoJsonSchemaCreatorUnitTests {
return ENC_FROM_METHOD_PROPOERTY_KEY;
}
if (target.equals("patients")) {
return ENC_FROM_COLLECTION_KEY;
}
return "xKVup8B1Q+CkHaVRx+qa+g==";
}
}

Loading…
Cancel
Save