DATAMONGO-2306 - Add field level encryption to JSON Schema.
We now support encrypted fields via MongoJsonSchema and allow XML configuration of com.mongodb.AutoEncryptionSettings via a dedicated factory bean. Original pull request: #766.
This commit is contained in:
committed by
Mark Paluch
parent
56ac8397aa
commit
da0cb6d766
@@ -22,6 +22,7 @@ import org.springframework.beans.factory.config.AbstractFactoryBean;
|
||||
import org.springframework.data.mongodb.MongoDbFactory;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
import com.mongodb.AutoEncryptionSettings;
|
||||
import com.mongodb.DBDecoderFactory;
|
||||
import com.mongodb.DBEncoderFactory;
|
||||
import com.mongodb.MongoClient;
|
||||
@@ -73,6 +74,7 @@ public class MongoClientOptionsFactoryBean extends AbstractFactoryBean<MongoClie
|
||||
|
||||
private boolean ssl;
|
||||
private @Nullable SSLSocketFactory sslSocketFactory;
|
||||
private @Nullable AutoEncryptionSettings autoEncryptionSettings;
|
||||
|
||||
/**
|
||||
* Set the {@link MongoClient} description.
|
||||
@@ -272,6 +274,16 @@ public class MongoClientOptionsFactoryBean extends AbstractFactoryBean<MongoClie
|
||||
this.serverSelectionTimeout = serverSelectionTimeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the {@link AutoEncryptionSettings} to be used.
|
||||
*
|
||||
* @param autoEncryptionSettings can be {@literal null}.
|
||||
* @since 2.2
|
||||
*/
|
||||
public void setAutoEncryptionSettings(@Nullable AutoEncryptionSettings autoEncryptionSettings) {
|
||||
this.autoEncryptionSettings = autoEncryptionSettings;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.config.AbstractFactoryBean#createInstance()
|
||||
@@ -304,7 +316,8 @@ public class MongoClientOptionsFactoryBean extends AbstractFactoryBean<MongoClie
|
||||
.requiredReplicaSetName(requiredReplicaSetName) //
|
||||
.serverSelectionTimeout(serverSelectionTimeout) //
|
||||
.sslEnabled(ssl) //
|
||||
.socketFactory(socketFactoryToUse) // TODO: Mongo Driver 4 - remove if not available
|
||||
.autoEncryptionSettings(autoEncryptionSettings) //
|
||||
.socketFactory(socketFactoryToUse) // TODO: Mongo Driver 4 -
|
||||
.socketKeepAlive(socketKeepAlive) // TODO: Mongo Driver 4 - remove if not available
|
||||
.socketTimeout(socketTimeout) //
|
||||
.threadsAllowedToBlockForConnectionMultiplier(threadsAllowedToBlockForConnectionMultiplier) //
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright 2019 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
|
||||
*
|
||||
* https://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.data.mongodb.core;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.bson.BsonDocument;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
|
||||
import com.mongodb.AutoEncryptionSettings;
|
||||
import com.mongodb.MongoClientSettings;
|
||||
|
||||
/**
|
||||
* {@link FactoryBean} for creating {@link AutoEncryptionSettings} using the {@link AutoEncryptionSettings.Builder}.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @since 2.2
|
||||
*/
|
||||
public class MongoEncryptionSettingsFactoryBean implements FactoryBean<AutoEncryptionSettings> {
|
||||
|
||||
private boolean bypassAutoEncryption;
|
||||
private String keyVaultNamespace;
|
||||
private Map<String, Object> extraOptions;
|
||||
private MongoClientSettings keyVaultClientSettings;
|
||||
private Map<String, Map<String, Object>> kmsProviders;
|
||||
private Map<String, BsonDocument> schemaMap;
|
||||
|
||||
/**
|
||||
* @param bypassAutoEncryption
|
||||
* @see AutoEncryptionSettings.Builder#bypassAutoEncryption(boolean)
|
||||
*/
|
||||
public void setBypassAutoEncryption(boolean bypassAutoEncryption) {
|
||||
this.bypassAutoEncryption = bypassAutoEncryption;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param extraOptions
|
||||
* @see AutoEncryptionSettings.Builder#extraOptions(Map)
|
||||
*/
|
||||
public void setExtraOptions(Map<String, Object> extraOptions) {
|
||||
this.extraOptions = extraOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param keyVaultNamespace
|
||||
* @see AutoEncryptionSettings.Builder#keyVaultNamespace(String)
|
||||
*/
|
||||
public void setKeyVaultNamespace(String keyVaultNamespace) {
|
||||
this.keyVaultNamespace = keyVaultNamespace;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param keyVaultClientSettings
|
||||
* @see AutoEncryptionSettings.Builder#keyVaultMongoClientSettings(MongoClientSettings)
|
||||
*/
|
||||
public void setKeyVaultClientSettings(MongoClientSettings keyVaultClientSettings) {
|
||||
this.keyVaultClientSettings = keyVaultClientSettings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param kmsProviders
|
||||
* @see AutoEncryptionSettings.Builder#kmsProviders(Map)
|
||||
*/
|
||||
public void setKmsProviders(Map<String, Map<String, Object>> kmsProviders) {
|
||||
this.kmsProviders = kmsProviders;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param schemaMap
|
||||
* @see AutoEncryptionSettings.Builder#schemaMap(Map)
|
||||
*/
|
||||
public void setSchemaMap(Map<String, BsonDocument> schemaMap) {
|
||||
this.schemaMap = schemaMap;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.FactoryBean#getObject()
|
||||
*/
|
||||
@Override
|
||||
public AutoEncryptionSettings getObject() {
|
||||
|
||||
return AutoEncryptionSettings.builder() //
|
||||
.bypassAutoEncryption(bypassAutoEncryption) //
|
||||
.keyVaultNamespace(keyVaultNamespace) //
|
||||
.keyVaultMongoClientSettings(keyVaultClientSettings) //
|
||||
.kmsProviders(orEmpty(kmsProviders)) //
|
||||
.extraOptions(orEmpty(extraOptions)) //
|
||||
.schemaMap(orEmpty(schemaMap)) //
|
||||
.build();
|
||||
}
|
||||
|
||||
private <K, V> Map<K, V> orEmpty(Map<K, V> source) {
|
||||
return source != null ? source : Collections.emptyMap();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
|
||||
*/
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return AutoEncryptionSettings.class;
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,9 @@ import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.Numeri
|
||||
import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.ObjectJsonSchemaObject;
|
||||
import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.StringJsonSchemaObject;
|
||||
import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.TimestampJsonSchemaObject;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* {@link JsonSchemaProperty} implementation.
|
||||
@@ -1044,4 +1046,147 @@ public class IdentifiableJsonSchemaProperty<T extends JsonSchemaObject> implemen
|
||||
return required;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link JsonSchemaProperty} implementation for encrypted fields.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
* @since 2.2
|
||||
*/
|
||||
public static class EncryptedJsonSchemaProperty implements JsonSchemaProperty {
|
||||
|
||||
private final JsonSchemaProperty targetProperty;
|
||||
private final @Nullable String algorithm;
|
||||
private final @Nullable char[] keyId;
|
||||
private final @Nullable char[] iv;
|
||||
|
||||
/**
|
||||
* Create new instance of {@link EncryptedJsonSchemaProperty} wrapping the given {@link JsonSchemaProperty target}.
|
||||
*
|
||||
* @param target must not be {@literal null}.
|
||||
*/
|
||||
public EncryptedJsonSchemaProperty(JsonSchemaProperty target) {
|
||||
this(target, null, null, null);
|
||||
}
|
||||
|
||||
private EncryptedJsonSchemaProperty(JsonSchemaProperty target, @Nullable String algorithm, @Nullable char[] keyId,
|
||||
@Nullable char[] iv) {
|
||||
|
||||
Assert.notNull(target, "Target must not be null!");
|
||||
this.targetProperty = target;
|
||||
this.algorithm = algorithm;
|
||||
this.keyId = keyId;
|
||||
this.iv = iv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new instance of {@link EncryptedJsonSchemaProperty} wrapping the given {@link JsonSchemaProperty target}.
|
||||
*
|
||||
* @param target must not be {@literal null}.
|
||||
* @return new instance of {@link EncryptedJsonSchemaProperty}.
|
||||
*/
|
||||
public static EncryptedJsonSchemaProperty encrypted(JsonSchemaProperty target) {
|
||||
return new EncryptedJsonSchemaProperty(target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use {@literal AEAD_AES_256_CBC_HMAC_SHA_512-Random} algorithm.
|
||||
*
|
||||
* @return new instance of {@link EncryptedJsonSchemaProperty}.
|
||||
*/
|
||||
public EncryptedJsonSchemaProperty aead_aes_256_cbc_hmac_sha_512_random() {
|
||||
return algorithm("AEAD_AES_256_CBC_HMAC_SHA_512-Random");
|
||||
}
|
||||
|
||||
/**
|
||||
* Use {@literal AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic} algorithm.
|
||||
*
|
||||
* @return new instance of {@link EncryptedJsonSchemaProperty}.
|
||||
*/
|
||||
public EncryptedJsonSchemaProperty aead_aes_256_cbc_hmac_sha_512_deterministic() {
|
||||
return algorithm("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic");
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the given algorithm identified via its name.
|
||||
*
|
||||
* @return new instance of {@link EncryptedJsonSchemaProperty}.
|
||||
*/
|
||||
public EncryptedJsonSchemaProperty algorithm(String algorithm) {
|
||||
return new EncryptedJsonSchemaProperty(targetProperty, algorithm, keyId, iv);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public EncryptedJsonSchemaProperty keyId(char[] key) {
|
||||
return new EncryptedJsonSchemaProperty(targetProperty, algorithm, key, iv);
|
||||
}
|
||||
|
||||
public EncryptedJsonSchemaProperty keyId(String key) {
|
||||
return keyId(key.toCharArray());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.schema.JsonSchemaObject#toDocument()
|
||||
*/
|
||||
@Override
|
||||
public Document toDocument() {
|
||||
|
||||
Document doc = targetProperty.toDocument();
|
||||
Document propertySpecification = doc.get(targetProperty.getIdentifier(), Document.class);
|
||||
|
||||
Document enc = new Document();
|
||||
|
||||
if (!ObjectUtils.isEmpty(keyId)) {
|
||||
enc.append("keyId", new String(keyId));
|
||||
}
|
||||
|
||||
Type type = extractPropertyType(propertySpecification);
|
||||
if (type != null) {
|
||||
|
||||
propertySpecification.remove(type.representation());
|
||||
enc.append("bsonType", type.toBsonType().value()); // TODO: no samples with type -> is it bson type all the way?
|
||||
}
|
||||
|
||||
enc.append("algorithm", algorithm);
|
||||
|
||||
propertySpecification.append("encrypt", enc);
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.schema.JsonSchemaProperty#getIdentifier()
|
||||
*/
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return targetProperty.getIdentifier();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.mongodb.core.schema.JsonSchemaObject#getTypes()
|
||||
*/
|
||||
@Override
|
||||
public Set<Type> getTypes() {
|
||||
return targetProperty.getTypes();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Type extractPropertyType(Document source) {
|
||||
|
||||
if (source.containsKey("type")) {
|
||||
return Type.of(source.get("type", String.class));
|
||||
}
|
||||
if (source.containsKey("bsonType")) {
|
||||
return Type.of(source.get("bsonType", String.class));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.schema;
|
||||
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
@@ -428,6 +429,23 @@ public interface JsonSchemaObject {
|
||||
return new JsonType(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link Type} with its default {@link Type#representation() representation} via the name.
|
||||
*
|
||||
* @param name must not be {@literal null}.
|
||||
* @return the matching type instance.
|
||||
* @since 2.2
|
||||
*/
|
||||
static Type of(String name) {
|
||||
|
||||
Type type = jsonTypeOf(name);
|
||||
if (jsonTypes().contains(type)) {
|
||||
return type;
|
||||
}
|
||||
|
||||
return bsonTypeOf(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return all known JSON types.
|
||||
*/
|
||||
@@ -456,11 +474,34 @@ public interface JsonSchemaObject {
|
||||
*/
|
||||
Object value();
|
||||
|
||||
/**
|
||||
* Get the {@literal bsonType} representation of the given type.
|
||||
*
|
||||
* @return never {@literal null}.
|
||||
* @since 2.2
|
||||
*/
|
||||
default Type toBsonType() {
|
||||
|
||||
if (representation().equals("bsonType")) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (value().equals(Type.booleanType().value())) {
|
||||
return bsonTypeOf("bool");
|
||||
}
|
||||
if (value().equals(Type.numberType().value())) {
|
||||
return bsonTypeOf("long");
|
||||
}
|
||||
|
||||
return bsonTypeOf((String) value());
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Christpoh Strobl
|
||||
* @since 2.1
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@EqualsAndHashCode
|
||||
class JsonType implements Type {
|
||||
|
||||
private final String name;
|
||||
@@ -489,6 +530,7 @@ public interface JsonSchemaObject {
|
||||
* @since 2.1
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@EqualsAndHashCode
|
||||
class BsonType implements Type {
|
||||
|
||||
private final String name;
|
||||
|
||||
@@ -18,18 +18,9 @@ package org.springframework.data.mongodb.core.schema;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.ArrayJsonSchemaProperty;
|
||||
import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.BooleanJsonSchemaProperty;
|
||||
import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.DateJsonSchemaProperty;
|
||||
import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.NullJsonSchemaProperty;
|
||||
import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.NumericJsonSchemaProperty;
|
||||
import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.ObjectJsonSchemaProperty;
|
||||
import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.RequiredJsonSchemaProperty;
|
||||
import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.StringJsonSchemaProperty;
|
||||
import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.TimestampJsonSchemaProperty;
|
||||
import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.UntypedJsonSchemaProperty;
|
||||
import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.NumericJsonSchemaObject;
|
||||
import org.springframework.data.mongodb.core.schema.TypedJsonSchemaObject.ObjectJsonSchemaObject;
|
||||
import org.springframework.data.mongodb.core.schema.IdentifiableJsonSchemaProperty.*;
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
@@ -68,6 +59,17 @@ public interface JsonSchemaProperty extends JsonSchemaObject {
|
||||
return new UntypedJsonSchemaProperty(identifier, JsonSchemaObject.untyped());
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns the given target property into an {@link EncryptedJsonSchemaProperty ecrypted} one.
|
||||
*
|
||||
* @param property must not be {@literal null}.
|
||||
* @return new instance of {@link EncryptedJsonSchemaProperty}.
|
||||
* @since 2.2
|
||||
*/
|
||||
static EncryptedJsonSchemaProperty encrypted(JsonSchemaProperty property) {
|
||||
return EncryptedJsonSchemaProperty.encrypted(property);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link StringJsonSchemaProperty} with given {@literal identifier} of {@code type : 'string'}.
|
||||
*
|
||||
|
||||
@@ -311,6 +311,20 @@ The name of the MongoClient object that determines what server to monitor. (by d
|
||||
<xsd:union memberTypes="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="encryptionSettingsRef">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Reference to FactoryBean for com.mongodb.AutoEncryptionSettings - @since 2.2
|
||||
]]></xsd:documentation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="org.springframework.data.mongodb.core.MongoEncryptionSettingsFactoryBean" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:union memberTypes="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="writeConcernEnumeration">
|
||||
<xsd:restriction base="xsd:token">
|
||||
<xsd:enumeration value="NONE" />
|
||||
@@ -546,6 +560,13 @@ The SSLSocketFactory to use for the SSL connection. If none is configured here,
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="encryption-settings-ref" type="encryptionSettingsRef" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
AutoEncryptionSettings for MongoDB 4.2+ - @since 2.2
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
<xsd:group name="beanElementGroup">
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2019 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
|
||||
*
|
||||
* https://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.data.mongodb.core;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import com.mongodb.AutoEncryptionSettings;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link MongoEncryptionSettingsFactoryBean}.
|
||||
*
|
||||
* @author Christoph Strobl
|
||||
*/
|
||||
public class MongoEncryptionSettingsFactoryBeanTests {
|
||||
|
||||
@Test // DATAMONGO-2306
|
||||
public void createsAutoEncryptionSettings() {
|
||||
|
||||
RootBeanDefinition definition = new RootBeanDefinition(MongoEncryptionSettingsFactoryBean.class);
|
||||
definition.getPropertyValues().addPropertyValue("bypassAutoEncryption", true);
|
||||
definition.getPropertyValues().addPropertyValue("keyVaultNamespace", "ns");
|
||||
|
||||
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
|
||||
factory.registerBeanDefinition("factory", definition);
|
||||
|
||||
MongoEncryptionSettingsFactoryBean bean = factory.getBean("&factory", MongoEncryptionSettingsFactoryBean.class);
|
||||
assertThat(ReflectionTestUtils.getField(bean, "bypassAutoEncryption")).isEqualTo(true);
|
||||
|
||||
AutoEncryptionSettings target = factory.getBean(AutoEncryptionSettings.class);
|
||||
assertThat(target.getKeyVaultNamespace()).isEqualTo("ns");
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.springframework.data.mongodb.core.schema;
|
||||
|
||||
import static org.springframework.data.mongodb.core.schema.JsonSchemaProperty.*;
|
||||
import static org.springframework.data.mongodb.test.util.Assertions.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -71,6 +72,21 @@ public class MongoJsonSchemaUnitTests {
|
||||
new Document("lastname", new Document("type", "string")))));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-2306
|
||||
public void rendersEncryptedPropertyCorrectly() {
|
||||
|
||||
MongoJsonSchema schema = MongoJsonSchema.builder().properties( //
|
||||
encrypted(string("ssn")) //
|
||||
.aead_aes_256_cbc_hmac_sha_512_deterministic() //
|
||||
.keyId("*key0_id") //
|
||||
).build();
|
||||
|
||||
assertThat(schema.toDocument()).isEqualTo(new Document("$jsonSchema",
|
||||
new Document("type", "object").append("properties",
|
||||
new Document("ssn", new Document("encrypt", new Document("keyId", "*key0_id")
|
||||
.append("algorithm", "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic").append("bsonType", "string"))))));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-1835
|
||||
public void throwsExceptionOnNullRoot() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> MongoJsonSchema.of((JsonSchemaObject) null));
|
||||
|
||||
@@ -205,6 +205,28 @@ template.find(query(matchingDocumentStructure(schema)), Person.class);
|
||||
----
|
||||
====
|
||||
|
||||
[[mongo.jsonSchema.encrypted-fields]]
|
||||
==== Encrypted Fields
|
||||
|
||||
MongoDB 4.2 https://docs.mongodb.com/master/core/security-client-side-encryption/[Field Level Encryption] allows to directly secure certain properties.
|
||||
|
||||
Properties can be wrapped within an encrypted property when setting up the JSON Schema as shown in the example below.
|
||||
|
||||
.Client-Side Field Level Encryption via Json Schema
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
MongoJsonSchema schema = MongoJsonSchema.builder()
|
||||
.properties(
|
||||
encrypted(string("ssn"))
|
||||
.algorithm("AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic")
|
||||
.keyId("*key0_id")
|
||||
).build();
|
||||
----
|
||||
====
|
||||
|
||||
NOTE: Make sure to set the drivers `com.mongodb.AutoEncryptionSettings` to use client side encryption.
|
||||
|
||||
[[mongo.jsonSchema.types]]
|
||||
==== JSON Schema Types
|
||||
|
||||
|
||||
Reference in New Issue
Block a user