I’m coding a website that will be almost fully protected by login (I’m using Spring Security for it). There are certain pages that are not protected, though (home page, login page, registration page, forgotten password page, …) and what I’m trying to achieve is:
- If the user is not logged in when accessing these non-secured pages,
show them normally - If the user is already logged in, redirect to the
home page (or to the page specified in theredirectToannotation element)
Of course I want to avoid to put this in every single controller method:
if(loggedIn())
{
// Redirect
}
else
{
// Return the view
}
And for this reason I would like to use AOP.
I created the Annotation @NonSecured and I coded 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();
}
}
Example 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 method redirect(...) in the aspect never gets called. Aspects in general are working fine, in fact the following method in the aspect will get called: The following advice gets called but doesn’t get called for the controller methods.
@Around("execution(* *(..))")
public void redirect(ProceedingJoinPoint point) throws Throwable
{
point.proceed();
}
Am I doing something wrong in my pointcut?
Thank you.
Update: the last snippet in this question gets called but still doesn’t get called for the controller methods.
@satoshi, I think the problem that you are having is because you are using Spring-AOP and it can create AOP proxies only 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 weaving using AspectJ and to not use Spring AOP OR to have cglib jars in the classpath and to force cglib based proxy creation :
Update:
Compile time weaving can be done using a maven plugin, the showWeaveInfo configuration will show exactly which of the classes have been weaved: