Reputation: 18228
I have hit a problem with isSecure()
returning false on request arriving on HTTPS connection, actually a HTTPS connection with valid certificates from common CA, both user and server certificates. Why?
Here is a callstack:
But the member that is returned by isSecure()
is false:
This is with Jetty 9.4.8.
UPDATE
On HttpChannelOverHttp(HttpChannel).onRequest(MetaData$Request) line: 638
I see _request.setSecure(HttpScheme.HTTPS.is(request.getURI().getScheme()));
which could set up the flag to true. Unfortunately, the URI is incomplete of //host.name:8081/path/a/b/c
format and getScheme()
returns null
which results in false
being returned by is()
. WTH?
UPDATE 2
It appears that I can fix this by adding the following to HttpConfiguration
in jetty-config.xml
:
<Call name="addCustomizer">
<Arg>
<New class="org.eclipse.jetty.server.SecureRequestCustomizer" />
</Arg>
</Call>
But it is unclear to my why is this necessary and why it does not work OOTB.
Upvotes: 1
Views: 1828
Reputation: 49452
As you have discovered yourself, you were missing a configuration.
The fact that you felt you needed to manually add this configuration tells me you are using an old version of Jetty. (please consider upgrading, it is easier to control this now, as evidenced below)
The SecureRequestCustomizer
in the HttpConfiguration
is responsible for handling the identification of SSL Certificates, SNI, Host checks, the various HttpServletRequest
attributes for SSL/TLS, etc..
It looks like this on older versions of Jetty.
<Call name="addCustomizer">
<Arg>
<New class="org.eclipse.jetty.server.SecureRequestCustomizer" />
</Arg>
</Call>
On Newer versions of Jetty this is added by the jetty-ssl.xml
xml (part of the ssl
module), and it looks like this ...
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- [snip] ssl connector setup -->
<!-- =========================================================== -->
<!-- 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>
The reason this isn't on by default is that a request can be considered secure without Jetty handling the actual SSL/TLS. This is the forwarded scenario, from a load balancer, proxy, firewall, gateway, etc... In that scenario, the SSL/TLS is handled by another process, which talks to Jetty via a non-secure channel (standard HTTP without encryption, proxy, unix sockets, etc). The fact that the connection is secure or not is then communicated to jetty via "forwarded" headers.
This forwarded behavior is controlled by a different customizer org.eclipse.jetty.server.ForwardedRequestCustomizer
(found in jetty-http-forwarded.xml
, which part of the http-forwarded
module)
Upvotes: 1