我正在尝试设置Spring Security以使用Spring Boot的嵌入式Tomcat实例。有相当多的基本样本可以做到这一点,但我被困在他们离开的地方 - 他们通过HTTP(而不是HTTPS)进行基本身份验证。
如果我可以访问Tomcat配置文件(server.xml
),我可能会工作但是由于Spring Boot使用嵌入式Tomcat实例(这是一个非常方便),我无法访问Tomcat配置文件(至少,据我所知)。
可能有application.properties
设置,但我无法追踪它。我已经看到server.contextPath
中application.properties
字段的引用,我怀疑它可能与替换Tomcat配置文件有关。即使它是相关的,我也不知道从哪里开始 - 我见过的所有Tomcat SSL指令都是从编辑现有的server.xml
文件开始的,而不是从头开始构建一个。
这可以通过Spring Boot完成(通过某种方式指定server.xml
的片段或通过其他方式)?如果没有,最简单的方法是什么?我知道我可能需要排除Spring Boot的Tomcat组件,但如果可能的话,我宁愿避免使用它。
答案 0 :(得分:55)
从Spring Boot 1.2开始,您可以使用application.properties
或application.yml
配置SSL。以下是application.properties
的示例:
server.port = 8443
server.ssl.key-store = classpath:keystore.jks
server.ssl.key-store-password = secret
server.ssl.key-password = another-secret
与application.yml
相同:
server:
port: 8443
ssl:
key-store: classpath:keystore.jks
key-store-password: secret
key-password: another-secret
答案 1 :(得分:18)
事实证明有一种方法可以做到这一点,虽然我不确定我是否找到了'正确'的方式,因为这需要几个小时从多个项目中读取源代码。换句话说,这可能是很多愚蠢的工作(但它确实有效)。
首先,无法获取嵌入式Tomcat中的server.xml,无论是扩充还是替换它。这必须以编程方式完成。
其次,'require_https'设置无效,因为您无法以这种方式设置证书信息。 设置从http到https的转发,但它没有为您提供使https工作的方法,因此转发不会有用。但是,请将其与下面的内容一起使用, 使https正常工作。
首先,您需要按照Embedded Servlet Container Support docs中的说明提供EmbeddedServletContainerFactory
。这些文档适用于Java,但Groovy看起来几乎相同。请注意,我无法识别其示例中使用的@Value
注释,但不需要它。对于groovy,只需将其放入一个新的.groovy文件中,并在启动spring
启动时在命令行中包含该文件。
现在,说明说您可以自定义在该代码中创建的TomcatEmbeddedServletContainerFactory
类,以便您可以更改web.xml行为,这是正确的,但对于我们的目的,知道您的重要性也可以用它来定制server.xml
行为。实际上,阅读该类的源代码并将其与嵌入式Tomcat文档进行比较,您会发现这是唯一可以做到这一点的地方。有趣的函数是TomcatEmbeddedServletContainerFactory.addConnectorCustomizers()
,它可能看起来不像Javadocs,但实际上为您提供了嵌入式Tomcat对象来自定义。只需传递您自己的TomcatConnectorCustomizer
实现,并在Connector
函数中的给定void customize(Connector con)
上设置您想要的内容。现在,您可以使用Connector
完成大约十亿件事情,但我找不到有用的文档,但此this guys personal Spring-embedded-Tomcat project中的createConnector()
函数是非常实用的指南。我的实现最终看起来像这样:
package com.deepdownstudios.server
import org.springframework.boot.context.embedded.tomcat.TomcatConnectorCustomizer
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory
import org.apache.catalina.connector.Connector;
import org.apache.coyote.http11.Http11NioProtocol;
import org.springframework.boot.*
import org.springframework.stereotype.*
@Configuration
class MyConfiguration {
@Bean
public EmbeddedServletContainerFactory servletContainer() {
final int port = 8443;
final String keystoreFile = "/path/to/keystore"
final String keystorePass = "keystore-password"
final String keystoreType = "pkcs12"
final String keystoreProvider = "SunJSSE"
final String keystoreAlias = "tomcat"
TomcatEmbeddedServletContainerFactory factory =
new TomcatEmbeddedServletContainerFactory(this.port);
factory.addConnectorCustomizers( new TomcatConnectorCustomizer() {
void customize(Connector con) {
Http11NioProtocol proto = (Http11NioProtocol) con.getProtocolHandler();
proto.setSSLEnabled(true);
con.setScheme("https");
con.setSecure(true);
proto.setKeystoreFile(keystoreFile);
proto.setKeystorePass(keystorePass);
proto.setKeystoreType(keystoreType);
proto.setProperty("keystoreProvider", keystoreProvider);
proto.setKeyAlias(keystoreAlias);
}
});
return factory;
}
}
Autowiring将使用它来运行此实现。一旦我修复了我的破坏的密钥库文件(确保你用-storetype pkcs12
调用keytool,而不是在其他地方报告的-storepass pkcs12
),这就行了。另外,提供参数(端口,密码等)作为测试的配置设置会更好......如果你能得到@Value注释来使用Groovy,我肯定是可能的。
答案 2 :(得分:9)
对于外部密钥库,前缀为"文件:"
app.run(host = 'your global ip from whatismyip', port = '5000')
答案 3 :(得分:0)
如果您不想实施connector customizer
,则可以构建并导入提供预定义connector customizer
的库(https://github.com/ycavatars/spring-boot-https-kit)。根据自述文件,您只需创建密钥库,配置connector.https.*
,导入库并添加@ComponentScan("org.ycavatars.sboot.kit")
。然后,您将拥有HTTPS连接。
答案 4 :(得分:-1)