Expected Behavior
When using @AuthorizeReturnObject annotation to mask object fields, AuthorizationAdvisorProxyFactory now working with some built-in TargetVisitor implements like ClassVisitor, ContainerTypeVisitor. I want the AuthorizationAdvisorProxyFactory can provide some methods to register some TargetVisitors that user implements for some returned object that not in Java native types.
Current Behavior
Creating a proxyFactory by withDefaults() method.
AuthorizationProxyFactory proxyFactory = AuthorizationAdvisorProxyFactory.withDefaults();
Foo foo = new Foo();
foo.bar(); // passes
Foo securedFoo = proxyFactory.proxy(foo);
securedFoo.bar(); // access denied!
withDefaults() using these default TargetVistor implements:
private static final TargetVisitor DEFAULT_VISITOR = isReactivePresent
? TargetVisitor.of(new ClassVisitor(), new ReactiveTypeVisitor(), new ContainerTypeVisitor())
: TargetVisitor.of(new ClassVisitor(), new ContainerTypeVisitor());
Context
For example, some ORM provide an Interface to do pagination, the DAO interface directly returning type with class like Page<T> rather than List<T>. This Page<T> looks like:
@Data
public class Page<T> {
private long size;
private long offset;
private long total;
private List<T> records;
}
So if I want to apply @AuthorizeReturnObject on methods like Page<T> method(), that would not work. I tried to create an implement of TargetVisitor for this type but there seems no where to add it into DEFAULT_VISITOR.
Comment From: kse-music
This is what you need?
@Bean
Customizer<AuthorizationAdvisorProxyFactory> customizer() {
return factory -> factory.setTargetVisitor(AuthorizationAdvisorProxyFactory.TargetVisitor.of(new CustomeTargetVisitor(), AuthorizationAdvisorProxyFactory.TargetVisitor.defaults()));
}
record CustomeTargetVisitor implements AuthorizationAdvisorProxyFactory.TargetVisitor {
@Override
public Object visit(AuthorizationAdvisorProxyFactory proxyFactory, Object target) {
if (target instanceof Page<?> page) {
return proxyPage(proxyFactory, page);
}
return null;
}
@SuppressWarnings("unchecked")
private <T> Page<T> proxyPage(AuthorizationProxyFactory proxyFactory, Page<T> page) {
page.setRecords((List<T>) proxyFactory.proxy(page.getRecords()));
return page;
}
}
Comment From: la3rence
This is what you need?
``` @Bean Customizer
customizer() { return factory -> factory.setTargetVisitor(AuthorizationAdvisorProxyFactory.TargetVisitor.of(new CustomeTargetVisitor(), AuthorizationAdvisorProxyFactory.TargetVisitor.defaults())); } record CustomeTargetVisitor implements AuthorizationAdvisorProxyFactory.TargetVisitor {
@Override public Object visit(AuthorizationAdvisorProxyFactory proxyFactory, Object target) { if (target instanceof Page<?> page) { return proxyPage(proxyFactory, page); } return null; } @SuppressWarnings("unchecked") private <T> Page<T> proxyPage(AuthorizationProxyFactory proxyFactory, Page<T> page) { page.setRecords((List<T>) proxyFactory.proxy(page.getRecords())); return page; }} ```
Yes, exactly! I didn't notice the method AuthorizationAdvisorProxyFactory.TargetVisitor.defaults() is already available.
Thanks!