Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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);
    }

}

And a spring security XML that looks something like this:

Code:

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

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 {

}

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("/*");
    }

}

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.

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
186 views
Welcome To Ask or Share your Answers For Others

1 Answer

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

  • Spring AOP implementation doesn't require weaving, but it's only applicable to beans managed by Spring and have some limitations

  • 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" tells Spring to use AspectJ for AOP implementation, therefore security aspect won't work without weaving in your case.

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.

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...