apines
apines

Reputation: 1262

Spring boot 2 enabling a non-secure /health endpoint

I have a Spring Boot 2 project with client and server authentication, and I'm trying to expose only the /actuator/health endpoint so it won't need any authentication.

My initial WebSecurityConfigurerAdapter was:

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
...
    private void configureWithSsl(@NotNull HttpSecurity http) throws Exception {
        LOG.info("configuring access with ssl");
        http
                .csrf().disable()
                .authorizeRequests()
                .anyRequest().authenticated()
                .and().x509()
                .and().userDetailsService(userDetailsService());
    }
...
}

and application.yaml

server:
  port: 8443
  ssl:
    enabled: true
    key-store: 'paht/to/kestore/keystore.jks'
    key-store-password: 123456
    key-store-type: JKS
    client-auth: need
    trust-store: 'paht/to/truststore/truststore.jks'
    trust-store-type: JKS
    trust-store-password: 123456
    protocol: TLS
    enabled-protocols: TLSv1.2

I've tried: 1. Configuring 'channel' as insecure for the endpoint

    private void configureWithSsl(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .requiresChannel().requestMatchers(EndpointRequest.to("health")).requiresInsecure()
                .and()
                .authorizeRequests()
                .anyRequest().authenticated()
                .and().x509()
                .and().userDetailsService(userDetailsService());
    }
  1. add matchers to the endpoint:
    private void configureWithSsl(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .authorizeRequests()
                .requestMatchers(EndpointRequest.to("health")).permitAll()
                .anyRequest().authenticated()
                .and().x509()
                .and().userDetailsService(userDetailsService());
    }
  1. Add ignore to the endpoint:
@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring().requestMatchers(EndpointRequest.to("health"));
}

I've tried all these combinations, and still I get

curl -k  https://localhost:8443/actuator/health
curl: (35) error:1401E412:SSL routines:CONNECT_CR_FINISHED:sslv3 alert bad certificate
curl http://localhost:8443/actuator/health
Bad Request
This combination of host and port requires TLS.

I want just the health endpoint to be not secured, the rest of the actuator endpoints I do need secured, so configuring management.server.ssl.enabled=false won't solve the problem...

EDIT:

As per @Aritra Paul answer, I've also tried:

http
        .csrf().disable()
        .authorizeRequests()
        .antMatchers( "/actuator/health/**").permitAll()
        .antMatchers( "/**").authenticated()
        .and().x509()
        .and().userDetailsService(userDetailsService());

But I still get the same result.

Upvotes: 6

Views: 9609

Answers (3)

eluinstra
eluinstra

Reputation: 34

I solved it as follows

In SecurityConfig that implements WebSecurityConfigurerAdapter

    @Override
    protected void configure(HttpSecurity http) throws Exception {
    http.regexMatcher("^(?!(/actuator/)).*$")
            .csrf().disable()
            .authorizeRequests()
            .anyRequest()
            .authenticated()
            .and()
            .x509()
            .subjectPrincipalRegex("CN=(.*?)(?:,|$)")
            .userDetailsService(userDetailsService());

and in application.yaml

management:
  server:
    port: 8088
    ssl:
      enabled: false
  endpoint:
    health:
      probes:
        enabled: true
  health:
    livenessState:
      enabled: true
    readinessState:
      enabled: true

Upvotes: 0

Uncle Long Hair
Uncle Long Hair

Reputation: 2959

I had a very similar case where we added X.509 authentication to our endpoints but wanted to keep the Spring actuator endpoints authentication-free.

With Spring 2.2.3 it is possible to configure your server with ssl as you have done, but disable ssl in your management config (which is used to configure the actuator endpoints) like this:

management:
  server:
    port: 8080
    ssl:
      enabled: false

This simple combination allowed us to hit the actuator endpoints with no auth on port 8080, while we hit the other endpoints with ssl on port 8443.

Upvotes: 5

Aritra Paul
Aritra Paul

Reputation: 874

What I understand that you want to make actuator/health url open for all and all other url is based on role or authorization. If so You can try like bellow

        @Override
        public void configure(HttpSecurity http) throws Exception {
            http
                .authorizeRequests()
                .antMatchers( "/actuator/health/**").permitAll()
                .antMatchers("/other-url/**").hasRole("your role")
                .authenticated();
    }

Upvotes: -1

Related Questions