我已经设法将我的嵌入式tomcat配置为使用密钥库文件,当我从eclipse执行项目时它可以工作。
代码很简单:
...
String keystore = new File(MyServer.class.getResource("/keystore").toURI()).toPath().toString();
httpsConnector.setAttribute("keystoreFile",keystore);
...
文件keystore
位于添加到构建路径的源目录中。
将项目导出到可执行jar后,我可以验证jar根目录中是否存在keyfile
。
但是在执行jar时,我收到了这个错误:
Exception in thread "main" java.lang.IllegalArgumentException: URI is not hierarchical
所以我认为,我无法使用httpsConnector.setAttribute("keystoreFile",...)
配置密钥文件。还有另一种配置方式吗?我真的不想在临时目录中复制密钥文件并从那里引用它。
答案 0 :(得分:2)
我真的不想在临时目录中复制密钥文件并从那里引用它。
我很同情,但看起来你将不得不这样做。可以从任何类型的输入流加载Java密钥库(请参阅Keystore.load),以便您可以认为可以从jar文件中的资源加载密钥库。但是,如果在Tomcat 7源代码中搜索字符串“ks.load”,您将看到它始终将keystoreFile属性解释为File
的名称,并创建一个FileInputStream,然后传递给ks.load。
因此,有必要创建包含密钥库的临时文件,并将此文件的位置作为keystoreFile
属性传递。
BTW - 如果你不打算分发这个jar并且愿意将它保密,那么嵌入密钥库的方法可能就行了。
但是,如果您计划将此jar分发到多个站点,则每个站点的安全性都基于相同的私钥。此外,任何有权访问jar文件的人都可以提取私钥,然后可以窃听或者中间人攻击您的所有站点。
通常,安装过程最好需要由站点管理员生成新的私钥和证书(即使它只是一个自签名证书)。这样每个密钥都是不同的,破坏网站的唯一方法就是访问该服务器密钥库和密码。
答案 1 :(得分:1)
这可能是一个旧帖子,但我遇到了同样的问题,并没有在网上找到解决方案。所以我想分享我的所作所为。
就我而言,我需要两个带有自签名证书的端口。除了在application.yml中配置的那个,另一个端口在主条目中配置。
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public ServletWebServerFactory servletContainer() throws IOException
{
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
tomcat.addAdditionalTomcatConnectors(additionalConnector());
return tomcat;
}
private Connector additionalConnector() throws IOException
{
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("https");
connector.setPort(8088);
...
URL keystore = new ClassPathResource("keystore.jks").getURL();
connector.setAttribute("keystoreFile", keystore.toExternalForm());
return connector;
}
}
使用URL,mvn spring-boot:运行并运行jar工作,可以毫无问题地加载密钥库。
我使用的是spring-boot 2.0.1.RELEASE和tomcat 8.5.29