Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Global method security in Spring Boot

I'm having some issues when trying to enable the global method security in a Spring Boot application. More or less I've this configuration:

@ComponentScan
@Configuration
@EnableAutoConfiguration
@EnableConfigurationProperties
public class Main extends SpringBootServletInitializer {

    public static void main(String[] args) throws Exception {
        SpringApplication app = new SpringApplication(Main.class);
        app.setShowBanner(false);
        ApplicationContext context = app.run(args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Main.class);
    }
}

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true, proxyTargetClass = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        ...
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        ...
    }
}

@Controller
public class SampleController {

    @RequestMapping("/api/hello")
    @ResponseBody
    String hello() {
        return "Hello!";
    }

    @Secured(SecurityGrant.WRITE_PROJECT)
    @RequestMapping("/api/bye")
    @ResponseBody
    String bye() {
        return "Bye!";
    }
}

The @Secure annotations are working OK at services, but not in controllers, so as I read here (http://docs.spring.io/spring-security/site/faq/faq.html#faq-method-security-in-web-context) I think is because method security is only configured in the root application context and not in the one for the servlet. However, I can't find the way to set this via Java Configuration, instead of using a web.xml file. Any ideas?

Update:

As pointed in the comments, methods should be public to be proxied.

like image 642
Franco Gotusso Avatar asked Feb 10 '14 10:02

Franco Gotusso


People also ask

What is global method security?

The global method security functionality is disabled by default. To enable it, you use the @EnableGlobalMethodSecurity annotation over the configuration class of your application. You can apply authorization rules that the application checks before the call to a method.

What is method Security in spring boot?

Method-level security is implemented by placing the @PreAuthorize annotation on controller methods (actually one of a set of annotations available, but the most commonly used). This annotation contains a Spring Expression Language (SpEL) snippet that is assessed to determine if the request should be authenticated.

What's the difference between @secured and @PreAuthorize in Spring Security?

The real difference is that @PreAuthorize can work with Spring Expression Language (SpEL). You can: Access methods and properties of SecurityExpressionRoot . (Advanced feature) Add your own methods (override MethodSecurityExpressionHandler and set it as <global-method-security><expression-handler ... /></...> ).

What is the use of @PreAuthorize annotation?

The @PreAuthorize annotation checks the given expression before entering the method, whereas the @PostAuthorize annotation verifies it after the execution of the method and could alter the result.


2 Answers

The controller methods need to be public in order to be proxied for @Secured. Just doing that should fix it.

like image 199
Dave Syer Avatar answered Sep 26 '22 01:09

Dave Syer


In XML you would have to define a second global-method-security in the servlet-context.xml file. This is because there are two contexts, the root context and the web context and security needs to be configured in each separately.

In Java config, try to create a separate web configuration class, and mark it with @EnableWebMvc:

@Configuration
@EnableWebMvc
@EnableGlobalMethodSecurity(securedEnabled = true, proxyTargetClass = true)
public class WebConfig {
    ...
}
like image 21
Angular University Avatar answered Sep 25 '22 01:09

Angular University