For our current project, we are integrating JSF and the Spring Framework. I’d like to use Spring Security to handle authentication and authorization. So far, I have implemented a custom PasswordEncoder and AccessDecisionVoter which are working fine. Now I’m trying to secure methods using the @Secured annotation (among others) but I can’t get that to work as I would expect it to do.
It seems that the @Secured annotation works for bean methods called directly from the JSF layer, only. Here’s a simplified example:
@Named("foobarBean")
@Scope("access")
public class FoobarBean
{
@Secured("PERMISSION_TWO")
public void dummy()
{
}
@Secured("PERMISSION_ONE")
public String save()
{
dummy();
}
}
The method save() is called from the JSF layer like this:
<h:commandButton id="save" action="#{foobarBean.save}" />
Our AccessDecisionVoter is then asked to vote on PERMISSION_ONE but not on PERMISSION_TWO. Is this working as designed (I hope not) or am I doing something wrong (what could that be?).
I’d post more code or config but I’m not sure which part is relevant, and I don’t want to clutter this post.
It is a simple problem of Proxy AOP! If you use Proxy AOP for Security, then the Proxy can only intercept calles that go through the proxy. If one method invoke an other method of the same bean directly, then there is no proxy that can intercept this call. — And this is the reason why only the the Security Annotation of
save()is taken in account.One solution would be using AspectJ AOP instead of Proxy AOP. (It is supported by Spring (Security) too.)