代码之家  ›  专栏  ›  技术社区  ›  Dave

如何使用Spring Boot和Tomcat指定.keystore文件?

  •  52
  • Dave  · 技术社区  · 11 年前

    我正在尝试设置Spring Security以使用Spring Boot的嵌入式Tomcat实例。有相当多的基本示例可以做到这一点,但我一直停留在它们停止的地方——它们通过HTTP(而不是HTTPS)进行基本身份验证。

    如果我有权访问Tomcat配置文件,我可能会让它正常工作( server.xml )但由于Spring Boot使用了嵌入式Tomcat实例(这在其他方面非常方便),我无法访问Tomcat配置文件(至少据我所知)。

    可能有 application.properties 设置,但我一直没能找到它。我看到了对 server.contextPath 字段在 应用程序.属性 我怀疑这可能与替换Tomcat配置文件有关。即使它是相关的,我也不知道从哪里开始——我看到的所有Tomcat SSL指令都是从编辑现有的 服务器.xml 文件,而不是从头开始构建。

    这可以用Spring Boot完成吗?(或者通过某种方式指定 服务器.xml 或通过其他方式)?如果没有,最简单的方法是什么?我知道我可能需要排除Spring Boot的Tomcat组件,但如果可能的话,我更愿意避免。

    5 回复  |  直到 8 年前
        1
  •  72
  •   user41871 user41871    10 年前

    从Spring Boot 1.2开始,您可以使用配置SSL application.properties application.yml 。这里有一个例子 应用程序.属性 :

    server.port = 8443
    server.ssl.key-store = classpath:keystore.jks
    server.ssl.key-store-password = secret
    server.ssl.key-password = another-secret
    

    与相同 应用程序.yml :

    server:
      port: 8443
      ssl:
        key-store: classpath:keystore.jks
        key-store-password: secret
        key-password: another-secret
    

    这里有一个链接 current reference documentation .

        2
  •  25
  •   pma    7 年前

    对于外部密钥库,前缀为“file:”

    server.ssl.key-store=file:config/keystore 
    
        3
  •  21
  •   Dave    11 年前

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

    首先,无法访问嵌入式Tomcat中的server.xml,也无法对其进行扩充或替换。这必须通过编程实现。

    其次,“require_https”设置没有帮助,因为您不能以这种方式设置证书信息。它 设置从http到https的转发,但它不能让https工作,所以转发没有帮助。然而,将其与以下内容一起使用 使https发挥作用。

    首先,您需要提供 EmbeddedServletContainerFactory 如中所述 Embedded Servlet Container Support docs 。这些文档是针对Java的,但Groovy看起来几乎是一样的。请注意,我还没能让它识别 @Value 在他们的例子中使用了注释,但不需要。对于groovy,只需将其放入一个新的.groovy文件中,并在启动时将该文件包含在命令行中 spring 靴子

    现在,说明显示您可以自定义 TomcatEmbeddedServletContainerFactory 您在该代码中创建的类,以便您可以更改web.xml的行为,这是正确的,但为了我们的目的,重要的是要知道您也可以使用它来定制 server.xml 行为事实上,阅读类的源代码并将其与Embedded Tomcat文档进行比较,您会发现这是唯一可以做到这一点的地方。有趣的功能是 TomcatEmbeddedServletContainerFactory.addConnectorCustomizers() ,这在Javadocs中看起来可能不太像,但实际上为您提供了嵌入式Tomcat对象来自定义。只需通过您自己的实现 TomcatConnectorCustomizer 并将你想要的东西设置在给定的 Connector void customize(Connector con) 作用现在,你可以用 连接器 我找不到有用的文档,但 createConnector() 函数 this guys personal Spring-embedded-Tomcat project 是一个非常实用的指南。我的实现结果是这样的:

    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 -storepass pkcs12 正如其他地方报道的那样),这起到了作用。此外,最好提供参数(端口、密码等)作为测试等配置设置。。。我相信,如果您能让@Value注释与Groovy一起使用,这是可能的。

        4
  •  0
  •   Community CDub    10 年前

    如果您不想实施 connector customizer ,您可以构建和导入库( https://github.com/ycavatars/spring-boot-https-kit )它提供了预定义的 连接器定制器 。根据自述文件,您只需要创建密钥库,配置 connector.https.* ,导入库并添加 @ComponentScan("org.ycavatars.sboot.kit") 。然后您将拥有HTTPS连接。