【问题标题】:Can a client make a request with RestTemplate without a certificate to a secure SSL server?客户端可以在没有证书的情况下使用 RestTemplate 向安全 SSL 服务器发出请求吗?
【发布时间】:2020-10-12 17:57:40
【问题描述】:

有人可以帮我解决以下问题吗:

我有一个启用了 SSL 的 REST 服务器和一个位于 2 台不同计算机上的 REST 客户端。两者都是用 Spring Boot 构建的。服务器将具有 .p12 或 .pfx 证书。

如果 REST 客户端想要向服务器发出请求,它是否需要提供证书,或者即使服务器是安全的,它也可以使用简单的 RestTemplate 发出请求?相同的规则是否适用于 Postman,或者 Postman 也可以在没有证书的情况下发送请求?

我尝试使用带有证书的 REST 模板从 REST 客户端创建请求。但我不确定,我应该提供哪个证书。它应该是服务器上的相同证书还是另一个证书?并且来自服务器的证书是否需要对 REST 客户端的 ip 有一个规则以允许请求?

ssl服务器配置:

ssl:
 key-store-type: PKCS12
 key-store: ${MY_DIR}/config/ssl/myCert.pfx
 key-store-password: 123456

来自客户端的其余模板:

 RestTemplate restTemplate = null;
    try {
        SSLContext sslContext = SSLContextBuilder
            .create()
            .loadTrustMaterial(ResourceUtils.getFile("classpath:config/ssl/myCert.pfx"), password.toCharArray())
            .build();

        HttpClient client = HttpClients.custom()
            .setSSLContext(sslContext)
            .build();

        HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
        requestFactory.setHttpClient(client);

        restTemplate = new RestTemplate(requestFactory);
    } catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException | KeyManagementException ex) {
        LOGGER.error("Error getting the RestTemplate with ssl certificate", ex);
    }

【问题讨论】:

    标签: spring-boot ssl https resttemplate


    【解决方案1】:

    是否需要客户端证书完全取决于服务器配置。有些服务器需要客户端证书,有些则不需要。请参阅您的特定 REST API 的文档以了解客户端的要求。

    【讨论】:

      【解决方案2】:
      @Bean
      public RestTemplate restTemplate() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
              TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
              SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
      
              SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
              CloseableHttpClient httpClient = HttpClients.custom()
                              .setSSLSocketFactory(csf)
                              .build();
      
              HttpComponentsClientHttpRequestFactory requestFactory =
                              new HttpComponentsClientHttpRequestFactory();
              requestFactory.setHttpClient(httpClient);
              RestTemplate restTemplate = new RestTemplate(requestFactory);
          return restTemplate;
      }
      

      这对我有用。

      【讨论】:

        【解决方案3】:

        请使用下面的导入包。

        import java.security.KeyManagementException;
        import java.security.KeyStoreException;
        import java.security.NoSuchAlgorithmException;
        import java.security.cert.X509Certificate;
        import javax.net.ssl.SSLContext;
        import org.apache.http.conn.ssl.NoopHostnameVerifier;
        import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
        import org.apache.http.impl.client.CloseableHttpClient;
        import org.apache.http.impl.client.HttpClients;
        import org.apache.http.ssl.SSLContexts;
        import org.apache.http.ssl.TrustStrategy;
        import org.springframework.boot.SpringApplication;
        import org.springframework.boot.autoconfigure.SpringBootApplication;
        import org.springframework.context.annotation.Bean;
        import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
        import org.springframework.web.client.RestTemplate;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-06-07
          • 1970-01-01
          • 2014-10-05
          • 2021-08-05
          • 2015-11-01
          • 1970-01-01
          • 2022-08-08
          • 1970-01-01
          相关资源
          最近更新 更多