@Secured批注在具有Autoproxy的AspectJ模式下不起作用 [英] @Secured annotations not working in AspectJ Mode with Autoproxy
问题描述
我正试图让我的Spring MVC应用程序与Spring @Secured批注和AspectJ自动代理功能配合使用,但是它似乎并不能代理或识别我的@Secured批注.我有一个像这样的控制器:
I'm trying to get my Spring MVC app to play nice with Spring @Secured annotations and AspectJ auto-proxying but it doesn't seem to be proxying or recognising my @Secured annotations. I have a controller like this:
@Controller
@RequestMapping("/")
public class ApplicationController {
private ApplicationFactory applicationFactory;
@Inject
public ApplicationController(ApplicationFactory applicationFactory) {
super();
this.applicationFactory = applicationFactory;
}
@Secured("ROLE_USER")
@ResponseBody
@RequestMapping(method = GET)
public Application getApplicationInfo() {
return applicationFactory.buildApplication(this);
}
}
还有一个看起来像这样的spring security XML:
And a spring security XML that looks something like this:
代码:
<security:global-method-security secured-annotations="enabled" mode="aspectj" proxy-target-class="true" />
<security:http auto-config="true" use-expressions="true">
<security:http-basic/>
</security:http>
以上内容是由无XML的Spring @Configuration组件加载的,如下所示:
The above is being loaded by a no-xml Spring @Configuration component like this:
@Configuration
@ComponentScan(basePackages = {"com.example"})
@EnableWebMvc
@ImportResource("classpath:security.xml")
public class ApplicationConfiguration extends WebMvcConfigurerAdapter {
}
依次使用Servlet 3.0 WebApplicationInitializer加载:
Which in turn is loaded using a Servlet 3.0 WebApplicationInitializer:
public class SpringMvcInitializer implements WebApplicationInitializer {
private final AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
public void onStartup(ServletContext servletContext) throws ServletException {
context.register(ApplicationConfiguration.class);
servletContext.addListener(new ContextLoaderListener(context));
servletContext.addListener(new Log4jConfigListener());
final DelegatingFilterProxy proxy = new DelegatingFilterProxy("springSecurityFilterChain", context);
FilterRegistration.Dynamic filter = servletContext.addFilter("securityFilter", proxy);
filter.addMappingForUrlPatterns(EnumSet.of(REQUEST), false, "/*");
final DispatcherServlet servlet = new DispatcherServlet(context);
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", servlet);
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/*");
}
}
但是,Spring Security不会检测到注释,并且我仍然能够在未经授权的情况下使用上面的安全端点.根据 Spring Security FAQ ,这可能是因为<global-method-security>
元素是在错误的应用程序上下文中加载的,但是我不知道如何使用上面的no-xml Spring配置来确保这一点.
However, Spring Security isn't detecting the annotation and I'm still able the secured endpoint above without being authorised. According to the Spring Security FAQ, this maybe because the <global-method-security>
element is being loaded in the wrong application context, but I don't know how to ensure this using the above no-xml Spring configuration.
我错过了什么吗?我尝试将@EnableAspectJAutoProxy(proxyTargetClass = true)添加到我的应用程序配置中,但这也无济于事.无论如何,是否需要运行时编织,还是我必须使用编译时编织为我的应用程序启用基于注释的安全性?
Am I missing something? I tried adding the @EnableAspectJAutoProxy(proxyTargetClass = true) to my application configuration but that didn't help either. Is there anyway to have run time weaving or will I have to use compile time weaving to enable annotation-based security for my application?
推荐答案
将AOP与Spring结合使用时,可以在两种AOP实现之间进行选择:
When using AOP with Spring you can choose between two implementations of AOP:
-
Spring AOP实现不需要编织,但仅适用于Spring管理的并且具有 AspectJ AOP实现可用于所有对象,并且不受Spring AOP的限制,但需要编译时或加载时编织
AspectJ AOP implementation can work for all objects and doesn't have limitations of Spring AOP, but requires compile-time or load-time weaving
mode="aspectj"
告诉Spring使用AspectJ进行AOP实现,因此,如果不进行具体编织,安全性方面将无法正常工作.mode="aspectj"
tells Spring to use AspectJ for AOP implementation, therefore security aspect won't work without weaving in your case.术语"AspectJ自动代理"与将AspectJ用作AOP实现无关-它是一项功能,允许您在Spring AOP中使用AspectJ API(而不是实现).
The term "AspectJ auto-proxying" has nothing to do with using AspectJ as AOP implementation - it's a feature that allows you to use AspectJ API (rather than implementation) with Spring AOP.
因此,在您的情况下,您可以使用Spring AOP实现,因为控制器是Spring bean,因此应删除
mode="aspectj"
.另外请注意,您的控制器应具有无参数的构造函数-这是Spring AOP的局限性之一.So, in your case you can use Spring AOP implementation, because controller is a Spring bean, therefore you should remove
mode="aspectj"
. Also note that your controller should have no-arguments constructor - it's one of the limitations of Spring AOP.这篇关于@Secured批注在具有Autoproxy的AspectJ模式下不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!