I have a spring boot project (version 2.5.5) and I'm using the spring-boot-starter-data-mongodb dependency to work with MongoDB.
I have a bean with these fields:
@Document(collection = "user_data")
public class UserData {
@Id
private String id;
@Field("is_active")
private Boolean isActive;
@Field("organization_id")
private String organizationId;
@Field("system_mode")
private SystemMode systemMode;
@Field("first_name")
private String firstName;
@Field("last_name")
private String lastName;
}
*Also with constructors and getters and setters but I omitted them for simplicity.
I also have a matching repository:
@Repository
public interface UsersDataRepository extends MongoRepository<UserData, String> {
}
Now the fields firstName and lastName are in fact encrypted and stored in the database as Binary type.
When I try to do say
Optional<UserData> optionalUserData = usersDataRepository.findById(userId);
I get an error stating that failed to convert from Binary to String, which makes sense because the fields are encrypted.
In the database I have a key_vault collection that contains the keys to decrypt.
So how can I add MongoDB client side field level decryption using the above setup so that I can get the fields decrypted and use them in my project?
CodePudding user response:
I followed this guide and got a working solution for my case: https://blog.contactsunny.com/tech/encrypting-and-decrypting-data-in-mongodb-with-a-springboot-project
In a nutshell, create a component that will handle encrypting and decrypting fields. Create two event listener classes that will listen to mongo save and get from database events.
My MongoDBAfterLoadEventListener ended up like this, note that it currently only works for strings:
public class MongoDBAfterLoadEventListener extends AbstractMongoEventListener<Object> {
@Autowired
private EncryptionUtil encryptionUtil;
@Override
public void onAfterLoad(AfterLoadEvent<Object> event) {
Document eventObject = event.getDocument();
List<String> keysToDecrypt = encryptionUtil.ENCRYPTED_FIELDS_MAP.get(event.getCollectionName());
if (keysToDecrypt == null || keysToDecrypt.isEmpty()) {
return;
}
for (String key : eventObject.keySet()) {
if (keysToDecrypt.contains(key)) {
Binary encrypted = (Binary) eventObject.get(key);
BsonBinary bsonBinary = new BsonBinary(encrypted.getData());
BsonValue decrypted = this.encryptionUtil.decryptText(bsonBinary);
eventObject.put(key, decrypted.asString().getValue());
}
}
super.onAfterLoad(event);
}
}
CodePudding user response:
Use MongoDB GridFsTemplate to save, retrieve and delete the binary files. https://www.youtube.com/watch?v=7ciWYVx3ZrA&t=1267s