Controller protection with @RolesAllowed and @PreAuthorize

My bean hit my head about this for a while. I did everything I could to find a suitable solution and followed a myriad of Stackoverflow examples and solutions.

Firstly, I am using annotation based solution. When I annotate my services, prePostEnabled works, but not when I comment on controllers, it is not. Also, even in my services, jsr250Enabled does not work.

I found many cases closed by moving the annotation from the security config to the MVC configuration, which in my case does not work.

I have a setting that looks like this: https://github.com/spring-projects/spring-security-oauth-javaconfig/tree/master/samples/oauth2-sparklr

But I use Servlet 3.0 and have nothing in my web.xml.

My SecurityInitializer is as follows:

public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer { } 

My MVC initializer is as follows:

 public class MvcWebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return new Class<?>[]{WebSecurityConfig.class, MethodSecurityConfig.class}; } @Override protected Class<?>[] getServletConfigClasses() { return new Class<?>[]{SpringMvcConfig.class}; } @Override protected String[] getServletMappings() { return new String[]{ApiPaths.API + "/*", "/res.jsp"}; } 

My WebSecurity configurator is initialized as follows:

 @Configuration @EnableWebSecurity @ComponentScan(value = {"com.roler.res.**.server"}, excludeFilters = { @Filter(type = FilterType.ASSIGNABLE_TYPE, value = SpringMvcConfig.class), @Filter(type = FilterType.ASSIGNABLE_TYPE, value = MethodSecurityConfig.class), @Filter(type = FilterType.REGEX, pattern = "com.xyz.*.controller.*")}) public class WebSecurityConfig extends WebSecurityConfigurerAdapter { 

And my SpringMvcConfig is initialized as follows:

 @Configuration @EnableWebMvc @ComponentScan(value = "com.xyz.**.controller") public class SpringMvcConfig extends WebMvcConfigurerAdapter { 

If you have any ideas, I'm out of juice, thanks!

+1
spring-mvc spring-security
Nov 18 '14 at 23:52
source share
2 answers

The symptoms you describe make me think about the proxy problem. Annotations work fine at the service level, because services typically implement interfaces, and Spring can easily use the JDK proxy to authorize AOP.

But controllers usually do not implement interfaces. The reason PreAuthorize annotations are more commonly used in the service level. IMHO, you'd better try using authorization based on URL patterns instead of PreAuthorize annotations on the controller. An alternative would be to use class class proxying with CGLIB.

To use PreAuthorize and JSR-250 annotations, you must

  • annotate your Spring security class with:

     @EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true) 
  • if you use Spring AOP with JDK proxies elsewhere in your application, create all controller classes in which you want to use the method security implementation interfaces declaring all protected methods

  • if you use Spring AOP with CGLIB proxies elsewhere in your application, add proxyTargetClass = true to @EnableGlobalMethodSecurity :

     @EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true, proxyTargetClass = true) 
  • if you want to use the CGLIB proxy with Spring version under 3.2, add the CGLIB library to your class path (CGLIB classes are included in Spring 3.2 +)

  • avoid mixing the CGLIB proxy server and the JDK because it is not recommended by the Spring documentation: multiple sections collapse into a single unified auto-proxy creator at runtime, which applies the most powerful proxy settings that any of the sections (usually from different XML bean). This also applies to elements and elements. To be clear: using "proxy-target-class =" true "'on or elements will force the use of a CGLIB proxy for all three of them.

But anyway, my advice is to try to transfer the security of the method to the level of service that AOP usually supports.

+7
Nov 22 '14 at 18:28
source share

Two things I noticed (as mentioned in this thread ):

  • prePostEnabled in annotations to enable Pre / Post annotations
  • use of the CGLib proxy (Serge also said this)

Does your @EnableGlobalMethodSecurity have these two attributes?

 @EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true) 
0
Nov 23 '14 at 18:14
source share



All Articles