Reputation: 163
I have the following code to configure Jetty server:
@Configuration
public class RedirectHttpToHttpsOnJetty2Config {
@Bean
public ConfigurableServletWebServerFactory webServerFactory() {
JettyServletWebServerFactory factory = new JettyServletWebServerFactory();
factory.addServerCustomizers(new JettyServerCustomizer() {
@Override
public void customize(Server server) {
ServerConnector connector = new ServerConnector(server);
connector.setPort(80);
server.addConnector(connector);
}
});
return factory;
}
}
and
application.properties as
server.port=8443
server.ssl.key-store=classpath:keystore
server.ssl.key-store-password=xyzxyzxyz
server.ssl.key-password=xyzxyzxyz
My applications works expectedly when I access localhost:8443 but localhost:80 is not reachable. gradlew bootRun mentions
... Jetty started on port(s) 8443 (ssl, http/1.1), 80 (http/1.1) with context path '/' ...
but upon visiting http://localhost:80 I get the message
This site can’t be reached... localhost refused to connect.
I am looking for http://localhost:80 getting redirected to https://localhost:8443.
I had it working in Tomcat:
@Bean
public ServletWebServerFactory servletContainer(){
TomcatServletWebServerFactory tomcat = 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);
}
};
tomcat.addAdditionalTomcatConnectors(redirectConnector());
return tomcat;
}
private Connector redirectConnector(){
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http");
connector.setPort(80);
connector.setSecure(false);
connector.setRedirectPort(8443);
return connector;
}
But unable to find an equivalent for Jetty. Any pointers much appreciated.
Upvotes: 3
Views: 3313
Reputation: 7106
The following configuration will set up a redirect from HTTP to HTTPS. It assumes that you already configure Spring Boot to listen on port 443 and SSL is configured properly.
@Bean
public ConfigurableServletWebServerFactory webServerFactory() {
JettyServletWebServerFactory factory = new JettyServletWebServerFactory();
factory.addServerCustomizers(new JettyServerCustomizer() {
@Override
public void customize(Server server) {
final HttpConnectionFactory httpConnectionFactory = server.getConnectors()[0].getConnectionFactory(HttpConnectionFactory.class);
final ServerConnector httpConnector = new ServerConnector(server, httpConnectionFactory);
httpConnector.setPort(80 /* HTTP */);
server.addConnector(httpConnector);
final HandlerList handlerList = new HandlerList();
handlerList.addHandler(new SecuredRedirectHandler());
for(Handler handler : server.getHandlers())
handlerList.addHandler(handler);
server.setHandler(handlerList);
}
});
return factory;
}
Upvotes: 2
Reputation: 49462
You are missing the required HttpConfiguration
on your port 80 ServerConnector
to tell Jetty what your secure vs unsecured ports are.
The Jetty side SecuredRedirectHandler
is how the redirect actually functions.
package org.eclipse.jetty.cookbook;
import java.net.URL;
import org.eclipse.jetty.cookbook.handlers.HelloHandler;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.SecureRequestCustomizer;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.SslConnectionFactory;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.SecuredRedirectHandler;
import org.eclipse.jetty.util.ssl.SslContextFactory;
public class SecuredRedirectHandlerExample
{
public static void main(String[] args) throws Exception
{
Server server = new Server();
int httpPort = 8080;
int httpsPort = 8443;
// Setup HTTP Connector
HttpConfiguration httpConf = new HttpConfiguration();
httpConf.setSecurePort(httpsPort);
httpConf.setSecureScheme("https");
// Establish the HTTP ServerConnector
ServerConnector httpConnector = new ServerConnector(server,
new HttpConnectionFactory(httpConf));
httpConnector.setPort(httpPort);
server.addConnector(httpConnector);
// Find Keystore for SSL
ClassLoader cl = SecuredRedirectHandlerExample.class.getClassLoader();
String keystoreResource = "ssl/keystore";
URL f = cl.getResource(keystoreResource);
if (f == null)
{
throw new RuntimeException("Unable to find " + keystoreResource);
}
// Setup SSL
SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setKeyStorePath(f.toExternalForm());
sslContextFactory.setKeyStorePassword("OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4");
sslContextFactory.setKeyManagerPassword("OBF:1u2u1wml1z7s1z7a1wnl1u2g");
// Setup HTTPS Configuration
HttpConfiguration httpsConf = new HttpConfiguration(httpConf);
httpsConf.addCustomizer(new SecureRequestCustomizer()); // adds ssl info to request object
// Establish the HTTPS ServerConnector
ServerConnector httpsConnector = new ServerConnector(server,
new SslConnectionFactory(sslContextFactory,"http/1.1"),
new HttpConnectionFactory(httpsConf));
httpsConnector.setPort(httpsPort);
server.addConnector(httpsConnector);
// Add a Handlers for requests
HandlerList handlers = new HandlerList();
handlers.addHandler(new SecuredRedirectHandler()); // always first
handlers.addHandler(new HelloHandler("Hello Secure World"));
handlers.addHandler(new DefaultHandler()); // always last
server.setHandler(handlers);
server.start();
server.join();
}
}
Upvotes: 3