在嵌入式码头中自动从http重定向到https

时间:2014-09-30 14:41:37

标签: https jetty

我的要求是当我在浏览器中输入网址http://ip:port时,它会自动跳转到https://ip:port,我是如何通过嵌入方式使用jetty来实现的。

我按如下方式启动https服务器,但不知道如何实现自动直接,我的码头版本是8.1.14.v20131031

val server = new Server
val ctxFactory = new SslContextFactory()
ctxFactory.setNeedClientAuth(false)
ctxFactory.setKeyManagerPassword("123456")
ctxFactory.setKeyStorePath("./resources/hello.keystore")
ctxFactory.setKeyStorePassword("123456")
ctxFactory.setKeyStoreType("jks")
val connector = new SslSelectChannelConnector(ctxFactory)
connector.setHost("localhost")
connector.setPort(8888)

server.addConnector(connector)

val handler = new hello
val handlers = ArrayBuffer[org.eclipse.jetty.server.Handler]()

handlers += handler

val handlerlist = new HandlerList
handlerlist.setHandlers(handlers.toArray)
server.setHandler(handlerlist);
server.start();
server.join();

2 个答案:

答案 0 :(得分:1)

使用Jetty 9.2.3.v20140905,这里是an example of this

package jetty;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.HttpConfiguration;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Request;
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.AbstractHandler;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.util.URIUtil;
import org.eclipse.jetty.util.ssl.SslContextFactory;

public class SecureContexts
{
    public static class SecureSchemeHandler extends AbstractHandler
    {
        @Override
        public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
        {
            HttpConfiguration httpConfig = HttpChannel.getCurrentHttpChannel().getHttpConfiguration();

            if (baseRequest.isSecure())
            {
                return; // all done
            }

            if (httpConfig.getSecurePort() > 0)
            {
                String scheme = httpConfig.getSecureScheme();
                int port = httpConfig.getSecurePort();

                String url = URIUtil.newURI(scheme,baseRequest.getServerName(),port,baseRequest.getRequestURI(),baseRequest.getQueryString());
                response.setContentLength(0);
                response.sendRedirect(url);
            }
            else
            {
                response.sendError(HttpStatus.FORBIDDEN_403,"!Secure");
            }

            baseRequest.setHandled(true);
        }
    }

    public static class HelloHandler extends AbstractHandler
    {
        private final String msg;

        public HelloHandler(String msg)
        {
            this.msg = msg;
        }

        @Override
        public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
        {
            response.setContentType("text/plain");
            response.getWriter().printf("%s%n",msg);
            baseRequest.setHandled(true);
        }
    }

    public static class RootHandler extends AbstractHandler
    {
        private final String[] childContexts;

        public RootHandler(String ... children)
        {
            this.childContexts = children;
        }

        @Override
        public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
        {
            response.setContentType("text/html");
            PrintWriter out = response.getWriter();
            out.println("<html>");
            out.println("<head><title>Contexts</title></head>");
            out.println("<body>");
            out.println("<h4>Child Contexts</h4>");
            out.println("<ul>");
            for(String child: childContexts) {
                out.printf("<li><a href=\"%s\">%s</a></li>%n",child,child);
            }
            out.println("</ul>");
            out.println("</body></html>");
            baseRequest.setHandled(true);
        }
    }

