Jetty实战之 嵌入式运行Jetty 配置Https

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Jetty实战之 嵌入式运行Jetty 配置Https相关的知识,希望对你有一定的参考价值。

在开发Java web项目时候,可以在项目中嵌入Jetty服务的方式来运行web程序。

嵌入式Jetty服务比较简洁,不用在服务器再部署其他服务。

本人用的Jetty9.3,其他版本的应该也差不多,我见过别人的嵌入式Jetty服务,他们都是把一些配置参数写死在代码里,不利于维护,我是做了进一步的改进,把配置参数放在配置文件,然后直接把配置参数读到相应的类里。

首先列一下Jetty项目里比较重要的xml:jetty-https.xml,jetty-ssl.xml,jetty-ssl-context.xml,jetty.xml

jetty-https.xml

技术分享
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">

<!-- ============================================================= -->
<!-- Configure a HTTPS connector.                                  -->
<!-- This configuration must be used in conjunction with jetty.xml -->
<!-- and jetty-ssl.xml.                                            -->
<!-- ============================================================= -->
<Configure id="sslConnector" class="org.eclipse.jetty.server.ServerConnector">

  <Call name="addIfAbsentConnectionFactory">
    <Arg>
      <New class="org.eclipse.jetty.server.SslConnectionFactory">
        <Arg name="next">http/1.1</Arg>
        <Arg name="sslContextFactory"><Ref refid="sslContextFactory"/></Arg>
      </New>
    </Arg>
  </Call>

  <Call name="addConnectionFactory">
    <Arg>
      <New class="org.eclipse.jetty.server.HttpConnectionFactory">
        <Arg name="config"><Ref refid="sslHttpConfig" /></Arg>
        <Arg name="compliance">
        <Call class="org.eclipse.jetty.http.HttpCompliance" name="valueOf">
        <Arg>
        <Property name="jetty.http.compliance" default="RFC7230"/>
        </Arg></Call></Arg>
      </New>
    </Arg>
  </Call>
  
</Configure>
View Code

jetty-ssl.xml

技术分享
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">

<!-- ============================================================= -->
<!-- Base SSL configuration                                        -->
<!-- This configuration needs to be used together with 1 or more   -->
<!-- of jetty-https.xml or jetty-http2.xml                         -->
<!-- ============================================================= -->
<Configure id="Server" class="org.eclipse.jetty.server.Server">

  <!-- =========================================================== -->
  <!-- Add a SSL Connector with no protocol factories              -->
  <!-- =========================================================== -->
  <Call  name="addConnector">
    <Arg>
      <New id="sslConnector" class="org.eclipse.jetty.server.ServerConnector">
        <Arg name="server"><Ref refid="Server" /></Arg>
        <Arg name="acceptors" type="int"><Property name="jetty.ssl.acceptors" deprecated="ssl.acceptors" default="-1"/></Arg>
        <Arg name="selectors" type="int"><Property name="jetty.ssl.selectors" deprecated="ssl.selectors" default="-1"/></Arg>
        <Arg name="factories">
          <Array type="org.eclipse.jetty.server.ConnectionFactory">
            <!-- uncomment to support proxy protocol
            <Item>
              <New class="org.eclipse.jetty.server.ProxyConnectionFactory"/>
            </Item>-->
          </Array>
        </Arg>

        <Set name="host"><Property name="jetty.ssl.host" deprecated="jetty.host" /></Set>
        <Set name="port"><Property name="jetty.ssl.port" deprecated="ssl.port" default="8443" /></Set>
        <Set name="idleTimeout"><Property name="jetty.ssl.idleTimeout" deprecated="ssl.timeout" default="30000"/></Set>
        <Set name="soLingerTime"><Property name="jetty.ssl.soLingerTime" deprecated="ssl.soLingerTime" default="-1"/></Set>
        <Set name="acceptorPriorityDelta"><Property name="jetty.ssl.acceptorPriorityDelta" deprecated="ssl.acceptorPriorityDelta" default="0"/></Set>
        <Set name="acceptQueueSize"><Property name="jetty.ssl.acceptQueueSize" deprecated="ssl.acceptQueueSize" default="0"/></Set>
      </New>
    </Arg>
  </Call>

  <!-- =========================================================== -->
  <!-- Create a TLS specific HttpConfiguration based on the        -->
  <!-- common HttpConfiguration defined in jetty.xml               -->
  <!-- Add a SecureRequestCustomizer to extract certificate and    -->
  <!-- session information                                         -->
  <!-- =========================================================== -->
  <New id="sslHttpConfig" class="org.eclipse.jetty.server.HttpConfiguration">
    <Arg><Ref refid="httpConfig"/></Arg>
    <Call name="addCustomizer">
      <Arg>
        <New class="org.eclipse.jetty.server.SecureRequestCustomizer">
          <Arg name="sniHostCheck" type="boolean"><Property name="jetty.ssl.sniHostCheck" default="true"/></Arg>
          <Arg name="stsMaxAgeSeconds" type="int"><Property name="jetty.ssl.stsMaxAgeSeconds" default="-1"/></Arg>
          <Arg name="stsIncludeSubdomains" type="boolean"><Property name="jetty.ssl.stsIncludeSubdomains" default="false"/></Arg>
        </New>
      </Arg>
    </Call>
  </New>

</Configure>
View Code

jetty-ssl-context.xml

技术分享
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">

<!-- ============================================================= -->
<!-- SSL ContextFactory configuration                              -->
<!-- ============================================================= -->

