2010-04-01 13 views
13

Me gustaría implementar seguridad declarativa con Spring/AOP y anotaciones. Como verá en el siguiente ejemplo de código, tengo las anotaciones restringidas con el parámetro "allowedRoles" para definir quién puede ejecutar un método recomendado.Spring AOP: cómo obtener las anotaciones del método asesorado

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

Ahora, el problema es que en mi consejo que no tienen acceso a las anotaciones definidas:

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); 
     } 

El método anterior siempre devuelve un valor nulo (no hay anotaciones encontradas en absoluto). ¿Hay una solución simple para esto?

He leído algo sobre el uso del agente AspectJ pero preferiría no utilizar este agente.

Respuesta

13

Supongo @Restricted es su anotación. Si ese es el caso, asegúrese de tener:

@Retention(RetentionPolicy.RUNTIME) 

en su definición de anotación. Esto significa que la anotación se conserva en el tiempo de ejecución.

+0

Muchas gracias, esa fue la razón. – hugri

2

¿Por qué no solo usa Spring Security? Es un breve para implementar y usar, realmente no veo el sentido de perder tiempo reinventando la rueda.

+0

Gracias, voy a echarle un vistazo pronto – hugri

4

Incluso después de cambiar la política de retención como Bozho mencionó esta llamada para obtener rendimientos de anotación nulo:

targetMethod.getAnnotation(Restricted.class); 

Lo que he encontrado es que hay que obligar a la anotación. Dada la interfaz se declara como esto:

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

El consejo tendría que ser declarado como esto:

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

Lo que esto hace es obligar a la anotación para el parámetro en la firma del método, restrictedAnnotation. La parte de la que no estoy seguro es cómo obtiene el tipo de anotación, parece basarse en el parámetro. Y una vez que tenga la anotación, puede obtener los valores.

2

Whith primavera AOP si usted tiene una situación como MyManagerImpl implements MyManager el punto de corte se aplica al método interface por lo MethodSignature describe el método definido en MyManager que no tiene ninguna anotación. la única forma que he encontrado para solucionar esto es inspeccionar la clase del objeto jp.getTarget() y recuperar el método correspondiente.

27

Para quien todavía tenga el problema después de cambiando la retención de anotación a Runtime, es posible que tenga el mismo problema que tuve: getMethod() devuelve el método de interfaz en lugar de la clase implementadora. Entonces, si tiene sus anotaciones en la clase, naturalmente, getAnnotations() en el método de interfaz devuelve nulo.

La siguiente solución solucionado este problema:

final String methodName = pjp.getSignature().getName(); 
final MethodSignature methodSignature = (MethodSignature)pjp.getSignature(); 
Method method = methodSignature.getMethod(); 
if (method.getDeclaringClass().isInterface()) { 
    method = pjp.getTarget().getClass().getDeclaredMethod(methodName, method.getParameterTypes());  
} 

y si le gusta, usted tiene la opción de manejar las anotaciones de interfaz aquí también.

Algunos comentarios más disponibles aquí: getting template method instance from ProceedingJoinPoint

Oleg

+0

Hola, muchas gracias del futuro! –

Cuestiones relacionadas