views:

280

answers:

4

I'd like to implement declarative security with Spring/AOP and annotations. As you see in the next code sample I have the Restricted Annotations with the paramter "allowedRoles" for defining who is allowed to execute an adviced method.

    @Restricted(allowedRoles="jira-administrators")
        public void setPassword(...) throws UserMgmtException {             
               // set password code
               ...
        }

Now, the problem is that in my Advice I have no access to the defined Annotations:

public Object checkPermission(ProceedingJoinPoint pjp) throws Throwable {

    Signature signature = pjp.getSignature();
    System.out.println("Allowed:" + rolesAllowedForJoinPoint(pjp));
            ...
}

private Restricted rolesAllowedForJoinPoint(ProceedingJoinPoint thisJoinPoint)
        {
            MethodSignature methodSignature = (MethodSignature) thisJoinPoint.getSignature();
            Method targetMethod = methodSignature.getMethod();

            return targetMethod.getAnnotation(Restricted.class);
        }

The method above always returns null (there are no annotations found at all). Is there a simple solution to this?

I read something about using the AspectJ agent but I would prefer not to use this agent.

+1  A: 

I assume @Restricted is your annotation. If that is the case, make sure you have:

@Retention(RetentionPolicy.RUNTIME)

in your annotation definition. This means that the annotation is retained at runtime.

Bozho
Thanks a lot, that was the reason.
hubertg
A: 

Why don't you just use Spring Security ? It's a brief to implement and use, I don't really see the point in wasting time reinventing the wheel.

dakull
Thanks, I will have a look at it soon
hubertg
A: 

I am facing the same problem with my method interceptor unable to read the annotations definition on the adviced method. Has anyone solved this yet?

Did you try Bozho's answer, that made it for me.
hubertg
A: 

Even after changing the retention policy like Bozho mentioned this call to get annotation returns null:

targetMethod.getAnnotation(Restricted.class);

What I found is you have to bind the annotation. Given the interface is declared like this:

 @Retention(RetentionPolicy.RUNTIME)
 public @interface Restricted {
     String[] allowedRoles();
  }

The advice would need to be declared like this:

       @Before("@annotation( restrictedAnnotation )")
       public Object processRequest(final ProceedingJoinPoint pjp, Restricted restrictedAnnotation) throws Throwable {
                  String[] roles = restrictedAnnotation.allowedRoles();
                  System.out.println("Allowed:" +  roles);
       }

What this does is bind the annotation to the parameter in the method signature, restrictedAnnotation. The part I am not sure about is how it gets the annotation type, it seems to be based on the parameter. And once you have the annotation you can get the values.

Ryan K