简体   繁体   中英

Using Spring Security annotation on a method of a controller that extends another class

I have very similar spring-security beans configuation to this example . The @Secured annotation on controller's methods only function properly if it is on a method of a class that does not subclass another class. In other words, this following code does not work (an exception raised during the bean initializtion):

@Controller
@RequestMapping("/systeminfo")
public class SystemInfoController extends AbstractViewableController {

    @RequestMapping(method = RequestMethod.GET, value = "/")
    @Secured("ROLE_USER") // an exception below was raised
    public void view(HttpServletRequest request) {
    }
}

Here is the exception:

org.springframework.beans.factory.BeanCreationException: Error creating bean wit
h name 'systemInfoController' defined in file [C:\workspace\my\my-webapp
\target\classes\my\webapp\controller\SystemInfoController.class]: Initializa
tion of bean failed; nested exception is org.springframework.aop.framework.AopCo
nfigException: Could not generate CGLIB subclass of class [class my.webapp.c
ontroller.SystemInfoController]: Common causes of this problem include using a f
inal class or a non-visible class; nested exception is net.sf.cglib.core.CodeGen
erationException: java.lang.RuntimeException-->RequestMapping annotation cannot
be found on my.webapp.controller.SystemInfoController$$EnhancerByCGLIB$$e99f
e366

So I follow the instruction here and add proxy-target-class="true" to <global-method-security ...> (Not sure if it is related) but the security aspect is still lost. However, if the superclass is removed, then the security get applied properly, ie forward to login page.

Does anyone know what is going on and how to fix the problem when the controller needs to extend another class?

Have you enabled secured-annotations in your security.xml file

<global-method-security secured-annotations="enabled" />

Moreover, these annotations only work for Spring beans. You need to inject these beans rather than just creating normal instances. Try using Spring Dependency Injection.

This is highly probably a bug in spring bean factory, spring annotation scanner or the the generation of subclass using CGLIB. Spring should not scan the annotation on the subclasses that are generated by CGLIB directly since they are lost. It should scan its target class. In this case, it tried to scan @ResquestMapping on my.webapp.controller.SystemInfoController$$EnhancerByCGLIB$$e99fe366 .

However, since the whole thing works if SystemInfoController doesn't extend an abstrat class. It indicates that the annotation may be lost only when the controller is a subclass which suggests that this may be a bug in generating proxy subclass or a limitation of CGLIB.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM