Closed christianblust closed 1 year ago
It is hard to tell what's the problem here. The related test seems to work as expected. Please help us triage the issue and take the time to provide a complete minimal sample (something that we can unzip or git clone, build, and deploy) that reproduces the problem.
Please start the docker-compose.yml
(or any other mongocontainer) in /docker
, then the Application.
The Startup
Component
saves a simple Address
with @ExplicitEncrypted
String
fields and reads them successfully afterwards.
Then, a NestedDocument
with an @ExplicitEncrypted List<NestedAddress>
is saved and read. Reading results in the mentioned exception. When I change List<NestedAddress>
to NestedAddress
the error looks slightly different.
csfldebug.zip https://github.com/christianblust/csfle-debug/tree/develop
@christianblust thanks for the reproducer!
In this case, since the driver is aware of the encryption configuration, the driver already decrypts the array field internally before it is even handed to the converter, which leads to the mentioned ClassCastException
.
Thanks for looking into it! I just noticed the same happening for java.time.Instant
, but that happens probably for the same reason. Currently I am working around with a lot of @ExplicitEncrypted
annotations and ignoring the Instant
s. Is that a viable interim solution until a fix is available?
it is. you can try
@Bean
fun encryptingConverter(): MongoEncryptionConverter{
val encryption = MongoClientEncryption.just(clientEncryption)
val keyResolver = EncryptionKeyResolver.annotated{ _ -> EncryptionKey.keyAltName("demo-data-key")}
return object : MongoEncryptionConverter(encryption, keyResolver) {
override fun decrypt(encryptedValue: Any, context: EncryptionContext): Any {
return context.read(encryptedValue, context.property.typeInformation)
}
}
}
This helps a bit, no exception! However, the result-type after reading or decrypting @ExplicitEncrypted(algorithm = EncryptionAlgorithms.AEAD_AES_256_CBC_HMAC_SHA_512_Random, keyAltName = "demo-data-key") private val nestedAddress: List<NestedAddress> = emptyList())
then is a Document
, so no cast to NestedAddress
is happening.
I also tested skipping the AutoEncryptionSettings
in the MongoClient
:
@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()
)
}
So, @ExplicitEncrypted
works on complex types as you already indicated. Does this solution have some major drawbacks? Code seems much cleaner for larger classes with that approach. java.time.Instant
unfortunately still not works in that case.
Unable to convert 2023-07-04T12:56:09.668856Z (java.time.Instant) to BsonValue.
Hi all,
I am currently trying to implement explicit client side field level encryption according to https://docs.spring.io/spring-data/mongodb/docs/current/reference/html/#mongo.encryption.explicit
It works when I annotate simple types like String. However if I annotate a custom "Address" like type encryption works and my object is saved encrypted to mongo db. Although trying to read it results in a
ClassCastException
in theMongoEncryptionConverter
:Probably relevant code parts:
Here reading (or decrypting) fails with the mentioned ClassCastException
This works:
Sorry if you are also scanning stackoverflow, then this is probably redundant. However I am not sure if I stumbled upon a bug or if I just misconfigured something.