How avoid the certificate validation in spring-boot-admin?
Asked Answered
E

3

5

In what way can I avoid certificate validation in spring-boot-admin?

Link error image: https://ibb.co/fkZu8y

I configure the RestTemplate for avoid the certificate in a class, but I do not know how to send it, I guess it must be in the client, the spring-boot-admin-starter-client works automatically.

This is the code for avoid the certificate validation.

public class SSLUtil {

    public RestTemplate getRestTemplate() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
        TrustStrategy acceptingTrustStrategy = new TrustStrategy() {
            @Override
            public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
                return true;
            }
        };
        SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy)
                .build();
        SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());
        CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(csf).build();
        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
        requestFactory.setHttpClient(httpClient);
        RestTemplate restTemplate = new RestTemplate(requestFactory);
        return restTemplate;
    }

}

Application.properties

spring.application.name=Admin-Application

server.port=1111

security.user.name=admin

security.user.password=admin123

@Configuration
    public static class SecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            // Page with login form is served as /login.html and does a POST on
            // /login
            http.formLogin().loginPage("/login.html").loginProcessingUrl("/login").permitAll();
            // The UI does a POST on /logout on logout
            http.logout().logoutUrl("/logout");
            // The ui currently doesn't support csrf
            http.csrf().disable().authorizeRequests()

                    // Requests for the login page and the static assets are
                    // allowed
                    // http.authorizeRequests()
                    .antMatchers("/login.html", "/**/*.css", "/img/**", "/third-party/**").permitAll();
            // ... and any other request needs to be authorized
            http.authorizeRequests().antMatchers("/**").authenticated();

            // Enable so that the clients can authenticate via HTTP basic for
            // registering
            http.httpBasic();
        }
    }
Exhaust answered 13/5, 2018 at 20:56 Comment(0)
W
4

I'm using Spring Boot Admin 2.1.3 together with Eureka.

It seems SBA has moved from RestTemplate to WebClient. So I create a WebClient which has a SSLContext with a trust manager set to InsecureTrustManagerFactory, that trusts everything. Then I use this webclient and instantiate SBA's InstanceWebClient. Not sure if there is an easier approach, but this worked for me.

import de.codecentric.boot.admin.server.config.AdminServerProperties;
import de.codecentric.boot.admin.server.web.client.HttpHeadersProvider;
import de.codecentric.boot.admin.server.web.client.InstanceExchangeFilterFunction;
import de.codecentric.boot.admin.server.web.client.InstanceWebClient;
import io.netty.channel.ChannelOption;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import io.netty.handler.timeout.ReadTimeoutHandler;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.netty.ConnectionObserver;
import reactor.netty.http.client.HttpClient;

import javax.net.ssl.SSLException;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Configuration
@EnableConfigurationProperties(AdminServerProperties.class)
public class SslConfiguration {

    private final AdminServerProperties adminServerProperties;

    public SslConfiguration(AdminServerProperties adminServerProperties) {
        this.adminServerProperties = adminServerProperties;
    }


    @Bean
    public InstanceWebClient instanceWebClient(HttpHeadersProvider httpHeadersProvider,
                                        ObjectProvider<List<InstanceExchangeFilterFunction>> filtersProvider) throws SSLException {
        List<InstanceExchangeFilterFunction> additionalFilters = filtersProvider.getIfAvailable(Collections::emptyList);
        return InstanceWebClient.builder()
                .defaultRetries(adminServerProperties.getMonitor().getDefaultRetries())
                .retries(adminServerProperties.getMonitor().getRetries())
                .httpHeadersProvider(httpHeadersProvider)
                .webClient(getWebClient())
                .filters(filters -> filters.addAll(additionalFilters))
                .build();
    }

    private WebClient getWebClient() throws SSLException {
        SslContext sslContext = SslContextBuilder
                .forClient()
                .trustManager(InsecureTrustManagerFactory.INSTANCE)
                .build();

        HttpClient httpClient = HttpClient.create()
                .compress(true)
                .secure(t -> t.sslContext(sslContext))
                .tcpConfiguration(tcp -> tcp.bootstrap(bootstrap -> bootstrap.option(
                        ChannelOption.CONNECT_TIMEOUT_MILLIS,
                        (int) adminServerProperties.getMonitor().getConnectTimeout().toMillis()
                )).observe((connection, newState) -> {
                    if (ConnectionObserver.State.CONNECTED.equals(newState)) {
                        connection.addHandlerLast(new ReadTimeoutHandler(adminServerProperties.getMonitor().getReadTimeout().toMillis(),
                                TimeUnit.MILLISECONDS
                        ));
                    }
                }));
        ReactorClientHttpConnector reactorClientHttpConnector = new ReactorClientHttpConnector(httpClient);

        return WebClient.builder().clientConnector(reactorClientHttpConnector).build();
    }
}
Willson answered 20/3, 2019 at 10:30 Comment(3)
Hey @Willson I need to also override SBA's instance webclient to by pass ssl validation as I'm having a tough time connecting to clients on ssl. However the code you posted doesn't work for SBA server Version 2.6.2. Any chance you can post an update? Thank you so much!Schapira
@Schapira seems to change a lot (why I posted the version in original answer). Unfortunately I don't work with SBA anymore so I don't have any updates to share.Willson
Thanks for the response @Willson I actually found a solution at least for the admin server side connecting back to the clients which is right from their documentation (SBA Admin version 2.6.2): codecentric.github.io/spring-boot-admin/current/… For the client side, I'm using a custom rest template but the SBA client doesn't seem to be picking it up even though I see that the SBA client code is using the BlockingRegistrationClient i.e) RestTemplateSchapira
S
2

