Spring AOP Proxy for java.security.KeyStore - java

I'm wondering is there any way to make a Spring AOP Proxy for the java.security.KeyStore, there are few obstacles here:
KeyStore does not have default constructor
All methods of KeyStore are final
I know that it is impossible to make a Spring AOP Proxy with the above constraints, but anyway I need to somehow count the method invocations of the KeyStore in the application. Could anybody suggest some way to bypass the Spring AOP constraints or another way?

If you have control of the calling code - and hopefully you do because it is your own application you are talking about - and are willing to use full AspectJ (which does not need any proxies) instead of Spring-AOP, you cann use a call() pointcut instead of being limited to Spring-AOP's execution() pointcut. The pointcut would look something like this (untested, hacked from memory):
#Pointcut("call(* java.security.KeyStore.*(..))")
If you want to extend the pointcut to subclasses, add a + after the class name:
#Pointcut("call(* java.security.KeyStore+.*(..))")
You can even intercept constructor calls if they come from code you can weave into:
#Pointcut("call(java.security.KeyStore+.new(..))")

Related

Get calling method information via custom implementation of #PreAuthorize annotation

Hi we are implementing ABAC over SpringSecurity (looks same as Axiomatics solution). So we would like to define custome expression and customize underlaying mechanisms. e.g. #PreAuthorize("myexpression").
At this point I'm trying understand how can I get information about the target method (the JoinPoint): name, class, parameters. I didn't find how to do it for SpringSecurity customization.
As I Inderstand, other solution may be implemention based direct on AOP e.g. #Around, however I would like to try first to find out if the Spring Security can provide me a way to get somehow JoinPoint it self, isn't it implemented over AOP ?
If anyone have an example, thanks.
I would recommend checking out the new support for #PreAuthorize in Spring Security 5.6 with #EnableMethodSecurity. See the reference docs for information on how to customize the interceptors. There are numerous places you can hook into this support based on your requirements using delegation or fully replacing components with your own implementation.
In your case, it seems the most likely place to start would be creating an #Bean to replace the AuthorizationManagerBeforeMethodInterceptor:
#Bean
#Role(BeanDefinition.ROLE_INFRASTRUCTURE)
Advisor preAuthorizeAuthorizationMethodInterceptor() {
PreAuthorizeAuthorizationManager authorizationManager = new PreAuthorizeAuthorizationManager();
authorizationManager.setExpressionHandler(...);
return AuthorizationManagerBeforeMethodInterceptor.preAuthorize(authorizationManager);
}
You will have to implement the MethodSecurityExpressionHandler, but you can use delegation to re-use the DefaultMethodSecurityExpressionHandler for anything you don't want to implement yourself.

Osgi annotation processing

I have a component declared using the #Component annotation, in which there is a set of methods that implement communication with another api, in my product there are operations that are prohibited for a user with an anonymous id. I want to create an annotation, for example #ProhibitedForAnonym, which, every time the method is called, will check the ID of the anonymous customer, with the ID in the method parameter and throw an error if the IDs match. But I don't understand how to do annotation processing in OSGI, maybe some kind of interceptor?
There is no general interception framework in OSGi. However, you could do interception in the following ways:
Don't. Personally, I feel that since we've lambdas a code-based solution has won hands on over a 'magic' annotation check. It is about the same number of characters but a lambda based call allows me to single step, provide context to the security check, does not suffer from the THIS problem, is testable, and requires no complex framework with lots of bug opportunities.
Use the byte code weaving support in OSGi. You need to register a weaver early and then weave any class that has these annotations. You can take a look at https://github.com/aQute-os/biz.aQute.osgi.util/tree/master/biz.aQute.trace for an example of how to use the byte code weaver. Make sure your weaver is there first. If you use bndtools you can add it to the -runpath to run before anybody else. Or use start levels.
Use proxying. You can 'hide' and original service with the Service Hooks and then register a proxy. In the proxy you can then do the annotation check. This also requires that this code runs first and cannot be updated. I think the spec has an example of this
You might want to read: https://www.aqute.biz/appnotes/interceptors.html

Spring and AOP - handling every thrown exception

