title: Spring Boot: redirect from HTTP to HTTPS results in 405 error for PUT method
body: <p>I have a problem very similar to this one: <a href="https://stackoverflow.com/questions/42108498/redirect-post-method-http-https-http-status-405-spring-boot">Redirect Post method HTTP -&gt; HTTPS - HTTP Status 405 (Spring boot)</a></p>
  
  <p>Basically, I'm trying to make Spring Boot serve both HTTP and HTTPS with the redirection from HTTP to HTTPS. It works, but only for GET requests. If I perform PUT request, I get "Request method 'GET' not supported" error, so looks like my PUT request is being converted to GET request somewhere somehow. </p>
  
  <p>I tried both ways of configuring such redirect: define HTTPS connectivity in <code>application.properties</code> and then add HTTP programmatically and vise versa. Neither is working.</p>
  
  <p>Here's the first approach:</p>
  
  <pre><code>@Bean
  public EmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
      TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory() {
          @Override
          protected void postProcessContext(Context context) {
              SecurityConstraint securityConstraint = new SecurityConstraint();
              securityConstraint.setUserConstraint("CONFIDENTIAL");
              SecurityCollection collection = new SecurityCollection();
              collection.addPattern("/*");
              securityConstraint.addCollection(collection);
              context.addConstraint(securityConstraint);
          }
      };
      addHTTPConnector(factory);
      return factory;
  }
  
  private void addHTTPConnector(TomcatEmbeddedServletContainerFactory factory) {
      Connector connector = new Connector(TomcatEmbeddedServletContainerFactory.DEFAULT_PROTOCOL);
      connector.setScheme("http");
      connector.setPort(8080);
      connector.setRedirectPort(8443);
      connector.setSecure(false);
      Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
      protocol.setSSLEnabled(false);
      factory.addAdditionalTomcatConnectors(connector);
  }
  </code></pre>
  
  <p>With <code>application.properties</code>:</p>
  
  <pre><code>server.port=8443
  server.ssl.key-store=keystore.p12
  server.ssl.key-store-password=password
  server.ssl.keyStoreType=PKCS12
  server.ssl.keyAlias=alias
  </code></pre>
  
  <p>Here's the second approach:</p>
  
  <pre><code>@Bean
  public EmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
      TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory() {
          @Override
          protected void postProcessContext(Context context) {
              SecurityConstraint securityConstraint = new SecurityConstraint();
              securityConstraint.setUserConstraint("CONFIDENTIAL");
              SecurityCollection collection = new SecurityCollection();
              collection.addPattern("/*");
              securityConstraint.addCollection(collection);
              context.addConstraint(securityConstraint);
          }
      };
      addHTTPSConnector(factory);
      factory.addConnectorCustomizers((TomcatConnectorCustomizer) connector -&gt; connector.setRedirectPort(8443));
      return factory;
  }
  
  private void addHTTPSConnector(TomcatEmbeddedServletContainerFactory factory) {
      Connector connector = new Connector(TomcatEmbeddedServletContainerFactory.DEFAULT_PROTOCOL);
      connector.setScheme("https");
      connector.setPort(8443);
      connector.setSecure(true);
      Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
      protocol.setSSLEnabled(true);
      protocol.setKeystoreFile("keystore.p12");
      protocol.setKeystorePass("password");
      protocol.setKeystoreType("pkcs12");
      protocol.setKeystoreProvider("SunJSSE");
      protocol.setKeyAlias("alias");
      factory.addAdditionalTomcatConnectors(connector);
  }
  </code></pre>
  
  <p>For both I also have</p>
  
  <pre><code>@Configuration
  public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
  
      @Override
      protected void configure(HttpSecurity http) throws Exception {
          http.requiresChannel().anyRequest().requiresSecure();
      }
  
  }
  </code></pre>
  
  <p>in order to make redirect work.</p>
  
  <p>I have also seen this answer: <a href="https://stackoverflow.com/questions/39528694/spring-boot-request-method-get-not-supported-while-redirecting-post-request">Spring Boot &quot;Request method &#39;GET&#39; not supported&quot; while redirecting POST request to https port through Catalina Connector</a></p>
  
  <p>But I don't know what is "DEFAULT_PROTOCOL" constant. I tried adding all the methods there (POST, PUT, DELETE, GET, etc.), but it didn't help.</p>