To disable the SBA Admin server from validating SSL certs from the clients it tries to connect to, you can use the following: For SBA version 2.6.2 it is more or less outlined right from their documentation: https://codecentric.github.io/spring-boot-admin/current/#_using_mutual_tls

Here is the complete configuration overriding bean:

package com.markham.mkmappadmin.config;

import javax.net.ssl.SSLException;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.reactive.ClientHttpConnector;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;

import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import reactor.netty.http.client.HttpClient;

/**
 * Custom http client class which overrides Spring Boot Admin's server default client.<br>
 * The custom client will bypass any SSL Validation by configuring an instance of
 *  {@link InsecureTrustManagerFactory}
 * @author Hanif Rajabali
 * @see <a href="https://codecentric.github.io/spring-boot-admin/current/#_using_mutual_tls">Spring Boot Admin 2.6.2 Using Mutual TLS</a>
 */
@Configuration
public class CustomHttpClientConfig {

    @Bean
    public ClientHttpConnector customHttpClient() throws SSLException {
        SslContext sslContext = SslContextBuilder
              .forClient()
              .trustManager(InsecureTrustManagerFactory.INSTANCE)
              .build();
        HttpClient httpClient = HttpClient.create().secure(
            ssl -> ssl.sslContext(sslContext)
        );
        return new ReactorClientHttpConnector(httpClient);
    }

}

What I still haven't figured out is how to disable it from the SBA client. I have a custom RestTemplate Config defined below, but the SBA client doesn't seem to be picking it up even though I see that the SBA client code is using the BlockingRegistrationClient i.e) RestTemplate

package com.markham.mkmemailerws.config;

import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

/**
 * Need to explicitly build Spring Boot's auto configured
 * {@link #restTemplate(RestTemplateBuilder)}
 *
 * @author Hanif Rajabali
 *
 */
@Configuration
public class RestTemplateConfig {

//   @Bean
//   public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
//      return restTemplateBuilder.build();
//   }


    /**
     * The following will bypass ssl validation altogether. Not ideal.
     */
    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder)
            throws NoSuchAlgorithmException, KeyManagementException {

        TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return new X509Certificate[0];
            }

            public void checkClientTrusted(java.security.cert.X509Certificate[] certs, String authType) {
            }

            public void checkServerTrusted(java.security.cert.X509Certificate[] certs, String authType) {
            }
        } };
        SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
        CloseableHttpClient httpClient = HttpClients.custom().setSSLContext(sslContext)
                .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE).build();
        HttpComponentsClientHttpRequestFactory customRequestFactory = new HttpComponentsClientHttpRequestFactory();
        customRequestFactory.setHttpClient(httpClient);
        return builder.requestFactory(() -> customRequestFactory).build();
    }
}
Schapira answered 2/3, 2022 at 21:15 Comment(1)
It works also for spring-boot-admin-server 3.2.2Tearoom
H
0

Try http.csrf().disable().authorizeRequests() Above code will disable csrf token. Below is my code for OAuth where I disabled csrf to reduce complexity.

@RestController
@EnableOAuth2Sso
@EnableResourceServer
@SpringBootApplication
public class SpringBootWebApplication extends WebSecurityConfigurerAdapter {
            @Override
            protected void configure(HttpSecurity http) throws Exception {

                http.csrf().disable().authorizeRequests()

                        .antMatchers("/api/**", "/dashboard", "/welcome","/about").authenticated().antMatchers("/**").permitAll()
                        .anyRequest().authenticated().and().logout().logoutSuccessUrl("/").permitAll();

            }
Heaviness answered 14/5, 2018 at 3:42 Comment(1)
In my SecurityConfig class I already disable the csrf, the error in the spring-boot-admin is the same :(Exhaust

© 2022 - 2024 — McMap. All rights reserved.