如何使用 Spring Boot 和 Tomcat 指定我的 .keystore 文件? [英] How can I specify my .keystore file with Spring Boot and Tomcat?

查看:42
本文介绍了如何使用 Spring Boot 和 Tomcat 指定我的 .keystore 文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试设置 Spring Security 以使用 Spring Boot 的嵌入式 Tomcat 实例.有很多基本示例可以做到这一点,但我被困在他们离开的地方——他们通过 HTTP(而不是 HTTPS)进行基本身份验证.

I'm trying to set up Spring Security to work with Spring Boot's embedded Tomcat instance. There are quite a few basic samples that do this but I'm stuck where they leave off -- they do basic authentication over HTTP (not HTTPS).

如果我可以访问 Tomcat 配置文件 (server.xml),我可能会使其工作,但由于 Spring Boot 使用嵌入式 Tomcat 实例(否则会非常方便),我不可以访问 Tomcat 配置文件(至少,据我所知).

I could probably make it work if I had access to the Tomcat configuration files (server.xml) but since Spring Boot uses an embedded Tomcat instance (which is otherwise a huge convenience), I dont have access to the Tomcat configuration files (at least, not to my knowledge).

可能有一个用于此的 application.properties 设置,但我无法找到它.我在 application.properties 中看到了对 server.contextPath 字段的引用,我怀疑这可能与替换 Tomcat 配置文件有关.即使它是相关的,我也不知道从哪里开始——我看到的所有 Tomcat SSL 说明都是从编辑现有的 server.xml 文件开始的,而不是从头开始构建一个.

There may be an application.properties setting for this but I haven't been able to track it down. I've seen references to a server.contextPath field in application.properties that I suspect may have something to do with replacement Tomcat config files. Even if it is related, I wouldn't know where to begin anyway -- all of the Tomcat SSL instructions I've seen start with editing an existing server.xml file, not building one from scratch.

这可以通过 Spring Boot 完成吗(通过某种方式指定 server.xml 的片段或通过其他方式)?如果不是,那么最简单的方法是什么?我知道我可能需要排除 Spring Boot 的 Tomcat 组件,但我希望尽可能避免这种情况.

Can this be done with Spring Boot (either by somehow specifying a snippet of server.xml or through other means)? If not, what would be the simplest way to do this? I understand that I may need to exclude the Tomcat component of Spring Boot but I'd prefer to avoid that if possible.

推荐答案

事实证明有一种方法可以做到这一点,尽管我不确定我是否找到了正确"的方法,因为这需要数小时的阅读时间来自多个项目的源代码.换句话说,这可能是很多愚蠢的工作(但它确实有效).

It turns out that there is a way to do this, although I'm not sure I've found the 'proper' way since this required hours of reading source code from multiple projects. In other words, this might be a lot of dumb work (but it works).

首先,无法获取嵌入式Tomcat中的server.xml,无法对其进行扩充或替换.这必须以编程方式完成.

First, there is no way to get at the server.xml in the embedded Tomcat, either to augment it or replace it. This must be done programmatically.

第二,'require_https' 设置没有帮助,因为您不能那样设置证书信息.它确实设置了从 http 到 https 的转发,但它并没有给你一种让 https 工作的方法,所以转发没有帮助.但是,将它与下面的内容一起使用,确实使 https 工作.

Second, the 'require_https' setting doesn't help since you can't set cert info that way. It does set up forwarding from http to https, but it doesn't give you a way to make https work so the forwarding isnt helpful. However, use it with the stuff below, which does make https work.

首先,您需要提供 EmbeddedServletContainerFactory,如嵌入式 Servlet 容器支持文档.这些文档适用于 Java,但 Groovy 看起来几乎相同.请注意,我无法让它识别示例中使用的 @Value 注释,但不需要.对于 groovy,只需将其放入一个新的 .groovy 文件中,并在启动 spring 启动时将该文件包含在命令行中.

To begin, you need to provide an EmbeddedServletContainerFactory as explained in the Embedded Servlet Container Support docs. The docs are for Java but the Groovy would look pretty much the same. Note that I haven't been able to get it to recognize the @Value annotation used in their example but its not needed. For groovy, simply put this in a new .groovy file and include that file on the command line when you launch spring boot.

现在,说明说您可以自定义您在该代码中创建的 TomcatEmbeddedServletContainerFactory 类,以便您可以更改 web.xml 行为,这是正确的,但对于我们的目的而言,这很重要知道您还可以使用它来定制 server.xml 行为.事实上,阅读该类的源代码并将其与嵌入式 Tomcat 文档进行比较,您会发现这是唯一可以做到这一点的地方.有趣的函数是 TomcatEmbeddedServletContainerFactory.addConnectorCustomizers(),它可能看起来不像 Javadocs 中的很多,但实际上为您提供了嵌入式 Tomcat 对象来自定义您自己.只需传递您自己的 TomcatConnectorCustomizer 实现,并在 void Customize(Connector con) 函数中的给定 Connector 上设置您想要的内容.现在,您可以使用 Connector 做大约 10 亿件事情,我找不到有用的文档,但是 createConnector() 在这个 这家伙个人Spring-embedded-Tomcatproject 是一本非常实用的指南.我的实现最终看起来像这样:

Now, the instructions say that you can customize the TomcatEmbeddedServletContainerFactory class that you created in that code so that you can alter web.xml behavior, and this is true, but for our purposes its important to know that you can also use it to tailor server.xml behavior. Indeed, reading the source for the class and comparing it with the Embedded Tomcat docs, you see that this is the only place to do that. The interesting function is TomcatEmbeddedServletContainerFactory.addConnectorCustomizers(), which may not look like much from the Javadocs but actually gives you the Embedded Tomcat object to customize yourself. Simply pass your own implementation of TomcatConnectorCustomizer and set the things you want on the given Connector in the void customize(Connector con) function. Now, there are about a billion things you can do with the Connector and I couldn't find useful docs for it but the createConnector() function in this this guys personal Spring-embedded-Tomcat project is a very practical guide. My implementation ended up looking like this:

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 一起使用,这是可能的.

The Autowiring will pick up this implementation an run with it. Once I fixed my busted keystore file (make sure you call keytool with -storetype pkcs12, not -storepass pkcs12 as reported elsewhere), this worked. Also, it would be far better to provide the parameters (port, password, etc) as configuration settings for testing and such... I'm sure its possible if you can get the @Value annotation to work with Groovy.

这篇关于如何使用 Spring Boot 和 Tomcat 指定我的 .keystore 文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