6

I have a simple spring boot application that already runs: I can curl to hit the endpoints, etc.

I'm trying to configure it for use with HTTPS per the spring boot reference guide (pg 115) and added code like so to my @Configuration class:

@Bean
@Inject
public EmbeddedServletContainerCustomizer tomcatCustomizer(@Value("${keystore.file}") String keystoreFile,
                                                           @Value("${keystore.password}") String keystorePassword,
                                                           @Value("${keystore.type}") String keystoreType,
                                                           @Value("${keystore.alias}") String keystoreAlias) throws FileNotFoundException
{
    final String absoluteKeystoreFile = ResourceUtils.getFile(keystoreFile).getAbsolutePath();
    EmbeddedServletContainerCustomizer tomcatCustomizer = (ConfigurableEmbeddedServletContainer factory) -> {
        TomcatEmbeddedServletContainerFactory containerFactory = (TomcatEmbeddedServletContainerFactory) factory;
        containerFactory.addConnectorCustomizers((TomcatConnectorCustomizer) (Connector connector) -> {
            connector.setSecure(true);
            connector.setScheme("https");
            connector.setAttribute("keystoreFile", absoluteKeystoreFile);
            connector.setAttribute("keystorePass", keystorePassword);
            connector.setAttribute("keystoreType", keystoreType);
            connector.setAttribute("keyAlias", keystoreAlias);
            connector.setAttribute("clientAuth", "false");
            connector.setAttribute("sslProtocol", "TLS");
            connector.setAttribute("SSLEnabled", true);
        });
    };

    return tomcatCustomizer;
}

However, with only this code addition, my previously working app now gets the following stack trace:

Caused by: java.lang.IllegalArgumentException: A ServletContext is required to configure default servlet handling
at org.springframework.util.Assert.notNull(Assert.java:112)
at org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer.<init>(DefaultServletHandlerConfigurer.java:54)
at org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.defaultServletHandlerMapping(WebMvcConfigurationSupport.java:346)
at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerBySpringCGLIB$$f697b5e2.CGLIB$defaultServletHandlerMapping$23(<generated>)
at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerBySpringCGLIB$$f697b5e2$$FastClassBySpringCGLIB$$972d2616.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:312)
at org.springfr.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerBySpringCGLIB$$f697b5e2.defaultServletHandlerMapping(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:166)
... 16 more

I verified that the properties are coming in correctly to the method, and tried adding/removing @WebAppConfiguration as suggested by this question

My gradle file is using spring-boot-starter-web:1.0.0.RELEASE.

The questions are: How do I correctly configure https with spring boot? Why does my the app work when I don't try to configure tomcat, and break when I do try to configure tomcat?

Thanks

Community
  • 1
  • 1
Jason
  • 7,356
  • 4
  • 41
  • 48

1 Answers1

11

Just after posting this question, I discovered the answer:

For how to correctly configure https with spring boot: The code listed above was originally added to my @Configuration SecurityConfig extends WebSecurityConfigurerAdapter. When I moved the tomcat customization to its own @Configuration class, it worked.

For why: Presumably the WebSecurityConfigurerAdapter is called earlier in the application context lifecycle than the rest of the @Configurations.

Jason
  • 7,356
  • 4
  • 41
  • 48
  • 1
    Correct. Security lives in a `Filter` and they have to be registered early. – Dave Syer Apr 11 '14 at 09:47
  • I'm struggling with switching certain configuration parts in separate `@Configuration` over and over again. Would you please have a link which describes the behaviour you mentioned? Or some generic source of info on how the order of `@Configuration` works and what should be taken care of? – Jan Zyka Sep 29 '14 at 05:53
  • Correct, I add this into WebSecurityConfigurerAdapter and it won't work. after change to @Configuration it works. – Aaric Chen Aug 23 '17 at 03:22