Aspect not implemented in Spring

I am encoding a website that will be almost completely protected by login (I use Spring Security for it). There are certain pages that are not protected, though (home page, login page, registration page, forgotten password page ...), and I'm trying to achieve:

  • If the user does not register when accessing these unprotected pages, usually show them
  • If the user has already registered, redirect (or on the page specified in the redirectTo annotation element)

Of course, I want this not to be specified in every controller method:

 if(loggedIn()) { // Redirect } else { // Return the view } 

And for this reason, I would like to use AOP.

I created the @NonSecured annotation and I encoded the following aspect:

 @Aspect public class LoggedInRedirectAspect { @Autowired private UserService userService; @Around("execution(@my.package.annotation.NonSecured * *(..))") public void redirect(ProceedingJoinPoint point) throws Throwable { System.out.println("Test"); point.proceed(); } } 

An example of an annotated method:

 @Controller @RequestMapping("/") public class HomeController { @NonSecured(redirectTo = "my-profile") @RequestMapping(method = RequestMethod.GET) public String index(Model model, HttpServletRequest request) throws Exception { // Show home page } } 

applicationContext.xml important bits:

 <context:annotation-config /> <context:component-scan base-package="my.package" /> <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" /> <bean id="loggedInRedirectAspect" class="my.package.aspect.LoggedInRedirectAspect" /> <aop:aspectj-autoproxy proxy-target-class="true"> <aop:include name="loggedInRedirectAspect" /> </aop:aspectj-autoproxy> 

The problem is that the redirect(...) method in the aspect is never called. Aspects generally work fine, in fact the following method will be called in the aspect: The next call is called, but not called for controller methods.

 @Around("execution(* *(..))") public void redirect(ProceedingJoinPoint point) throws Throwable { point.proceed(); } 

Am I doing something wrong in my pointcut?

Thanks.

Update: The last snippet in this question is called, but still not called for controller methods.

+2
source share
3 answers

@satoshi, I think the problem you are facing is that you are using Spring -AOP and can only create AOP proxies for beans with interfaces, and in your case the controllers do not have an interface.

The fix could be to use compile time / load time using AspectJ and not use Spring AOP OR to have cglib banks in the classpath and force the creation of a cglib proxy:

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

Update: You can compile temporary weaving using the maven plugin, the showWeaveInfo configuration will show which class was woven:

 <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>aspectj-maven-plugin</artifactId> <version>1.0</version> <dependencies> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.6.10</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjtools</artifactId> <version>1.6.10</version> </dependency> </dependencies> <executions> <execution> <goals> <goal>compile</goal> <goal>test-compile</goal> </goals> </execution> </executions> <configuration> <outxml>true</outxml> <verbose>true</verbose> <showWeaveInfo>true</showWeaveInfo> <aspectLibraries> <aspectLibrary> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> </aspectLibrary> </aspectLibraries> <source>1.6</source> <target>1.6</target> </configuration> </plugin> 
+6
source

I usually use an interceptor, not an aspect for this purpose. For example, create a RequestInitializeInterceptor that will validate the security principal and redirect accordingly. Aspects are an excess of this work. The interceptor will act as the front controller for each request to specific controllers and decide whether it is allowed to transmit the request or not.

  public class RequestInitializeInterceptor extends HandlerInterceptorAdapter { // Obtain a suitable logger. private static Log logger = LogFactory .getLog(RequestInitializeInterceptor.class); /** * In this case intercept the request BEFORE it reaches the controller */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { try { logger.info("Intercepting: " + request.getRequestURI()); // Your logic to redirect accordingly if (userAuthenticated) { response.sendRedirect(URL); return false; } return true; } catch (SystemException e) { logger.info("request update failed"); return false; } } } 

Hope this helps.

0
source

What worked for me, check the following points:

  • aspectjweaver.jar is on the class path (version 1.6.8 or later)
  • An aspect class is annotated with both @Aspect and @Component
  • You have enabled spring aspectJ-auto-proxy

Java configuration:

 @Configuration @ComponentScan("io.mc.springaspects") @EnableAspectJAutoProxy public class SpringConfiguration { } 

Format:

 @Aspect @Component public class AnnotationAspect { ... } 

Maven:

 <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.9</version> </dependency> 
0
source

Source: https://habr.com/ru/post/1207327/


All Articles