Pergunta

The Spring Boot Actuator Endpoints are by default protected by basic http security.

Can this be changed to use Spring Security? I've setup Spring Security successfully and use this to protect my other pages.

I tried security.basic.enabled: false and adding .antMatchers("/manage/**").hasRole("ADMIN") in my authorize requests (note I'm using a different url as root for the endpoints) but this didn't help. I keep getting a basic http auth log, which does not users configured in the AuthenticationManager.

Any idea?

EDIT - providing more details -

My Application.java looks like:

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application extends WebMvcConfigurerAdapter {


    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/app").setViewName("app/index");
        registry.addViewController("/app/login").setViewName("app/login");
    }

    @Bean
    public ApplicationSecurity applicationSecurity() {
        return new ApplicationSecurity();
    }

    @Order(Ordered.LOWEST_PRECEDENCE - 8)
    protected static class ApplicationSecurity extends WebSecurityConfigurerAdapter {

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            // @formatter:off
            auth.inMemoryAuthentication()
                .withUser("test1")
                    .password("test1pw")
                    .roles("USER", "ADMIN")
                    .and()
                .withUser("test2")
                    .password("test2pw")
                    .roles("USER");
            // @formatter:on
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            // @formatter:off
            http
                .csrf()
                    .disable()
                .authorizeRequests()
                    .antMatchers("/app/login").permitAll()
                    .antMatchers("/app/**").hasRole("USER")
                    .antMatchers("/manage/**").hasRole("ADMIN")
                    .and()
                .formLogin()
                    .loginPage("/app/login")
                    .failureUrl("/app/login?error")
                    .defaultSuccessUrl("/app")
                    .permitAll()
                    .and()
                .logout()
                    .logoutUrl("/app/logout")
                    .logoutSuccessUrl("/app/login?logout");
            // @formatter:on
        }

        @Override
        public void configure(WebSecurity web) throws Exception {
            // @formatter:off
            web
                .ignoring()
                    .antMatchers("/assets/**");
            // @formatter:on
        }
    }
}

In my application.yml I also have:

management:
  context-path: /management

Note that is setup is the same as you the guide you mentioned.

Now what I would expect - or like to configure - is that the /manage endpoints like health, mappings etc would be protected with users from the customized AuthenticationManager.

I also tried to add management.security.enabled=falseand this indeed switches off authentication for e.g. /manage/mappings. The problematic thing however is that I explicitly told Spring Security to protect these urls's via:

@Override
protected void configure(HttpSecurity http) throws Exception {
    // @formatter:off
    http
        .authorizeRequests()
            .antMatchers("/app/login").permitAll()
            .antMatchers("/app/**").hasRole("USER")
            .antMatchers("/manage/**").hasRole("ADMIN")

but this does not work. Note other authorize matchers do work. I wonder if has something to do within timing/order. I copied @Order(Ordered.LOWEST_PRECEDENCE - 8) from the sample but I don't know why - 8 is used.

To delve a little bit deeper I've also run the sample (https://github.com/spring-projects/spring-boot/blob/master/spring-boot-samples/spring-boot-sample-web-method-security) myself and I see the same behaviour in the sample application. The management security is seems completely independent of the user and admin users configured in the sample's in memory authentication.

Foi útil?

Solução

Can this be changed to use Spring Security?

It is Spring Security (what else did you think we'd use?). If you just want to keep the default security rules and customize the AuthenticationManager it should just work if you use the AuthenticationManagerBuilder as recommended by the Spring Security team. The secure method sample has the behavior you are looking for, so you can copy the configuration pattern from there. The key thing, if you want to replace the Boot default authentication strategy, is to get the AuthenticationManager configured in a GlobalAuthenticationConfigurerAdapter like in the sample.

You can switch off management security with management.security.enabled=false (assuming Spring Security is on the classpath). It is mentioned in the user guide, but feel free to propose clarifications.

Outras dicas

I would say that sometimes it's easier to exclude autoconfiguration of Spring Boot component and make configuration from scratch if you have very specific case. In this case you could use:

@EnableAutoConfiguration(exclude = {SecurityAutoConfiguration.class, ManagementWebSecurityAutoConfiguration.class})

Or just ManagementWebSecurityConfiguration.java if you want to keep the rest of Boot Security configuration. And then you could use something like that:

@Configuration
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfiguration {

@Configuration
@Order(Ordered.HIGHEST_PRECEDENCE)
protected static class AuthenticationSecurity extends GlobalAuthenticationConfigurerAdapter {

    private final SecurityProperties securityProperties;

    @Autowired
    AuthenticationSecurity(SecurityProperties securityProperties) {
        this.securityProperties = securityProperties;
    }

    @Override
    public void init(AuthenticationManagerBuilder auth) throws Exception {
        // configuration
    }
}

@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
protected static class ApplicationSecurity extends WebSecurityConfigurerAdapter {

    private SecurityProperties security;

    @Autowired
    protected ApplicationSecurity(SecurityProperties security) {
        this.security = security;
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // you configuration
    }


}

}

As you can see I have reused the SecurityProperties in this case in order to avoid make my own.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top