0

I want to mask personal information when a Java DTO is created. I created an PersonalInfo annotation and added it to the field I want to mask. However, I don't know how to write an advice in the PersonalInfoAspect class.

@Getter
@Builder
public class User {

    private String id;

    @PersonalInfo
    private String name; 
}
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface PersonalInfo {
}
@Aspect
@Component
public class PersonalInfoAspect {
    
    // ...
}

When the DTO is created, should AOP be called when the constructor is called to change the field value?

When creating User DTO as shown below, I want it to be masked and stored using Spring AOP.

When creating a DTO, I want to intercept the constructor and generate it as masked data. Finally, when providing it as API using dto, I want to provide it as masked data Even if there is unmasked data in the DB.

kaven
  • 5
  • 3
  • Welcome to SO. Please edit your question to clarify what it is you want to achieve, because your wording is unclear and ambiguous. Your code nsippet on the bottom of the question is not helping either. "When a DTO is created" sounds like you want to intercept constructor calls. Then you say you "want it to be masked and stored using Spring AOP". I cannot imagine that you want to store the masked value instead of the original one. Maybe you want to **log** the masked value, but when exactly? Like I said, the question is totally unclear. – kriegaex Jan 19 '23 at 11:14
  • Thank you, When creating a DTO, I want to intercept the constructor and generate it as masked data. Finally, when providing it as API using dto, I want to provide it as masked data Even if there is unmasked data in the DB. – kaven Jan 20 '23 at 07:45
  • I understand it a little bit better now, but still not 100%, because your wording is still unclear: What does "when providing it as API using dto" mean? Your code does not communicate your intent, either. I suggest that you create an [MCVE](https://stackoverflow.com/help/mcve) on GitHub, i.e. a minimal project isolating and reproducing your problem. Then write a little, failing unit test (or main method with asserts) verifying the behaviour you expect for both cases you described. then I can easily help you. But I do not like guessing. – kriegaex Jan 20 '23 at 13:10
  • What I can tell you already is that if you want to intercept field read/write access or constructors, you cannot use the proxy-based Spring AOP anyway. It is an advanced case requiring native AspectJ. You can use AspectJ with or without Spring, and you are not limited to intercepting method calls of Spring components. It works for any code. If you want to avoid native AspectJ, you would have to create a Spring component with factory methods for your DTO, which you can intercept. If the DTO itself is a `@Component`, you can also intercept its setter/getter methods. – kriegaex Jan 20 '23 at 13:19

2 Answers2

0

You can write aspect for getters. Remember that Lombok @Getter generates plain old getter methods for fields which can be intercepted. You will probably have to mark your DTOs that should be affected with eg some annotation (and fields as well to show which fields should be obfuscated)

FYI What you call "Spring AOP" will work only on managed beans (@Components), but using AOP in general would work. As a crosspoint you could use return statements that returns your DTOs so it would become obfuscated right before passing controll back to spring.

Antoniossss
  • 31,590
  • 6
  • 57
  • 99
0

You would need a @Around advice on the annotation but only for the execution pointcut designator like -

@Around("@annotation(your.package.PersonalInfo) && execution(* *.*(..))")
public Object maskValue(final ProceedingJoinPoint jp) {
    Object obj = jp.proceed();
    if (obj == null && !jp.getSignature().getName().contains("get")) {
        return jp.proceed();
    }
    String value = String.valueOf(obj);
    obj = someFunction(value); // method call for your logic
    return obj;
}

The execution(...) will scan for all packages for the said annotation. It can be directed to scan a particular package as well to limit the scan.

dexter_
  • 381
  • 1
  • 6