Search code examples
spring-securityaspectjspring-aopaspectj-maven-plugin

Aspectj and spring security aspects - order of advice execution


I'm using spring-security 3.2.4.RELEASE , spring-security-aspects 3.2.4.RELEASE, AspectJ maven plugin version 1.6, Java 7.

I using AspectJ's weaving and not SpringAOP, therefore my aspectj maven plugin looks like this:

           <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.6</version>
                <executions>
                    <execution>                     
                    <goals>
                        <goal>compile</goal>
                        <goal>test-compile</goal>
                    </goals>
                    </execution>
                </executions>
                <configuration>
                    <Xlint>ignore</Xlint>
                    <showWeaveInfo>true</showWeaveInfo>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                    <complianceLevel>${org.aspectj-version}</complianceLevel>
                    <aspectLibraries>
                        <aspectLibrary>
                            <groupId>org.springframework.security</groupId>
                            <artifactId>spring-security-aspects</artifactId>
                        </aspectLibrary>
                    </aspectLibraries>
          </plugin>

I have another aspect that looks like this:

package com.mycompany.fw.app.config;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.DeclarePrecedence;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.security.core.parameters.DefaultSecurityParameterNameDiscoverer;

import com.mycompany.fw.security.Integration;

@Aspect
@DeclarePrecedence("IntegrationAspects*,*")
public class IntegrationAspects {

    ParameterNameDiscoverer parameterNameDiscoverer = new DefaultSecurityParameterNameDiscoverer();

    @Pointcut("(execution(* com.mycompany..*(..))) && @annotation(integrate) ")
    public void integratePointCut(Integration integrate) {

    }

    /**
     * TODO: cache
     * 
     * @param jp
     * @param integrate
     * @throws Throwable
     */
    @Around("integratePointCut(integrate)")
    public Object integrate(final ProceedingJoinPoint pjp, Integration integrate) throws Throwable {
        Object res = pjp.proceed();
        return res;
    }

}

What I need is to put the above (integration aspect) to be the first before any other aspect (including Spring's security aspect) As you can see I tried it with @DeclarePrecedence (I also tried it with declare precedence : IntegrationAspects*,* as well in an .aj file), unfortunately, without success.

Can someone instruct me how to define the aspects invocation order?


Solution

  • The problem is that you do not use the plain aspect name IntegrationAspects in @DeclarePrecedence, but a joker character *. In this case you need to use a fully qualified class name or jokers creating same.

    Does not work:

    @DeclarePrecedence("IntegrationAspects*, *")
    

    Works:

    @DeclarePrecedence("IntegrationAspects, *")
    
    @DeclarePrecedence("com.mycompany.fw.security.Integration.IntegrationAspects, *")
    
    @DeclarePrecedence("com.mycompany.fw.security.Integration.IntegrationAspects*, *")
    
    @DeclarePrecedence("*..IntegrationAspects*, *")
    

    And so forth. By the way, using upper-case package names and plurals in class names looks really ugly.

    I am an AspectJ expert, not a Spring user, so I cannot tell you if declaring precedence will also affect Spring-provided aspects. It might also depend on whether they are implemented using native AspectJ or Spring-AOP (proxy-based "AOP lite").