容器化Springboot应用程序-从JAR内加载嵌入式密钥库(.jks / .p12)

问题描述 投票:0回答:2

背景:我有一个使用docker容器化并在kubernetes集群上运行的springboot应用程序。它执行API调用,并依赖于需要加载.jks信任库的SSLContext,如下所示:

SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(ResourceUtils.getFile(keyStoreFilePath),
                        keyStorePassword.toCharArray(), new TrustSelfSignedStrategy()).build();

注意,字符串keyStoreFilePath当前在发布时作为环境/属性变量注入,并指向运行容器的主机上的/etc/ssl/keystore.jks之类的位置。缺点是我必须将其安装为kubernetes中的持久卷,以便我的容器化应用程序可以访问它。

相反,我决定将其嵌入到应用程序的类路径中,以便我们的运营团队不必在所有主机上进行设置。但是,当我这样做时,通过这样指定keyStoreFilePath值:classpath:security/keystore.jks,当我在容器外部运行可执行jar时,它运行良好。但是它失败,并在容器内显示以下错误:

class path resource [security/cacerts] cannot be resolved to absolute file path because it does not reside in the file system: jar:file:/app.jar!/BOOT-INF/classes!/security/cacerts","stackTrace":"org.springframework.util.ResourceUtils.getFile(ResourceUtils.java:217)

再次,有趣的是,完全相同的东西在容器外部运行良好,但在容器内部运行失败。有指针吗?

[Update:验证keystore.jks文件的大小为<1 MB。

spring-boot docker ssl kubernetes keystore
2个回答
2
投票

错误消息显示file:/<some-path-in-the-container>/App.jar!/keystore.jks-没有“安全”文件夹,而为keyStoreFilePath传递的值为classpath:security/keystore.jks

JKS文件不太可能大于1MB,这是Kubernetes中ConfigMap-s和Secrets的限制,因此,一个选项是使用JKS文件创建Secret并从Secret中装入卷-否需要使用永久卷或hostPath卷。

HTH


0
投票

我能够弄清楚。由于keystore.jks嵌入在jar中,并且需要从类路径(hostPath)加载,因此我们无法将其作为文件读取。相反,我们将不得不将其读取为输入流-对于jar文件(类路径)中的所有资源均为true。因此,我必须执行以下操作才能使其正常工作:

classpath:security/keystore.jks

[KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); keystore.load(truststoreResource.getInputStream(), keyStorePassword.toCharArray()); SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(keystore, new TrustSelfSignedStrategy()).build(); 答案很有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.