@Secured 注释在使用 Autoproxy 的 AspectJ 模式下不起作用 [英] @Secured annotations not working in AspectJ Mode with Autoproxy

查看:24
本文介绍了@Secured 注释在使用 Autoproxy 的 AspectJ 模式下不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试让我的 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 安全 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?

推荐答案

在 Spring 中使用 AOP 时,您可以在两种 AOP 实现之间进行选择:

When using AOP with Spring you can choose between two implementations of AOP:

  • Spring AOP 实现不需要织入,但只适用于 Spring 管理的 bean,并且有 一些限制

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 实现无关 - 它是一项允许您将 AspectJ API(而不是实现)与 Spring AOP 一起使用的功能.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