spring-boot - Spring Boot Jetty 自动重定向 HTTP(端口 80)请求到 HTTPS(端口 8443)

标签 spring-boot embedded-jetty http-redirect

我有以下代码来配置 Jetty 服务器:

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

application.properties 为

server.port=8443
server.ssl.key-store=classpath:keystore
server.ssl.key-store-password=xyzxyzxyz
server.ssl.key-password=xyzxyzxyz

当我访问 localhost:8443 但无法访问 localhost:80 时,我的应用程序正常运行。 gradlew bootRun 提到

... Jetty 在端口 8443(ssl、http/1.1)、80 (http/1.1) 上启动,上下文路径为“/” ...

但是访问http://localhost:80我收到消息

无法访问此站点...本地主机拒绝连接。

我在找http://localhost:80被重定向到 https://localhost:8443 .

我让它在 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;
    }

但无法找到 Jetty 的等效项。非常感谢任何指点。

最佳答案

您在端口 80 ServerConnector 上缺少所需的 HttpConfiguration 以告知 Jetty 您的安全端口与不安全端口是什么。

Jetty 端 SecuredRedirectHandler 是重定向的实际功能。

参见:https://github.com/jetty-project/embedded-jetty-cookbook/blob/master/src/main/java/org/eclipse/jetty/cookbook/SecuredRedirectHandlerExample.java

SecuredRedirectHandlerExample.java

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

关于spring-boot - Spring Boot Jetty 自动重定向 HTTP(端口 80)请求到 HTTPS(端口 8443),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49283130/

相关文章:

nginx - nginx将HTTPS重定向到HTTP

java - Spring JPA,@JointTable 注释不起作用

java - Spring Boot/Java 应用程序中的实体错误

java - Spring boot ConfigurationProperties - 注入(inject)带有比较器的 TreeMap

java - 带有 envers 的应用程序在架构验证 : REV column is of wrong type - found [int8 (Types#BIGINT)], 上失败,但需要 [int4 (Types#INTEGER)]

java - 带有单页应用程序的嵌入式 jetty

找不到 javax.servlet.http.HttpServletResponse.getStatus()

java - Jersey:如何将 Jackson 添加到 Servlet Holder

Python Spotify OAuth 流程

ssl - 在对指向同一文件夹的多个网站使用 SSL 重定向时保留 URL