toddcscar
toddcscar

Reputation: 1225

How to create a spring boot app with ssl.enable=true and a non-secure "/health" end point

Is it possible to configure spring boot application ( Jetty ) to have at least one non-secure (non https) endpoint for a load balancer to perform health checks but have all other requests be forced to be secure?

When setting the property:

server.ssl.enabled=true

requests for all ports (both regular port and management/actuator port) are forced to be https.

Secure requests URLS must have the server name in the URL match the certificate configured. A load balancer or container manager like kubernetes would have to access each node in a pool of servers with some kind of host name to server mapping.

Upvotes: 5

Views: 9391

Answers (2)

MarkOfHall
MarkOfHall

Reputation: 3353

The Spring Boot 2 property for disabling the management server TLS is:

management.server.ssl.enabled=false

Upvotes: 0

mjj1409
mjj1409

Reputation: 3174

Initially I thought that the setting management.ssl.enable=false would do the trick but it doesn't appear to be the case. What I wound up doing that worked for me was to add an ssl exclusion rule for just the /health endpoint.

Here is an abridged version of my SecurityConfiguration which is a @Configuration annotated class that extends/implements WebSecurityConfigurerAdapter/WebSecurityConfigurer.

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
            .antMatchers("/secure-path").hasAuthority("SOME_ROLE")
            .anyRequest().authenticated()
            .and()
                .formLogin()
                .loginPage("/login")
                .permitAll()
            .and()
                .logout()
                .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                .logoutSuccessUrl("/login")
                .permitAll()
            .and()
                .exceptionHandling();



    if (securityProperties.isRequireSsl()) {
        //allow health checks to be over http
        http.requiresChannel().antMatchers("/health").requiresInsecure();
        http.requiresChannel().anyRequest().requiresSecure();
    }
}

making use of the requiresInsecure() for the /health endpoint was the key. Note, the order is important, generally in Spring Security more specific rules should come first.

Upvotes: 1

Related Questions