<!-- 
  To configure Includes / Excludes for Cipher Suites or Protocols see tweak-ssl.xml example at 
     https://www.eclipse.org/jetty/documentation/current/configuring-ssl.html#configuring-sslcontextfactory-cipherSuites
-->

<Configure id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory">
  <Set name="KeyStorePath"><Property name="jetty.base" default="." />/<Property name="jetty.sslContext.keyStorePath" deprecated="jetty.keystore" default="etc/keystore"/></Set>
  <Set name="KeyStorePassword"><Property name="jetty.sslContext.keyStorePassword" deprecated="jetty.keystore.password" default="OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4"/></Set>
  <Set name="KeyStoreType"><Property name="jetty.sslContext.keyStoreType" default="JKS"/></Set>
  <Set name="KeyStoreProvider"><Property name="jetty.sslContext.keyStoreProvider"/></Set>
  <Set name="KeyManagerPassword"><Property name="jetty.sslContext.keyManagerPassword" deprecated="jetty.keymanager.password" default="OBF:1u2u1wml1z7s1z7a1wnl1u2g"/></Set>
  <Set name="TrustStorePath"><Property name="jetty.base" default="." />/<Property name="jetty.sslContext.trustStorePath" deprecated="jetty.truststore" default="etc/keystore"/></Set>
  <Set name="TrustStorePassword"><Property name="jetty.sslContext.trustStorePassword" deprecated="jetty.truststore.password"/></Set>
  <Set name="TrustStoreType"><Property name="jetty.sslContext.trustStoreType"/></Set>
  <Set name="TrustStoreProvider"><Property name="jetty.sslContext.trustStoreProvider"/></Set>
  <Set name="EndpointIdentificationAlgorithm"></Set>
  <Set name="NeedClientAuth"><Property name="jetty.sslContext.needClientAuth" deprecated="jetty.ssl.needClientAuth" default="false"/></Set>
  <Set name="WantClientAuth"><Property name="jetty.sslContext.wantClientAuth" deprecated="jetty.ssl.wantClientAuth" default="false"/></Set>
  <Set name="useCipherSuitesOrder"><Property name="jetty.sslContext.useCipherSuitesOrder" default="true"/></Set>
  <Set name="sslSessionCacheSize"><Property name="jetty.sslContext.sslSessionCacheSize" default="-1"/></Set>
  <Set name="sslSessionTimeout"><Property name="jetty.sslContext.sslSessionTimeout" default="-1"/></Set>
  <Set name="RenegotiationAllowed"><Property name="jetty.sslContext.renegotiationAllowed" default="true"/></Set>
  <Set name="RenegotiationLimit"><Property name="jetty.sslContext.renegotiationLimit" default="5"/></Set>
</Configure>
View Code

源包里这几个xml文件是分别独立的,在配置https的时候是需要我们把这三个xml融合到jetty.xml文件里面的,自己经历过各种尝试,分别读三个文件,但并没有什么乱用,各种失败,最后自己想想了,之前用的http就是放在jetty文件里的,要配置https那肯定也能放到jetty里面。

具体的步骤如下:

1、先把jetty-ssl.xml里面的<Call  name="addConnector">节点添加到jetty.xml文件里。

2、在jetty.xml文件里刚才添加的<Call  name="addConnector">节点下<Array type="org.eclipse.jetty.server.ConnectionFactory">添加jetty-https.xml文件下的<New class="org.eclipse.jetty.server.SslConnectionFactory">节点和

<New class="org.eclipse.jetty.server.HttpConnectionFactory">
<Arg name="config"><Ref refid="sslHttpConfig" /></Arg>
</New>

3、把jetty-ssl.xml下的<New id="sslHttpConfig" class="org.eclipse.jetty.server.HttpConfiguration">节点和jetty-ssl-context.xml(需要注意的一点是:需要把Configure改成New)里面的整个节点。

配置已经修改完,然后具体的相关配置根据自己的需要进行相应配置,需要注意的是,jetty.xml文件的节点顺序,New节点相当于声明变量,需要放在最顶部,要不然编译会报错。

 

接下来就是读取jetty.xml和jetty-jmx.xml文件到server的代码

public class HttpsServer {
    private static final String[] CFG_FILES = {"jetty.xml", "jetty-jmx.xml"};
    private Server server;

    public HttpsServer() {
        server = new Server();
    }

    public void start() throws Exception {
        if (server.isRunning()) {
            return;
        }

        ClassLoader loader = HttpServer.class.getClassLoader();

        for (String fileName : CFG_FILES) {

            InputStream stream = loader.getResourceAsStream(fileName);

            if (stream != null) {
                XmlConfiguration config = new XmlConfiguration(stream);
                stream.close();
                config.configure(this.server);
            }
        }

        server.start();
    }



    public int getPort() {
        return ((ServerConnector) server.getConnectors()[0]).getPort();
    }

    public void stop() throws Exception {
        if (server != null) {
            server.stop();
        }
    }
}

 

搞定,再说一下配置Https可能遇到的问题:

1、keystore 这个需要在linux生成,网上有现成的命令,并且需要把这个文件的正确路径要填写到配置文件里

2、注意节点的次序

 

以上是关于Jetty实战之 嵌入式运行Jetty 配置Https的主要内容,如果未能解决你的问题,请参考以下文章

Jetty实战之 安装 运行 部署

Jetty入门(1-2)配置Jetty - 独立运行模式

jetty插件

Jetty 9.0 SPDY 嵌入式配置

如何配置嵌入式 Jetty 以处理 OPTIONS 预检请求?

使用 mvn jetty:run 运行嵌入式 H2 数据库