Andreas Gottardi
Andreas Gottardi

Reputation: 53

SpringBoot 2.0 use http and https but redirect http to https on https-port

I have a SpringBoot 2.0 application which uses http and https. So on port 9080 it serves the http protocol and on port 9443 https, which works fine. The only thing I'd like to have is a redirection, if a user types in for example: http://localhost:9443/e1

To sum it up:

http://localhost:9080/e1 >> works as expected.

https://localhost:9443/e1 >> works as expected.

http://localhost:9443/e1 >> brings the error Bad Request. This combination of host and port requires TLS. but should get redirected to https://localhost:9443/e1.

@SpringBootApplication
@EnableScheduling
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    /* HTTP(S) configuration */

    @Value("${http.port}")
    private int httpPort;

    @Bean
    public ServletWebServerFactory servletContainer() {
        TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
        tomcat.addAdditionalTomcatConnectors(createStandardConnector());
        return tomcat;
    }

    private Connector createStandardConnector() {
        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
        connector.setPort(httpPort);
        return connector;
    }
}

My application.properties is

server.port=9443
http.port=9080
server.ssl.enabled=true
server.ssl.key-store-type=PKCS12
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-password=my_passowrd
server.ssl.key-alias=my_alias

Maybe someone has an idea on how to solve it. Thanks and have a good day :-)

Upvotes: 4

Views: 8792

Answers (3)

LHZ
LHZ

Reputation: 1

Maybe you can try to put your code in the configuration class, I did it this way and there is no problem.the version I use is 2.3.4.RELEASE

@Configuration
public class TomcatConfig {
    @Value("${server.http.port}")
    private int httpPort;

    @Bean
    public ServletWebServerFactory servletContainer() {
        TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory();
        tomcat.addAdditionalTomcatConnectors(createStandardConnector()); // 添加http
        return tomcat;
    }

    private Connector createStandardConnector() {
        Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
        connector.setPort(httpPort);
        return connector;
    }
}

If you still can’t solve your problem, I’m very sorry, I hope you can solve this problem as soon as possible

Upvotes: 0

ejazazeem
ejazazeem

Reputation: 551

For Springboot 2.x you can use the following.

    @Bean
public TomcatServletWebServerFactory tomcatFactory() {
    TomcatServletWebServerFactory tomcatFactory = new TomcatServletWebServerFactory() {
        @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);
        }
    };

    tomcatFactory.addAdditionalTomcatConnectors(redirectConnector());
    return tomcatFactory;
}

private Connector redirectConnector() {
    Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
    connector.setScheme("http");
    connector.setPort(80);
    connector.setSecure(false);
    connector.setRedirectPort(443);

    return connector;
}

Upvotes: 0

mota
mota

Reputation: 203

If you are using embedded Tomcat, you can modify returned message to contain redirect header.

E.g. for Tomcat 9.0.x:

TLSClientHelloExtractor.USE_TLS_RESPONSE = ("HTTP/1.1 302 \r\n"
    + "Content-Type: text/plain;charset=UTF-8\r\n" + "Location: https://" + hostnamePort + "\r\n"
    + "Connection: close\r\n" + "\r\n" + "Bad Request\r\n"
    + "This combination of host and port requires TLS.\r\n"
    + "Please access this URL with HTTPS scheme.\r\n").getBytes(StandardCharsets.UTF_8);

Note that this is static value and can redirect only to one URL, unless you provide your own secure channel implementation.

Upvotes: 1

Related Questions