spring RestTemplate忽略证书验证

要使RestTemplate忽略SSL证书验证,你可以配置一个自定义的SSLContext,然后将其注入到RestTemplate使用的HttpClient中。以下是一个示例代码:

import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.springframework.http.MediaType;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.SSLContext;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;

public class RestTemplateConfig {

    /**
     * 我们创建了一个SSLContext,它会接受所有的SSL证书,而不进行验证。
     * 然后我们创建了一个SSLConnectionSocketFactory,它使用这个SSLContext,并且提供了一个NoopHostnameVerifier,
     * 这个Verifier不会进行主机名验证。
     * 最后,我们创建了一个配置了这个SSLConnectionSocketFactory的HttpClient,并将其设置为RestTemplate工厂的HttpClient。
     * @return RestTemplate
     */
    public static RestTemplate createRestTemplate() {
        try {

            //SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, (x509Certificates, s) -> true).build();
            SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
                @Override
                public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
                    return true;
                }
            }).build();
            SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());
            HttpClient httpClient = HttpClients.custom()
                    .setSSLSocketFactory(socketFactory)
                    .build();

            HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
            factory.setHttpClient(httpClient);

            RestTemplate restTemplate=new RestTemplate(factory);

            FastJsonHttpMessageConverter converter=mediaType();
            restTemplate.getMessageConverters().add(converter);
            return restTemplate;
        //} catch (KeyManagementException | NoSuchAlgorithmException e) {
        } catch (Exception e) {
            throw new RuntimeException("Failed to create RestTemplate", e);
        }
    }

    private static FastJsonHttpMessageConverter mediaType(){
        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
        List<MediaType> supportedMediaTypes = new ArrayList<MediaType>();
        supportedMediaTypes.add(MediaType.APPLICATION_JSON);
        supportedMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
        supportedMediaTypes.add(MediaType.APPLICATION_ATOM_XML);
        supportedMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED);
        supportedMediaTypes.add(MediaType.APPLICATION_OCTET_STREAM);
        supportedMediaTypes.add(MediaType.APPLICATION_PDF);
        supportedMediaTypes.add(MediaType.APPLICATION_RSS_XML);
        supportedMediaTypes.add(MediaType.APPLICATION_XHTML_XML);
        supportedMediaTypes.add(MediaType.APPLICATION_XML);
        supportedMediaTypes.add(MediaType.IMAGE_GIF);
        supportedMediaTypes.add(MediaType.IMAGE_JPEG);
        supportedMediaTypes.add(MediaType.IMAGE_PNG);
        supportedMediaTypes.add(MediaType.TEXT_EVENT_STREAM);
        supportedMediaTypes.add(MediaType.TEXT_HTML);
        supportedMediaTypes.add(MediaType.TEXT_MARKDOWN);
        supportedMediaTypes.add(MediaType.TEXT_PLAIN);
        supportedMediaTypes.add(MediaType.TEXT_XML);
        converter.setSupportedMediaTypes(supportedMediaTypes);
        return converter;
    }

}

在这个示例中,我们创建了一个SSLContext,它会接受所有的SSL证书,而不进行验证。然后我们创建了一个SSLConnectionSocketFactory,它使用这个SSLContext,并且提供了一个NoopHostnameVerifier,这个Verifier不会进行主机名验证。最后,我们创建了一个配置了这个SSLConnectionSocketFactoryHttpClient,并将其设置为RestTemplate工厂的HttpClient

请注意,忽略SSL证书验证会降低安全性,因此应该只在你完全理解潜在的安全风险的情况下使用,通常这种做法只适用于开发或测试环境。

posted @ 2024-08-08 11:31  一叶知秋。  阅读(509)  评论(0编辑  收藏  举报