springboot 2.X 配置SSL证书 启用HTTPS

SpringBoot2.0 HTTPS配置
本文介绍如何在SpringBoot2.0项目中配置HTTPS,包括生成SSL证书、配置SSL证书及启用HTTPS服务等步骤。

微信小程序开发,正式上线后台接口需要启用HTTPS,后台采用SpringBoot2.0进行开发,在配置SSL证书启用HTTPS时遇到些许坑,在此做下记录,希望能帮到和我一样的菜鸟……

1、生成SSL证书

MAC系统:keytool -genkey -alias your.alias(别名随便起) -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 validity 3650

Windows系统,请在JDK目录下找到keytool.exe

keytool -genkey -alias your.alias(别名随便起) -keypass yourpass1 -keyalg RSA -keysize 2048 -validity 3650 -keystore D:/keys/keystore.keystore -storepass yourpass2

输入密钥库口令:
再次输入新口令:
您的名字与姓氏是什么?
  [Unknown]:  xxx
您的组织单位名称是什么?
  [Unknown]:  xxx
您的组织名称是什么?
  [Unknown]:  xxx
您所在的城市或区域名称是什么?
  [Unknown]:  beijing
您所在的省/市/自治区名称是什么?
  [Unknown]:  beijing
该单位的双字母国家/地区代码是什么?
  [Unknown]:  china
CN=xxx, OU=xxx, O=xxx, L=beijing, ST=beijing, C=china是否正确?
  [否]:  y

请正确设置上面的参数

 

2、创建一个SpringBoot2.X项目

配置就不写了

 

3、将生成的keystore.p12或者keystore.keystore拷贝到项目resources目录下

4、配置入口文件

package com.yourcompany.test;

import org.apache.catalina.connector.Connector;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ServletWebServerFactory;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class WandeTestSslApplication {

    public static void main(String[] args) {
        SpringApplication.run(WandeTestSslApplication.class, args);
    }
    //下面是2.0的配置,1.x请搜索对应的设置
    @Bean
    public ServletWebServerFactory servletContainer() {
        TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
        tomcat.addAdditionalTomcatConnectors(createHTTPConnector());
        return tomcat;
    }

    private Connector createHTTPConnector() {
        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
        //同时启用http(8080)、https(8443)两个端口
        connector.setScheme("http");
        connector.setSecure(false);
        connector.setPort(8080);
        connector.setRedirectPort(8443);
        return connector;
    }
    
}

5、配置application.yml文件

server:
  port: 8443
  ssl:
    # 证书名字
    key-store: classpath:keystore.p12

    #key-store: classpath:keystore.keystore
    # 密钥库密码
    key-store-password: yourpass2
    #key-password: yourpass1 #springboot2.0不需要配置这个 T-T
    key-store-type: PKCS12
    key-alias: your.alias

 

配置到这里,就可以运行了

6、新建Controller

@Controller
@RequestMapping("/")
public class IndexController {

    @GetMapping("/")
    public String index() {
        return "index";
    }
}

运行起来,打开浏览器:https://localhost:8443,会出现证书安全提示,因为是自已生成未认证的证书,所以不用理会

 

