How to save and load encrypted value using custom annotation

I am new to Java custom annotations

I am developing a custom annotation that encrypts and decrypts a string and store it in a database using spring and mongodb and for encryption I am using jasypt.

I am not getting the exact procedure for this.

My code.

An object

public class Demo {

    @Id
    private Long id;

    private String somethingPublic;

    @EncryptDemo()
    private String somethingPrivate;

   //getter setter

}

      

custom annotation

@Target({ ElementType.METHOD, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface EncryptDemo {

}

      

How do I add encryption behavior to custom annotation before I save the object.

Where should I add the encryption code that reflects my annotation when it is called.

I want to create a sleeper like annotation.

Any help would be appreciated. Thank you in advance.

+3


source to share


1 answer


Basically you need

  • Create AbstractMongoEventListener

    to listen for events AfterConvertEvent

    andBeforeSaveEvent

  • Execute callbacks org.springframework.util.ReflectionUtils.FieldCallback

    to perform actions on these events
  • Register listener as Bean in Spring data mongodb config class

Listener:

public class EncryptionMongoEventListener extends AbstractMongoEventListener<Object> {
    @Override
    public void onBeforeSave(BeforeSaveEvent<Object> event) {
        Object source = event.getSource();
        DBObject dbObject = event.getDBObject();
        ReflectionUtils.doWithFields(source.getClass(), 
            new EncryptCallback(source, dbObject),
            ReflectionUtils.COPYABLE_FIELDS);
    }
    @Override
    public void onAfterConvert(AfterConvertEvent<Object> event) {
        Object source = event.getSource();
        ReflectionUtils.doWithFields(source.getClass(), 
            new DecryptCallback(source),
            ReflectionUtils.COPYABLE_FIELDS);
    }
}

      

Encrypt callback:



class EncryptCallback implements FieldCallback {
    private final Object source;
    private final DBObject dbObject;

    public EncryptCallback(final Object source, final DBObject dbObject) {
        this.source = source;
        this.dbObject = dbObject;
    }

    @Override
    public void doWith(Field field) 
        throws IllegalArgumentException, IllegalAccessException {
        if (!field.isAnnotationPresent(/* your annotation */.class)) {
            return;
        }
        ReflectionUtils.makeAccessible(field);
        String plainText = (String) ReflectionUtils.getField(field, source);
        String encryptedValue = /* your encryption of plainText */;
        // update the value in DBObject before it is saved to mongodb
        dbObject.put(field.getName(), encryptedValue);
    }
}

      

Decrypt callback:

class DecryptCallback implements FieldCallback {
    private final Object source;

    public DecryptCallback(Object source) {
        this.source = source;
    }

    @Override
    public void doWith(Field field) 
        throws IllegalArgumentException, IllegalAccessException {
        if (!field.isAnnotationPresent(/* your annotation */.class)) {
            return;
        }
        ReflectionUtils.makeAccessible(field);
        String fieldValue = (String) ReflectionUtils.getField(field, source);
        String decryptedValue = /* your decryption of fieldValue */;
        // set the decrypted value in source Object
        ReflectionUtils.setField(field, source, decryptedValue);
    }
}

      

and finally register the listener as a Bean in your Spring Data mongodb configuration class

@Bean
public EncryptionMongoEventListener encryptionMongoEventListener() {
    return new EncryptionMongoEventListener();
}

      

+3


source







All Articles