    public static void main(String[] args) throws Exception
    {
        Server server = new Server();
        // the normal unsecured http port
        int port = 12080;
        // the secured http+ssl (https) port
        int securePort = 12443;

        // Setup SSL
        SslContextFactory sslContextFactory = new SslContextFactory();
        sslContextFactory.setKeyStorePath(System.getProperty("jetty.keystore.path","C:/keystore.jks"));
        sslContextFactory.setKeyStorePassword(System.getProperty("jetty.keystore.password","password"));
        sslContextFactory.setKeyManagerPassword(System.getProperty("jetty.keymanager.password","password"));

        // Setup HTTP Configuration
        HttpConfiguration httpConf = new HttpConfiguration();
        httpConf.setSecurePort(securePort);
        httpConf.setSecureScheme("https");

        ServerConnector httpConnector = new ServerConnector(server, 
                new HttpConnectionFactory(httpConf));
        httpConnector.setName("unsecured"); // named connector
        httpConnector.setPort(port);

        // Setup HTTPS Configuration
        HttpConfiguration httpsConf = new HttpConfiguration(httpConf);
        httpsConf.addCustomizer(new SecureRequestCustomizer());

        ServerConnector httpsConnector = new ServerConnector(server,
                new SslConnectionFactory(sslContextFactory,"http/1.1"),
                new HttpConnectionFactory(httpsConf));
        httpsConnector.setName("secured"); // named connector
        httpsConnector.setPort(securePort);

        // Add connectors
        server.setConnectors(new Connector[] { httpConnector, httpsConnector });

        // Wire up contexts for secure handling to named connector
        String secureHosts[] = new String[] { "@secured" };

        ContextHandler test1Context = new ContextHandler();
        test1Context.setContextPath("/test1");
        test1Context.setHandler(new HelloHandler("Hello1"));
        test1Context.setVirtualHosts(secureHosts);

        ContextHandler test2Context = new ContextHandler();
        test2Context.setContextPath("/test2");
        test2Context.setHandler(new HelloHandler("Hello2"));
        test2Context.setVirtualHosts(secureHosts);

        ContextHandler rootContext = new ContextHandler();
        rootContext.setContextPath("/");
        rootContext.setHandler(new RootHandler("/test1", "/test2"));
        rootContext.setVirtualHosts(secureHosts);

        // Wire up context for unsecure handling to only
        // the named 'unsecured' connector
        ContextHandler redirectHandler = new ContextHandler();
        redirectHandler.setContextPath("/");
        redirectHandler.setHandler(new SecureSchemeHandler());
        redirectHandler.setVirtualHosts(new String[]{"@unsecured"});

        // Establish all handlers that have a context
        ContextHandlerCollection contextHandlers = new ContextHandlerCollection();
        contextHandlers.setHandlers(new Handler[]
        { redirectHandler, rootContext, test1Context, test2Context });

        // Create server level handler tree
        HandlerList handlers = new HandlerList();
        handlers.addHandler(contextHandlers);
        handlers.addHandler(new DefaultHandler()); // round things out

        server.setHandler(handlers);

        server.start();
        server.join();
    }
}

更新#1:

提交bug at eclipse to add this handler as a standard feature

更新#2:

Resolved/Fixed bug,新的org.eclipse.jetty.server.handlers.SecuredRedirectHandler将在下一个Jetty版本中提供。

答案 1 :(得分:0)

//this works for jetty 8

package jetty;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException; 
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;    
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;    
import org.eclipse.jetty.server.handler.DefaultHandler;    
import org.eclipse.jetty.server.handler.HandlerList;    
import org.eclipse.jetty.server.nio.SelectChannelConnector;    
import org.eclipse.jetty.server.ssl.SslSelectChannelConnector;   
import org.eclipse.jetty.util.ssl.SslContextFactory;

public class SecureContexts0
{
    private static int securePort;
    private static String schema;


    public static String newURI(String scheme,String server, int port,String path,String query)
    {
        System.out.println("scheme: "+scheme+" port: "+port);
        StringBuilder builder = newURIBuilder(scheme, server, port);
        builder.append(path);
        if (query!=null && query.length()>0)
            builder.append('?').append(query);
        return builder.toString();
    }
    public static StringBuilder newURIBuilder(String scheme,String server, int port)
    {
        StringBuilder builder = new StringBuilder();
        appendSchemeHostPort(builder, scheme, server, port);
        return builder;
    }

    public static void appendSchemeHostPort(StringBuilder url,String scheme,String server, int port)
    {
        if (server.indexOf(':')>=0&&server.charAt(0)!='[')
            url.append(scheme).append("://").append('[').append(server).append(']');
        else
            url.append(scheme).append("://").append(server);
        if (port > 0)
        {
            if(scheme == "http")
            {
                if (port!=80)
                    url.append(':').append(port);
            }
            else if(scheme == "https")
            {
                if (port!=443)
                    url.append(':').append(port);
            }
            else
            {
                url.append(':').append(port);
            }
        }
    }