<think>我们正在解决在Spring Boot 3.x中配置Feign客户端使用HTTPS协议的问题。用户之前遇到了PKIX路径构建失败的错误,但当前问题是如何配置Feign使用HTTPS。 由于Feign在底层通常使用HTTP客户端(如Apache HttpClient或OKHttp),我们需要确保这些客户端能够正确处理HTTPS请求,特别是当目标服务器使用自签名证书或不受信任的证书时。 解决方案: 1. 如果目标服务器使用公共信任的证书,则无需特殊配置,Feign客户端可以直接使用HTTPS2. 如果目标服务器使用自签名证书或不被JVM信任的证书,我们可以通过以下方式之一解决: a. 将目标服务器的证书导入到JVM的信任库(推荐用于生产环境)。 b. 在Feign客户端配置中忽略SSL证书验证(仅用于开发测试环境)。 由于用户之前遇到PKIX错误,我们假设目标服务器证书不被信任。因此,我们将提供两种配置Feign客户端的方法: 方法一:配置Feign使用自定义的SSL上下文(通过Apache HttpClient) 方法二:配置Feign使用OKHttp并设置信任所有证书(不推荐用于生产) 我们以方法一(使用Apache HttpClient)为例,因为Spring Cloud OpenFeign默认支持Apache HttpClient。 步骤: 1. 添加Apache HttpClient依赖 2. 配置一个自定义的HttpClient,该客户端使用信任所有证书SSL上下文(或者也可以配置为信任指定证书) 3. 配置Feign使用这个自定义的HttpClient 注意:在Spring Boot 3.x中,我们使用Spring Cloud 2022.x(代号Kilburn),它基于Spring Framework 6和Java 17。 具体代码实现: 第一步:添加依赖(如果尚未添加) 在pom.xml中添加: ```xml <!-- Feign with Apache HttpClient --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency> <dependency> <groupId>org.apache.httpcomponents.client5</groupId> <artifactId>httpclient5</artifactId> </dependency> ``` 第二步:配置自定义的HttpClient 我们可以创建一个配置类,配置一个忽略SSL验证的HttpClient(仅用于测试环境): ```java import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.classic.HttpClients; import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; import org.apache.hc.client5.http.io.HttpClientConnectionManager; import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; import org.apache.hc.core5.ssl.SSLContextBuilder; import org.apache.hc.core5.ssl.TrustStrategy; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.net.ssl.SSLContext; import java.security.KeyManagementException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.cert.X509Certificate; @Configuration public class FeignConfig { @Bean public CloseableHttpClient httpClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException { // 信任所有证书 TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true; SSLContext sslContext = SSLContextBuilder.create() .loadTrustMaterial(null, acceptingTrustStrategy) .build(); SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext); HttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder.create() .setSSLSocketFactory(sslSocketFactory) .build(); return HttpClients.custom() .setConnectionManager(connectionManager) .evictExpiredConnections() .build(); } } ``` 第三步:在Feign客户端接口上使用配置 在Feign客户端接口上,我们可以指定配置类(如果我们需要将自定义的HttpClient应用到特定的Feign客户端): ```java import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; @FeignClient(name = "exampleClient", url = "https://example.com", configuration = FeignConfig.class) public interface ExampleClient { @GetMapping("/api/data") String getData(); } ``` 但是,上面的配置会应用到所有Feign客户端(因为我们在配置类中定义了全局的HttpClient Bean)。如果我们只想为特定客户端配置,可以创建不同的HttpClient Bean,并通过@Qualifier指定。 另外,我们也可以使用默认的Feign配置,因为Spring Cloud OpenFeign会自动使用我们定义的CloseableHttpClient Bean(类型为CloseableHttpClient)作为HTTP客户端。 方法二:使用OKHttp(可选) 如果我们想使用OKHttp,可以添加OKHttp依赖并配置一个信任所有证书的OkHttpClient。 添加依赖: ```xml <dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-okhttp</artifactId> </dependency> ``` 配置OKHttpClient Bean: ```java import okhttp3.OkHttpClient; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.concurrent.TimeUnit; @Bean public OkHttpClient okHttpClient() { try { // 创建信任所有证书的TrustManager TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[]{}; } } }; // 创建SSLContext并使用信任所有证书的TrustManager SSLContext sslContext = SSLContext.getInstance("SSL"); sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); return new OkHttpClient.Builder() .sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]) .hostnameVerifier((hostname, session) -> true) // 忽略主机名验证 .connectTimeout(10, TimeUnit.SECONDS) .readTimeout(30, TimeUnit.SECONDS) .build(); } catch (Exception e) { throw new RuntimeException(e); } } ``` 然后,在配置文件中启用OKHttp: ```properties feign.okhttp.enabled=true ``` 注意:同样,这种方法仅用于测试环境。 生产环境建议: 在生产环境中,我们应该将目标服务器的证书(或根证书)导入到JVM的信任库中,这样就不需要绕过SSL验证。具体步骤参考之前提供的“导入证书到JVM信任库”。 如果使用Docker容器部署,可以在构建镜像时导入证书。 总结: 在Spring Boot 3.x中配置Feign客户端使用HTTPS,主要在于配置底层的HTTP客户端(如Apache HttpClient或OKHttp)以支持SSL。对于自签名证书,我们可以临时配置信任所有证书,但生产环境应导入证书。 相关问题: 1. 如何在Spring Boot 3.x中为不同的Feign客户端配置不同的SSL设置? 2. 如何在生产环境中为Feign客户端配置双向SSL认证(mTLS)? 3. 如何将SSL证书添加到Spring Boot应用的Docker镜像中?</think>在 Spring Boot 3.x 中配置 Feign 客户端使用 HTTPS 协议,需要解决 SSL 证书验证问题。以下是完整的配置方案,分为开发环境(快速绕过验证)和生产环境(安全配置)两种场景: --- ### 方案一:开发环境(绕过证书验证 - 仅限测试) ```java import feign.Client; import feign.httpclient.ApacheHttpClient; import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.classic.HttpClients; import org.apache.hc.client5.http.ssl.NoopHostnameVerifier; import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; import org.apache.hc.core5.ssl.SSLContextBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.net.ssl.SSLContext; @Configuration public class FeignInsecureConfig { @Bean public Client feignClient() throws Exception { // 创建信任所有证书SSL上下文 SSLContext sslContext = new SSLContextBuilder() .loadTrustMaterial(null, (chain, authType) -> true) // 信任所有证书 .build(); // 配置HTTP客户端 CloseableHttpClient httpClient = HttpClients.custom() .setSSLSocketFactory(new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE)) .build(); return new ApacheHttpClient(httpClient); } } ``` 在 Feign 客户端接口添加配置: ```java @FeignClient( name = "secure-service", url = "https://your-secure-api.com", configuration = FeignInsecureConfig.class // 应用配置 ) public interface SecureServiceClient { @GetMapping("/data") String getSecureData(); } ``` > ⚠️ **警告**:此方案会禁用所有 SSL 验证,仅用于开发测试环境[^1]。 --- ### 方案二:生产环境(安全配置 - 推荐) #### 步骤 1:获取服务器证书 ```bash openssl s_client -connect your-secure-api.com:443 </dev/null | openssl x509 -out api-certificate.crt ``` #### 步骤 2:创建自定义信任库 ```bash # 创建JKS信任库 (密码: changeit) keytool -import -alias api-cert -file api-certificate.crt \ -keystore custom-truststore.jks -storepass changeit ``` #### 步骤 3:Spring Boot 配置 `application.yml`: ```yaml feign: client: config: default: loggerLevel: FULL server: ssl: trust-store: classpath:custom-truststore.jks trust-store-password: changeit ``` #### 步骤 4:创建安全 Feign 配置 ```java import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; import org.apache.hc.client5.http.impl.classic.HttpClients; import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; import org.apache.hc.core5.ssl.SSLContexts; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import javax.net.ssl.SSLContext; import java.io.InputStream; import java.security.KeyStore; @Configuration public class FeignSecureConfig { @Value("${server.ssl.trust-store}") private Resource trustStore; @Value("${server.ssl.trust-store-password}") private String trustStorePassword; @Bean public CloseableHttpClient httpClient() throws Exception { // 加载信任库 KeyStore truststore = KeyStore.getInstance("JKS"); try (InputStream is = trustStore.getInputStream()) { truststore.load(is, trustStorePassword.toCharArray()); } // 创建SSL上下文 SSLContext sslContext = SSLContexts.custom() .loadTrustMaterial(truststore, null) .build(); return HttpClients.custom() .setSSLSocketFactory(new SSLConnectionSocketFactory(sslContext)) .build(); } } ``` --- ### 证书验证的数学原理 HTTPS 证书验证基于非对称加密: 1. 服务器证书包含公钥 $K_{pub}$ 和签名 $S$ 2. CA 使用私钥 $K_{priv}$ 生成签名: $$ S = \text{Sign}(K_{priv}, \text{CertData}) $$ 3. 客户端使用 CA 公钥验证: $$ \text{Verify}(K_{pub}^{CA}, \text{CertData}, S) = \text{true} $$ 当客户端信任库中缺少 CA 证书时,验证失败[^2]。 --- ### 最佳实践建议 1. **证书管理**: ```mermaid graph LR A[证书来源] --> B{环境类型} B -->|生产环境| C[公共CA证书] B -->|内部系统| D[私有CA导入信任库] B -->|开发测试| E[临时禁用验证] ``` 2. **证书监控**: ```bash # 检查证书有效期 openssl x509 -in api-certificate.crt -noout -dates # 输出:notBefore=... notAfter=... ``` 3. **容器部署**: ```dockerfile FROM eclipse-temurin:17-jdk COPY target/*.jar app.jar COPY custom-truststore.jks /truststore/ CMD java -Djavax.net.ssl.trustStore=/truststore/custom-truststore.jks \ -Djavax.net.ssl.trustStorePassword=changeit \ -jar app.jar ``` > **重要提示**:生产环境必须使用有效证书,禁用验证会导致中间人攻击风险[^3]。
评论 22
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值