Frage

Ich habe eine Service-Klasse implementiert in Java 6 / Feder 3, die eine Anmerkung Zugang zu beschränken, indem Rolle muss.

Ich habe eine Anmerkung genannt RequiredPermission definiert, die als Wert Attribut einer oder mehr Werte aus einer Enum genannt Operation hat:

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

ich auch die folgenden Aspekt Definition haben:

/**
 * 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());
    }
}

Der Parameter-Objekt enthält einen Benutzernamen und ich möchte die erforderliche Rolle für den Benutzer suchen, bevor der Zugriff auf das Verfahren zu ermöglichen.

Wenn ich die Anmerkung über die Methode in MyServiceImpl setzen, alles funktioniert gut, die pointcut abgestimmt ist und die Seiten Kicks in. Ich glaube jedoch, die Anmerkung Teil des Servicevertrages und soll mit der Schnittstelle in einem veröffentlicht separates API-Paket. Und natürlich würde ich nicht wie die Anmerkung auf beide Service-Definition zu setzen und Implementierung (DRY).

Ich weiß, dass es Fälle gibt, in Spring AOP wo Aspekte von Annotationen einer Interface-Methoden ausgelöst werden (z Transactional). Gibt es eine spezielle Syntax hier oder ist es einfach nur unmöglich, aus dem Kasten heraus.

PS: Ich habe nicht meine Feder Config geschrieben, da es einfach gut zu sein scheint zu funktionieren. Und nein, die sind weder meine ursprüngliche Klasse noch Methodennamen.

PPS: Eigentlich ist hier der relevante Teil meiner Feder config:

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

<bean class="com.mycompany.aspect.MyAspect">
    <property name="userService" ref="userService" />
</bean>
War es hilfreich?

Lösung

Wenn ich verstehe, Sie korrigieren, möchten Sie eine pointcut, das alle Methoden in Klassen findet, die MyService erstreckt und mit Anmerkungen versehen und mit den bevorzugten Argumente.

Ich schlage vor, dass Sie ersetzen:

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

mit:

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

Das Pluszeichen wird verwendet, wenn Sie ein joinpoint wollen die MyService Klasse oder eine Klasse entsprechen, die sie erweitert.

Ich hoffe, es hilft!

Andere Tipps

Espen, Ihr Code funktioniert nur für eine Klasse:

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

aber was, wenn ich will dieses Verhalten für alle Dienste in * com.mycompany.services. ** Paket?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top