如何配置Fargate/Docker上的Spring Boot服务通过mTLS调用外部REST API?
Spring Boot + Fargate/Docker 实现mTLS认证调用第三方服务
一、证书准备
- 获取第三方提供的CA根证书,以及自身的客户端证书(含私钥),所有证书需加密存储(推荐AWS Secrets Manager),禁止嵌入镜像。
- 将客户端证书转换为Java兼容的PKCS12格式:
openssl pkcs12 -export -in client.crt -inkey client.key -out client.p12 -name "client" - 将CA根证书导入Java信任库:
keytool -importcert -file ca.crt -alias third-party-ca -keystore truststore.jks
二、Spring Boot 代码配置
方式1:使用RestTemplate
在application.yml中配置SSL参数(密码通过环境变量注入):
spring: resttemplate: ssl: trust-store: /secrets/truststore.jks trust-store-password: ${TRUST_STORE_PWD} key-store: /secrets/client.p12 key-store-password: ${KEY_STORE_PWD} key-store-type: PKCS12 key-alias: client
创建配置类初始化RestTemplate:
@Configuration public class RestTemplateConfig { @Value("${spring.resttemplate.ssl.trust-store}") private String trustStorePath; @Value("${spring.resttemplate.ssl.trust-store-password}") private char[] trustStorePwd; @Value("${spring.resttemplate.ssl.key-store}") private String keyStorePath; @Value("${spring.resttemplate.ssl.key-store-password}") private char[] keyStorePwd; @Value("${spring.resttemplate.ssl.key-alias}") private String keyAlias; @Bean public RestTemplate mtlsRestTemplate() throws Exception { SSLContext sslContext = SSLContextBuilder .create() .loadTrustMaterial(new File(trustStorePath), trustStorePwd) .loadKeyMaterial(new File(keyStorePath), keyStorePwd, keyStorePwd) .build(); HttpClient httpClient = HttpClientBuilder.create() .setSSLContext(sslContext) .build(); HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient); return new RestTemplate(factory); } }
方式2:使用WebClient(推荐Spring WebFlux场景)
@Configuration public class WebClientConfig { @Value("${spring.resttemplate.ssl.trust-store}") private String trustStorePath; @Value("${spring.resttemplate.ssl.key-store}") private String keyStorePath; @Value("${spring.resttemplate.ssl.key-store-password}") private char[] keyStorePwd; @Bean public WebClient mtlsWebClient() throws SSLException { SslContext sslContext = SslContextBuilder .forClient() .trustManager(new File(trustStorePath)) .keyManager(new File(keyStorePath), keyStorePwd) .build(); HttpClient httpClient = HttpClient.create().secure(t -> t.sslContext(sslContext)); return WebClient.builder() .clientConnector(new ReactorClientHttpConnector(httpClient)) .build(); } }
三、Docker镜像构建
编写Dockerfile,禁止将证书打包进镜像:
FROM amazoncorretto:17-alpine-jdk WORKDIR /app COPY target/your-service.jar app.jar ENTRYPOINT ["java", "-jar", "app.jar"]
构建镜像并推送到ECR:
docker build -t your-ecr-repo/your-service:latest . aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin your-ecr-repo-url docker push your-ecr-repo/your-service:latest
四、Fargate任务配置
- 证书挂载:在ECS任务定义中,将存储在Secrets Manager的证书文件(
truststore.jks、client.p12)挂载到容器的/secrets/目录(通过secrets字段配置,指定文件路径)。 - 环境变量注入:将证书密码(
TRUST_STORE_PWD、KEY_STORE_PWD)通过Secrets Manager作为环境变量注入容器。 - 权限配置:为Fargate任务执行角色添加
SecretsManagerReadWrite权限(或自定义最小权限策略),确保容器能读取证书和密码。
五、验证测试
- 本地测试:使用curl模拟mTLS请求,确认证书有效性:
curl --cert client.crt --key client.key --cacert ca.crt https://third-party-api.com/endpoint - 容器内测试:进入Fargate容器,执行上述curl命令验证连通性。
内容的提问来源于stack exchange,提问作者avijendr
相关产品推荐
相关产品推荐

