英文:
Explicit Encryption with Spring Data Mongo fails when annotating custom class instead of simple type
问题
I try to implement explicit client side field level encryption with spring boot and mongodb.
我尝试使用Spring Boot和MongoDB实现显式客户端端字段级加密。
I am using the following documentation: https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongo.encryption.explicit
我正在使用以下文档:https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongo.encryption.explicit
Encryption and decryption works when I annotate simple types like String or Int like this:
当我像这样注释简单类型,比如String或Int时,加密和解密都能正常工作:
@Document
data class AdressDocument(
@ExplicitEncrypted(algorithm = EncryptionAlgorithms.AEAD_AES_256_CBC_HMAC_SHA_512_Random, keyAltName = "demo-data-key") private val zip: String,
@ExplicitEncrypted(algorithm = EncryptionAlgorithms.AEAD_AES_256_CBC_HMAC_SHA_512_Random, keyAltName = "demo-data-key") private val city: String)
I can save and read types with the standard mongo repositories, meaning data is encrypted and decrypted.
我可以使用标准的Mongo仓库保存和读取类型,这意味着数据已加密和解密。
However, when I annotate the whole type (or a list of the type), the data is encrypted successfully (verified via mongodb compass), but reading fails with the following stacktrace:
然而,当我注释整个类型(或类型的列表)时,数据会成功加密(通过mongodb compass验证),但读取操作失败,出现以下堆栈跟踪:
java.lang.ClassCastException: class org.bson.Document cannot be cast to class org.bson.BsonValue (org.bson.Document and org.bson.BsonValue are in unnamed module of loader 'app')
...
Mongo configuration classes:
Mongo配置类:
@Configuration
class ClientEncryptionConfig(private val masterKeyProvider: MasterKeyProvider) {
...
}
@Configuration
class MongoConfig(private val clientEncryption: ClientEncryption, private val masterKeyProvider: MasterKeyProvider, private val appContext: ApplicationContext): AbstractMongoClientConfiguration(){
...
}
I'm not sure if some additional configuration is missing or if I just did something wrong.
我不确定是否缺少一些附加配置,或者我是否做错了什么。
I am using Spring Boot 3.1.1
and mongodb-crypt 1.8.0
.
我正在使用Spring Boot 3.1.1
和mongodb-crypt 1.8.0
。
英文:
I try to implement explicit client side field level encryption with spring boot and mongodb.
I am using the following documentation: https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongo.encryption.explicit
Encryption and decryption works when I annotate simple types like String or Int like this:
@Document
data class AdressDocument(
@ExplicitEncrypted(algorithm = EncryptionAlgorithms.AEAD_AES_256_CBC_HMAC_SHA_512_Random, keyAltName = "demo-data-key") private val zip: String,
@ExplicitEncrypted(algorithm = EncryptionAlgorithms.AEAD_AES_256_CBC_HMAC_SHA_512_Random, keyAltName = "demo-data-key") private val city: String)
I can save and read types with the standard mongo repositories, meaning data is encrypted and decrypted.
However, when I annotate the whole type (or a list of the type), the data is encrypted successfully (verified via mongodb compass), but reading fails with the following stacktrace:
java.lang.ClassCastException: class org.bson.Document cannot be cast to class org.bson.BsonValue (org.bson.Document and org.bson.BsonValue are in unnamed module of loader 'app')
at org.springframework.data.mongodb.core.convert.encryption.MongoEncryptionConverter.lambda$decrypt$1(MongoEncryptionConverter.java:102)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at org.springframework.data.mongodb.core.convert.encryption.MongoEncryptionConverter.decrypt(MongoEncryptionConverter.java:101)
at org.springframework.data.mongodb.core.convert.encryption.EncryptingConverter.read(EncryptingConverter.java:32)
at org.springframework.data.mongodb.core.convert.encryption.MongoEncryptionConverter.read(MongoEncryptionConverter.java:65)
at org.springframework.data.mongodb.core.convert.encryption.MongoEncryptionConverter.read(MongoEncryptionConverter.java:48)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$MongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1920)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$AssociationAwareMongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1983)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$AssociationAwareMongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1944)
at org.springframework.data.mapping.model.PersistentEntityParameterValueProvider.getParameterValue(PersistentEntityParameterValueProvider.java:71)
at org.springframework.data.mapping.model.SpELExpressionParameterValueProvider.getParameterValue(SpELExpressionParameterValueProvider.java:49)
at org.springframework.data.mapping.model.KotlinClassGeneratingEntityInstantiator$DefaultingKotlinClassInstantiatorAdapter.extractInvocationArguments(KotlinClassGeneratingEntityInstantiator.java:222)
at org.springframework.data.mapping.model.KotlinClassGeneratingEntityInstantiator$DefaultingKotlinClassInstantiatorAdapter.createInstance(KotlinClassGeneratingEntityInstantiator.java:196)
at org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:98)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:491)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readDocument(MappingMongoConverter.java:459)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:395)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:391)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:102)
at org.springframework.data.mongodb.core.MongoTemplate$ReadDocumentCallback.doWith(MongoTemplate.java:3217)
at org.springframework.data.mongodb.core.MongoTemplate.executeFindMultiInternal(MongoTemplate.java:2851)
at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:2556)
at org.springframework.data.mongodb.core.MongoTemplate.doFind(MongoTemplate.java:2537)
at org.springframework.data.mongodb.core.MongoTemplate.find(MongoTemplate.java:865)
at org.springframework.data.mongodb.repository.support.SimpleMongoRepository.findAll(SimpleMongoRepository.java:354)
at org.springframework.data.mongodb.repository.support.SimpleMongoRepository.findAll(SimpleMongoRepository.java:136)
Mongo configuration classes:
@Configuration
class ClientEncryptionConfig(private val masterKeyProvider: MasterKeyProvider) {
@Bean
fun encryptionClient(): ClientEncryption {
val clientEncryptionSettings = ClientEncryptionSettings.builder()
.keyVaultMongoClientSettings(
MongoClientSettings.builder()
.applyConnectionString(MongoConfig.connectionString)
.build()
)
.keyVaultNamespace(MongoConfig.keyVaultNamespace)
.kmsProviders(masterKeyProvider.kmsProviders())
.build()
return ClientEncryptions.create(clientEncryptionSettings)
}
}
@Configuration
class MongoConfig(private val clientEncryption: ClientEncryption, private val masterKeyProvider: MasterKeyProvider, private val appContext: ApplicationContext): AbstractMongoClientConfiguration(){
companion object {
val vaultCollectionName = "__keyVault"
val dbName = "dbName"
val keyVaultNamespace = "$dbName.$vaultCollectionName"
val connectionString = ConnectionString("dummy-connection-string")
}
@Bean
override fun mongoClient(): MongoClient {
val autoEncryptionSettings = AutoEncryptionSettings.builder()
.keyVaultNamespace(keyVaultNamespace)
.kmsProviders(masterKeyProvider.kmsProviders())
.bypassAutoEncryption(true)
.build()
return MongoClients.create(
MongoClientSettings.builder()
.applyConnectionString(connectionString)
.autoEncryptionSettings(autoEncryptionSettings)
.build()
)
}
@Bean
fun encryptingConverter(): MongoEncryptionConverter{
val encryption = MongoClientEncryption.just(clientEncryption)
val keyResolver = EncryptionKeyResolver.annotated{ _ -> EncryptionKey.keyAltName("demo-data-key")}
return MongoEncryptionConverter(encryption, keyResolver)
}
override fun configureConverters(converterConfigurationAdapter: MongoCustomConversions.MongoConverterConfigurationAdapter) {
converterConfigurationAdapter.registerPropertyValueConverterFactory(PropertyValueConverterFactory.beanFactoryAware(appContext))
}
override fun getDatabaseName(): String {
return "databaseName"
}
}
I'm not sure if some additional configuration is missing or if I just did something wrong.
I am using Spring Boot 3.1.1
and mongodb-crypt 1.8.0
答案1
得分: 0
我在 GitHub 上发布了这个问题,它是一个目前正在修复的错误:
https://github.com/spring-projects/spring-data-mongodb/issues/4432
一个临时解决方案是在配置 MongoClient
时跳过自动加密配置。
英文:
I posted the issue on github, it is a bug which is currently beeing fixed:
https://github.com/spring-projects/spring-data-mongodb/issues/4432
An intermediate solution is to skip the auto-encryption configuration when configuring the MongoClient
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论