    public static class SecureSchemeHandler extends AbstractHandler
    {
        @Override
        public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
        {

            if (baseRequest.isSecure())
            {
                return; // all done
            }

            if ( securePort > 0)
            {

                String url = newURI(schema,baseRequest.getServerName(),securePort,baseRequest.getRequestURI(),baseRequest.getQueryString());
                response.setContentLength(0);
                response.sendRedirect(url);
            }
            else
            {
                response.sendError(HttpStatus.FORBIDDEN_403,"!Secure");
            }

            baseRequest.setHandled(true);
        }
    }

    public static class HelloHandler extends AbstractHandler
    {
        private final String msg;

        public HelloHandler(String msg)
        {
            this.msg = msg;
        }

        @Override
        public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
        {
            response.setContentType("text/plain");
            response.getWriter().printf("%s%n",msg);
            baseRequest.setHandled(true);
        }
    }

    public static class RootHandler extends AbstractHandler
    {
        private final String[] childContexts;

        public RootHandler(String ... children)
        {
            this.childContexts = children;
        }

        @Override
        public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
        {
            response.setContentType("text/html");
            PrintWriter out = response.getWriter();
            out.println("<html>");
            out.println("<head><title>Contexts</title></head>");
            out.println("<body>");
            out.println("<h4>Child Contexts</h4>");
            out.println("<ul>");
            for(String child: childContexts) {
                out.printf("<li><a href=\"%s\">%s</a></li>%n",child,child);
            }
            out.println("</ul>");
            out.println("</body></html>");
            baseRequest.setHandled(true);
        }
    }

    public static void main(String[] args) throws Exception
    {
        Server server = new Server();
        // the normal unsecured http port
        int port = 12080;
        // the secured http+ssl (https) port
        int _securePort = 12443;

        // Setup SSL
        SslContextFactory sslContextFactory = new SslContextFactory();
        sslContextFactory.setKeyStorePath(System.getProperty("jetty.keystore.path","./hello.keystore"));
        sslContextFactory.setKeyStorePassword(System.getProperty("jetty.keystore.password","123456"));
        sslContextFactory.setKeyManagerPassword(System.getProperty("jetty.keymanager.password","123456"));
        sslContextFactory.setKeyStoreType("jks");

        SelectChannelConnector httpConnector = new SelectChannelConnector();
        httpConnector.setName("unsecured"); // named connector
        httpConnector.setPort(port);
        httpConnector.setHost("localhost");

        SslSelectChannelConnector httpsConnector = new SslSelectChannelConnector(sslContextFactory);
        httpsConnector.setName("secured"); // named connector
        httpsConnector.setPort(_securePort);
        httpConnector.setHost("localhost");

        securePort = _securePort;
        schema = "https";

        // Add connectors
        server.addConnector(httpsConnector);
        server.addConnector(httpConnector);


        ContextHandler test1Context = new ContextHandler();
        test1Context.setContextPath("/test1");
        test1Context.setHandler(new HelloHandler("Hello1"));

        ContextHandler test2Context = new ContextHandler();
        test2Context.setContextPath("/test2");
        test2Context.setHandler(new HelloHandler("Hello2"));

        ContextHandler rootContext = new ContextHandler();
        rootContext.setContextPath("/");
        rootContext.setHandler(new RootHandler("/test1", "/test2"));

        ContextHandler redirectHandler = new ContextHandler();
        redirectHandler.setContextPath("/");
        redirectHandler.setHandler(new SecureSchemeHandler());

        // Establish all handlers that have a context
        ContextHandlerCollection contextHandlers = new ContextHandlerCollection();
        contextHandlers.setHandlers(new Handler[]
                { redirectHandler,rootContext, test1Context, test2Context });

        // Create server level handler tree
        HandlerList handlers = new HandlerList();
        handlers.addHandler(contextHandlers);
        handlers.addHandler(new DefaultHandler()); // round things out

        server.setHandler(handlers);

        server.start();
        server.join();
    }
}