1

Per the Spring Security 3.2.0 documentation I've created a Spring Security configuration and reference it in getRootConfigClasses:

@Override
protected Class<?>[] getRootConfigClasses() {
    return new Class[]{RootConfiguration.class, SpringSecurityConfig.class};
}

@Override
protected Class<?>[] getServletConfigClasses() {
    return new Class[]{SpringWebConfiguration.class};
}

I can prove that this mostly works as Spring Security forces users to login per my configurataion. The problem is with method security. I've annotated SpringSecurityConfig with @EnableGlobalMethodSecurity like so:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

then annotated a method in my contoller with:

@PreAuthorize("hasAuthority('ROLE_ADMIN')")

with the idea of only allowing those with ROLE_ADMIN access to this controller method. However, those logged in with ROLE_USER and ROLE_ADMIN can call this method, not what is expected.

By modifying my web application initializer to doubly include the Spring Security configuration it starts to work, but I'd like to use method authentication on methods in my root context as well the web context, which I can't seem to make happen:

@Override
protected Class<?>[] getRootConfigClasses() {
    return new Class[]{RootConfiguration.class, SpringSecurityConfig.class};
}

@Override
protected Class<?>[] getServletConfigClasses() {
    return new Class[]{SpringSecurityConfig.class, SpringWebConfiguration.class};
}

Does each context need its own security config? Or should one in the parent context suffice?

Thanks.

Jason
  • 2,233
  • 3
  • 24
  • 27
  • Did you figured it out? I'm facing same problem. I'm (unsuccessfully) trying to split security configuration into 2: the root (parent) context security and a web context (child) security... – pakman May 23 '14 at 16:33
  • No I did not. I moved this specific application to Spring Boot which uses one context, which is fine for my purposes. – Jason May 23 '14 at 20:52
  • https://stackoverflow.com/questions/17444856/using-static-variables-in-spring-annotations/61080418#61080418 Here is one good example – izanaj Apr 18 '23 at 08:27

1 Answers1

2

I finally managed to have a root context, with a child web context and have @Pre and @Post authorization annotations work for controllers.

The trick was to expose the AuthenticationProvider created in the RootContext, which is not exposed by default.

So, my setup is :

@Order(1)
public class SecurityWebAppInitializer extends AbstractSecurityWebApplicationInitializer {}



@Order(2)
public class ApiDispatcherInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] { RootConfiguration.class };
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[] { ApiWebMvcConfig.class };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/*" };
    }
}


@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    // IMPORTANT: to expose it to the WebContext
    @Bean(name = "myAuthenticationManager")
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

}



@Configuration
@EnableWebMvc
@EnableGlobalMethodSecurity(prePostEnabled = true, mode = AdviceMode.PROXY, proxyTargetClass = true) // <-- IMPORTANT to make it work for controllers
@ComponentScan(basePackageClasses = { foo.bar.Package.class }, useDefaultFilters = false, includeFilters = { @Filter(Controller.class) })
public class WebMvcConfig extends WebMvcConfigurerAdapter {

}

Hope this might help someone.

pakman
  • 1,676
  • 3
  • 23
  • 41