Pregunta

Tengo una clase de servicio implementado en Java 6 / Spring 3 que necesita una anotación para restringir el acceso de papel.

he definido un llamado RequiredPermission anotación que tiene como un atributo de valor o más valores de una enumeración llamado OperationType:

public @interface RequiredPermission {

/**
 * One or more {@link OperationType}s that map to the permissions required
 * to execute this method.
 * 
 * @return
 */
OperationType[] value();}

public enum OperationType {
      TYPE1,
      TYPE2;
}

package com.mycompany.myservice;
public interface MyService{
   @RequiredPermission(OperationType.TYPE1)
   void myMethod( MyParameterObject obj );
}

package com.mycompany.myserviceimpl;
public class MyServiceImpl implements MyService{
   public myMethod( MyParameterObject obj ){
       // do stuff here
   }
}

También tiene la siguiente definición del aspecto:

/**
 * Security advice around methods that are annotated with
 * {@link RequiredPermission}.
 * 
 * @param pjp
 * @param param
 * @param requiredPermission
 * @return
 * @throws Throwable
 */
@Around(value = "execution(public *"
        + " com.mycompany.myserviceimpl.*(..))"
        + " && args(param)" + // parameter object
        " && @annotation( requiredPermission )" // permission annotation

, argNames = "param,requiredPermission")
public Object processRequest(final ProceedingJoinPoint pjp,
        final MyParameterObject param,
        final RequiredPermission requiredPermission) throws Throwable {
    if(userService.userHasRoles(param.getUsername(),requiredPermission.values()){
        return pjp.proceed();
    }else{
        throw new SorryButYouAreNotAllowedToDoThatException(
            param.getUsername(),requiredPermission.value());
    }
}

El objeto de parámetro contiene un nombre de usuario y quiero buscar la función necesaria para el usuario antes de permitir el acceso al método.

Cuando pongo la anotación en el método de MyServiceImpl, todo funciona bien, el punto de corte se corresponde y las patadas de aspecto en. Sin embargo, creo que la anotación es parte del contrato de servicio y debe ser publicada con la interfaz en una paquete de API. Y, obviamente, no me gustaría poner la anotación tanto en la definición e implementación del servicio (SECO).

Sé que hay casos en Spring AOP donde aspectos son provocados por anotaciones uno métodos de interfaz (por ejemplo transaccional). ¿Hay una sintaxis especial aquí, o es imposible salir simplemente de la caja.

PS: No he publicado mi config primavera, ya que parece estar funcionando muy bien. Y no, esos son ni mis nombres de clase ni del método original.

PPS: En realidad, esta es la parte pertinente de mi config primavera:

<aop:aspectj-autoproxy proxy-target-class="false" />

<bean class="com.mycompany.aspect.MyAspect">
    <property name="userService" ref="userService" />
</bean>
¿Fue útil?

Solución

Si entiendo a corregir, usted quiere un punto de corte que encuentra todos los métodos en las clases que se extiende MyService y se anota y con los argumentos preferidos.

Propongo que reemplace:

execution(public * com.mycompany.myserviceimpl.*(..))

por:

execution(public * com.mycompany.myservice.MyService+.*(..))

El signo más se utiliza si quieres un joinpoint para que coincida con la clase MyService o una clase que se extiende a él.

Espero que ayude!

Otros consejos

Espen, el código funciona sólo para una clase:

execution(public * com.mycompany.myservice.MyService+.*(..))

pero lo que si quiero este comportamiento para todos los servicios en com.mycompany.services *. ** paquete?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top