How can I specify my .keystore file with Spring Boot and Tomcat?

后端 未结 5 1276
面向向阳花
面向向阳花 2020-12-04 09:20

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

相关标签:
5条回答
  • 2020-12-04 09:56

    For external keystores, prefix with "file:"

    server.ssl.key-store=file:config/keystore 
    
    0 讨论(0)
  • 2020-12-04 10:03

    If you don't want to implement your connector customizer, you can build and import the library (https://github.com/ycavatars/spring-boot-https-kit) which provides predefined connector customizer. According to the README, you only have to create your keystore, configure connector.https.*, import the library and add @ComponentScan("org.ycavatars.sboot.kit"). Then you'll have HTTPS connection.

    0 讨论(0)
  • 2020-12-04 10:03

    And here's an example of the customizer implemented in Groovy:

    https://github.com/UniconLabs/orville/blob/master/web/src/main/groovy/org/apereo/openregistry/config/TomcatSslConfiguration.groovy

    0 讨论(0)
  • 2020-12-04 10:07

    Starting with Spring Boot 1.2, you can configure SSL using application.properties or application.yml. Here's an example for application.properties:

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

    Same thing with application.yml:

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

    Here's a link to the current reference documentation.

    0 讨论(0)
  • 2020-12-04 10:08

    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).

    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.

    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.

    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.

    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;
    }
    }
    

    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.

    0 讨论(0)
提交回复
热议问题