How to disable SSL certificate checking with Spring RestTemplate?

后端 未结 9 1097
余生分开走
余生分开走 2020-11-29 18:11

I am trying to write an integration test where our test launches an embedded HTTPS server using Simple. I created a self-signed certificate using keytool and am able to acce

相关标签:
9条回答
  • 2020-11-29 19:04

    Here's a solution where security checking is disabled (for example, conversing with the localhost) Also, some of the solutions I've seen now contain deprecated methods and such.

    /**
     * @param configFilePath
     * @param ipAddress
     * @param userId
     * @param password
     * @throws MalformedURLException
     */
    public Upgrade(String aConfigFilePath, String ipAddress, String userId, String password) {
        configFilePath = aConfigFilePath;
        baseUri = "https://" + ipAddress + ":" + PORT + "/";
    
        restTemplate = new RestTemplate(createSecureTransport(userId, password, ipAddress, PORT));
        restTemplate.getMessageConverters().add(new MappingJacksonHttpMessageConverter());
        restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
     }
    
    ClientHttpRequestFactory createSecureTransport(String username,
            String password, String host, int port) {
        HostnameVerifier nullHostnameVerifier = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };
        UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(username, password);
        CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        credentialsProvider.setCredentials(
                new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM), credentials);
    
        HttpClient client = HttpClientBuilder.create()
                .setSSLHostnameVerifier(nullHostnameVerifier)
                .setSSLContext(createContext())
                .setDefaultCredentialsProvider(credentialsProvider).build();
    
        HttpComponentsClientHttpRequestFactory requestFactory = 
                new HttpComponentsClientHttpRequestFactory(client);
    
        return requestFactory;
    }
    
    private SSLContext createContext() {
        TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return null;
            }
    
            public void checkClientTrusted(
                    java.security.cert.X509Certificate[] certs, String authType) {
            }
    
            public void checkServerTrusted(
                    java.security.cert.X509Certificate[] certs, String authType) {
            }
        } };
    
        try {
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, null);
            SSLContext.setDefault(sc);
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
            HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
                public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                });
            return sc;
    
        } catch (Exception e) {
        }
        return null;
    }
    
    0 讨论(0)
  • 2020-11-29 19:06

    Iknow It is too old to answer, but I couldn't find solution like this.

    The code that worked for me with the jersey client:

    import org.glassfish.jersey.client.ClientConfig;
    import org.glassfish.jersey.client.ClientProperties;
    
    import javax.net.ssl.*;
    import javax.ws.rs.client.Client;
    import javax.ws.rs.client.ClientBuilder;
    import javax.ws.rs.client.Entity;
    import javax.ws.rs.client.WebTarget;
    import javax.ws.rs.core.Form;
    import javax.ws.rs.core.MediaType;
    import javax.ws.rs.core.MultivaluedHashMap;
    import java.security.KeyManagementException;
    import java.security.NoSuchAlgorithmException;
    import java.security.cert.CertificateException;
    
    public class Testi {
    
    static {
        disableSslVerification();
    }
    private static void disableSslVerification() {
        // Create all-trusting host name verifier
        HostnameVerifier allHostsValid = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        };
        // Install the all-trusting host verifier
        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
    }
    
    public Testi() {
        MultivaluedHashMap<String, Object> headers = new MultivaluedHashMap<>();
        //... initialize headers
    
        Form form = new Form();
        Entity<Form> entity = Entity.entity(form, MediaType.APPLICATION_FORM_URLENCODED_TYPE);
        // initialize entity ...
    
        WebTarget target = getWebTarget();
        Object responseResult = target.path("api/test/path...").request()
                .headers(headers).post(entity, Object.class);
    
    }
    
    public static void main(String args[]) {
        new Testi();
    }
    
    private WebTarget getWebTarget() {
        ClientConfig clientConfig = new ClientConfig();
        clientConfig.property(ClientProperties.CONNECT_TIMEOUT, 30000);
        clientConfig.property(ClientProperties.READ_TIMEOUT, 30000);
    
        SSLContext sc = getSSLContext();
        Client client = ClientBuilder.newBuilder().sslContext(sc).withConfig(clientConfig).build();
        WebTarget target = client.target("...url...");
        return target;
    }
    
    private SSLContext getSSLContext() {
        try {
            // Create a trust manager that does not validate certificate chains
            TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
                @Override
                public void checkClientTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) throws CertificateException {
    
                }
    
                @Override
                public void checkServerTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) throws CertificateException {
    
                }
    
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            }
            };
    
            // Install the all-trusting trust manager
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            return sc;
        } catch (NoSuchAlgorithmException | KeyManagementException e) {
            e.printStackTrace();
        }
        return null;
    }
    }
    
    0 讨论(0)
  • 2020-11-29 19:07

    Please see below for a modest improvement on @Sled's code shown above, that turn-back-on method was missing one line, now it passes my tests. This disables HTTPS certificate and hostname spoofing when using RestTemplate in a Spring-Boot version 2 application that uses the default HTTP configuration, NOT configured to use Apache HTTP Client.

    package org.my.little.spring-boot-v2.app;
    
    import java.security.KeyManagementException;
    import java.security.NoSuchAlgorithmException;
    import java.security.cert.X509Certificate;
    
    import javax.net.ssl.HostnameVerifier;
    import javax.net.ssl.HttpsURLConnection;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLSession;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.X509TrustManager;
    
    /**
     * Disables and enables certificate and host-name checking in
     * HttpsURLConnection, the default JVM implementation of the HTTPS/TLS protocol.
     * Has no effect on implementations such as Apache Http Client, Ok Http.
    */
    public final class SSLUtils {
    
        private static final HostnameVerifier jvmHostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
    
        private static final HostnameVerifier trivialHostnameVerifier = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession sslSession) {
                return true;
            }
        };
    
        private static final TrustManager[] UNQUESTIONING_TRUST_MANAGER = new TrustManager[] { new X509TrustManager() {
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return null;
            }
    
            public void checkClientTrusted(X509Certificate[] certs, String authType) {
            }
    
            public void checkServerTrusted(X509Certificate[] certs, String authType) {
            }
        } };
    
        public static void turnOffSslChecking() throws NoSuchAlgorithmException, KeyManagementException {
            HttpsURLConnection.setDefaultHostnameVerifier(trivialHostnameVerifier);
            // Install the all-trusting trust manager
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, UNQUESTIONING_TRUST_MANAGER, null);
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        }
    
        public static void turnOnSslChecking() throws KeyManagementException, NoSuchAlgorithmException {
            HttpsURLConnection.setDefaultHostnameVerifier(jvmHostnameVerifier);
            // Return it to the initial state (discovered by reflection, now hardcoded)
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, null, null);
            HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        }
    
        private SSLUtils() {
            throw new UnsupportedOperationException("Do not instantiate libraries.");
        }
    }
    
    0 讨论(0)
提交回复
热议问题