I have a requirement to intercept every thrown exception and do something with it. I am using this part of code:
#Aspect
#Component
class Advice
{
#AfterThrowing(pointcut = "execution(* mail.service..*.*(..))", throwing = "throwable")
public void sendError(Throwable throwable)
{
System.out.println("exception thrown");
}
}
This somehow does not work as I expected. This pointcut seems to 'affect' only the public methods(which is expected from Spring AOP, I suppose?) but it prints the String only in certain methods, for example, methods that are declared in my Spring configuration class(i guess its because they are initialized before the app starts) and not in the other ones.
I tried to get this aspect working for any exception thrown, but I had no success. Is this somehow connected with the fact that I am using Spring AOP and not full AspectJ?
Also, my project is written in Kotlin(I wrote the aspect in Java so IJ can support it), will this have an impact on using AspectJ? I had a lot of troubles to get it working (because of final classes) and I am wondering if it's going to be a lot harder when I start writing more advanced AspectJ code.
Thanks!
Yes, Spring AOP only works for Spring components and only for public methods (plus protected and package-protected ones for CGLIB proxies). It also does not work for self-invoked methods like this.doSomething() because those do not go through the proxy. Only if your exceptions escalate outside a method called via proxy, Spring AOP will be able to intercept it.
AspectJ with LTW (load-time weaving) or CTW (compile-time weaving) does not have any of those limitations, plus you can also handle exceptions in constructors, not just in methods.
Never having used Kotlin before, I cannot tell you what possible problems might be there, but final classes should not be a problem as such because AspectJ instruments the classes' bytecode directly, not via proxies. Just give it a try.
BTW, just in case you only use Spring because of AOP: You do not need to use Spring at all in order to apply AOP to your classes because AspectJ is 100% independent of Spring. You can use them together or not, your choice. I for example never use Spring, but just Java SE + AspectJ.

How to configure Spring AOP to use AspectJ

I want to use AOP concept to time execution time of some methods that I mark with an annotation that I created. My problem however is that I refer to the annotated method internally, from within the same class. For example:
public void login(params) {
some logic ...
performLogin();
some logic ...
}
#Measured
public void performLogin() {
some logic ...
}
This is a known issue caused by the fact that Spring AOP is using proxy based approach that does not "see" the internal calls within the same class. Apparently I can solve this situation by using AspectJ instead of Spring AOP. If I understand correctly, it can be configured from within Spring itself. From what I found, it looks like I should include #EnableAspectJAutoProxy annotation to configure Spring to use AspectJ instead of its own AOP. Unfortunately, it did not help and after adding the annotation, the interception of the annotated method did not occur.
There is a lot of information on this topic in Spring reference documentation and I got a bit lost. Is there anything else I am supposed to do so that AspectJ will be used?
P.S. Please note that I cannot refactor the whole class and move the calling method outside.
P.P.S. I also verified my pointcut configuration. I annotated the calling method which is invoked externally and it worked fine.
Proxies can only achieve a sub-set of the full capabilities of the actual AspectJ system, basically advice that wraps methods. Due to their nature proxies have following limitations:
interception on external calls only (while breaching proxy boundary)
interception on public members only (private/protected can't be intercepted)
unawareness to local calls (or calls with this or super)
<aop:aspectj-autoproxy /> is not enough - it only wraps methods, you need something like this: <context:load-time-weaver/>
If you want to be able to advise fields for example, you would need to enable the use of Native AspectJ.

Java Intercepting the calls to an Interface Method

I need to intercept the calls to all the method calls to an Interface. I've gone through the Java Dynamic Proxies however that will not help me. I'm not even sure whether this can be achieved, but thought of confirming.
So basically lets say i have an interface as follows:
public interface Foo {
public String getValue();
}
I would like to intercept all the calls to getValue() from whichever implementations of Foo. Problem is i do not have control over the different implementations of Foo, because of which i cant use Dynamic Proxies.
Is there a way i can do this?
Thanks.
AOP might help, but as you've discovered, it all gets much easier if you're in control of the object creation (even if only through a DI framework like Spring or Guice).
Another alternative is compile-time byte-code weaving - that is, finding all implementations and altering them to have your interception code in them at compile time.
A third alternative would be to look at using either an agent or a custom classloader to do weaving as the classes are loaded into the system. This is load-time weaving. But if you're in, say, a web container where you're not fully in charge of the classloaders, this might be tricky.
The only way to do this would be with a custom classloader that replaces the implementation classes with a proxy.
It might be possible to do this out-of-the-box with Spring AOP's load-time weaving.

Categories