使用Spring Data Mongo对自定义类而不是简单类型进行注解时,显式加密失败。

huangapple go评论79阅读模式
英文:

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.1mongodb-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.

huangapple
  • 本文由 发表于 2023年6月30日 01:27:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/76583341.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定