Skip to content

Commit ce85fe8

Browse files
committed
Finish HTTPS
- cleanup code - supports pkcs12 and x509 certificates - add SSLHandler - add javadoc - add documentation - add ctx.getRequestURL - add tests
1 parent 204ef23 commit ce85fe8

File tree

39 files changed

+1911
-418
lines changed

39 files changed

+1911
-418
lines changed

docs/asciidoc/handlers.adoc

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@ include::handlers/cors.adoc[]
66

77
include::handlers/head.adoc[]
88

9+
include::handlers/ssl.adoc[]
10+
911
include::handlers/trace.adoc[]

docs/asciidoc/handlers/ssl.adoc

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
=== SSLHandler
2+
3+
The javadoc:SSLHandler[] forces client to use HTTPS by redirecting non-HTTPS calls to the HTTPS version.
4+
5+
.Force SSL
6+
[source, java, role = "primary"]
7+
----
8+
import io.jooby.Jooby;
9+
import io.jooby.SSLHandler;
10+
...
11+
{
12+
13+
setServerOptions(new ServerOptions().setSecurePort(8443));
14+
15+
before(new SSLHandler(false)); <1>
16+
17+
get("/", ctx -> {
18+
return ctx.getScheme();
19+
});
20+
}
21+
----
22+
23+
.Kotlin
24+
[source, kotlin, role = "secondary"]
25+
----
26+
import io.jooby.Jooby
27+
import io.jooby.SSHandler
28+
...
29+
{
30+
serverOptions {
31+
securePort = 8443
32+
}
33+
34+
before(SSLHandler(false)) <1>
35+
36+
get("/") {
37+
...
38+
}
39+
}
40+
----
41+
42+
<1> Install SSLHandler
43+
44+
The SSL Handler recreates the HTTPs URL version using the `Host` header, if you are behind a proxy
45+
you will need to use the `X-Forwarded-Host` header. To do that just pass `true` to the SSLHandler.
46+
47+
Optionally, you can specify the host to use:
48+
49+
.Force SSL
50+
[source, java, role = "primary"]
51+
----
52+
import io.jooby.Jooby;
53+
import io.jooby.SSLHandler;
54+
...
55+
{
56+
57+
setServerOptions(new ServerOptions().setSecurePort(8443));
58+
59+
before(new SSLHandler("myhost.org")); <1>
60+
61+
get("/", ctx -> {
62+
return ctx.getScheme();
63+
});
64+
}
65+
----
66+
67+
.Kotlin
68+
[source, kotlin, role = "secondary"]
69+
----
70+
import io.jooby.Jooby
71+
import io.jooby.SSHandler
72+
...
73+
{
74+
serverOptions {
75+
securePort = 8443
76+
}
77+
78+
before(SSLHandler("myhost.org")) <1>
79+
80+
get("/") {
81+
ctx.scheme
82+
}
83+
}
84+
----
85+
86+
For more information about SSL, please check the <<server-ssl, configure SSL>> section.

docs/asciidoc/servers.adoc

Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ Server options are available via javadoc:ServerOptions[] class:
4545
.setSingleLoop(false)
4646
.setDefaultHeaders(true)
4747
.setMaxRequestSize(10485760)
48+
.setSecurePort(8433)
49+
.setSsl(SslOptions.selfSigned())
4850
);
4951
}
5052
----
@@ -62,6 +64,8 @@ Server options are available via javadoc:ServerOptions[] class:
6264
singleLoop = false
6365
defaultHeaders = true
6466
maxRequestSize = 10485760
67+
securePort = 8443
68+
ssl = SslOptions.selfSigned()
6569
}
6670
}
6771
----
@@ -74,6 +78,8 @@ Server options are available via javadoc:ServerOptions[] class:
7478
- singleLoop: Indicates if the web server should use a single loop/group for doing IO or not. **Netty only**.
7579
- defaultHeaders: Configure server to set the following headers: `Date`, `Content-Type` and `Server` headers.
7680
- maxRequestSize: Maximum request size in bytes. Request exceeding this value results in 413(REQUEST_ENTITY_TOO_LARGE) response. Default is `10mb`.
81+
- securePort: Configure Jooby to do HTTPs. This option is fully convered in next section.
82+
- ssl: SSL options with certificate details. This option is fully convered in next section.
7783

7884
Server options are available as application configuration properties too:
7985

@@ -88,4 +94,180 @@ server.gzip = false
8894
server.singleLoop = false
8995
server.defaultHeaders = true
9096
server.maxRequestSize = 10485760
97+
server.securePort = 8443
98+
server.ssl.type = self-signed
99+
----
100+
101+
=== SSL
102+
103+
Jooby supports HTTPS out of the box. By default HTTPS is disabled and all requests are served using
104+
HTTP. To enable HTTPS support, modify your configuration.
105+
106+
.SSL Options
107+
[source,java,role="primary"]
108+
----
109+
{
110+
setServerOptions(new ServerOptions()
111+
.setSecurePort(8443) <1>
112+
);
113+
}
114+
----
115+
116+
.Kotlin
117+
[source,kotlin,role="secondary"]
118+
----
119+
{
120+
serverOptions {
121+
securePort = 8443 <1>
122+
}
123+
}
124+
----
125+
126+
<1> Set secure port and use a self-signed certificate
127+
128+
Once SSL is enabled application logs print something like:
129+
130+
----
131+
listening on:
132+
http://localhost:8080/
133+
https://localhost:8443/
134+
----
135+
136+
The `self-signed` certificate is useful for development and only works for `localhost`.
137+
138+
Jooby supports two certificate formats:
139+
140+
- PKCS12 (this is the default format)
141+
- X.509
142+
143+
The javadoc:SslOptions[] class provides options to configure SSL:
144+
145+
- cert: A PKCS12 or X.509 certificate chain file in PEM format. It can be an absolute path or a classpath resource. Required.
146+
- key: A PKCS#8 private key file in PEM format. It can be an absolute path or a classpath resource. Required when using X.509 certificates.
147+
- password: Password to use (if any). Optional. Default is: null/empty.
148+
149+
==== Using X.509
150+
151+
It is also possible to configure Jooby to use a X.509 certificate, for example one created with https://letsencrypt.org/[Let’s Encrypt]. You will need the `*.crt` and `*.key` files:
152+
153+
.X509
154+
[source,java,role="primary"]
155+
----
156+
{
157+
SslOptions ssl = SslOptions.x509("path/to/server.crt", "path/to/server.key");
158+
setServerOptions(new ServerOptions()
159+
.setSsl(ssl) <1>
160+
);
161+
}
162+
----
163+
164+
.Kotlin
165+
[source,kotlin,role="secondary"]
166+
----
167+
{
168+
serverOptions {
169+
ssl = SslOptions.x509("path/to/server.crt", "path/to/server.key") <1>
170+
}
171+
}
172+
----
173+
174+
<1> Creates a SslOptions using X509 certificates path
175+
176+
Certificate (.crt) and private key (.key) location can be file system or class path locations.
177+
178+
Optionally you can define the SSL options in your application configuration file:
179+
180+
.Ssl options:
181+
[source,json]
182+
----
183+
server {
184+
ssl {
185+
type: X509,
186+
cert: "path/to/server.crt",
187+
key: "path/to/server.key"
188+
}
189+
}
190+
----
191+
192+
.X509 from configuration
193+
[source,java,role="primary"]
194+
----
195+
{
196+
setServerOptions(new ServerOptions()
197+
.setSsl(SslOptions.from(getConfig()))
198+
);
199+
}
200+
----
201+
202+
.Kotlin
203+
[source,kotlin,role="secondary"]
204+
----
205+
{
206+
serverOptions {
207+
ssl = SslOptions.from(config)
208+
}
209+
}
210+
----
211+
212+
==== Using PKCS12
213+
214+
It is also possible to configure Jooby to use a PKCS12 certificate:
215+
216+
.PKCS12
217+
[source,java,role="primary"]
218+
----
219+
{
220+
SslOptions ssl = SslOptions.pkcs12("path/to/server.p12", "password");
221+
setServerOptions(new ServerOptions()
222+
.setSsl(ssl) <1>
223+
);
224+
}
225+
----
226+
227+
.Kotlin
228+
[source,kotlin,role="secondary"]
229+
----
230+
{
231+
serverOptions {
232+
ssl = SslOptions.x509("path/to/server.p12", "password") <1>
233+
}
234+
}
235+
----
236+
237+
<1> Creates SslOptions using PKCS12 certificates path
238+
239+
Certificate (.crt) location can be file system or class path locations.
240+
241+
Optionally you can define the SSL options in your application configuration file:
242+
243+
.Ssl options:
244+
[source,json]
245+
----
246+
server {
247+
ssl {
248+
type: PKCS12,
249+
cert: "path/to/server.p12",
250+
password: "password"
251+
}
252+
}
253+
----
254+
255+
.PKCS12 from configuration
256+
[source,java,role="primary"]
257+
----
258+
{
259+
setServerOptions(new ServerOptions()
260+
.setSsl(SslOptions.from(getConfig()))
261+
);
262+
}
263+
----
264+
265+
.Kotlin
266+
[source,kotlin,role="secondary"]
267+
----
268+
{
269+
serverOptions {
270+
ssl = SslOptions.from(config)
271+
}
272+
}
91273
----

examples/pom.xml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,6 @@
3636
<artifactId>jooby</artifactId>
3737
<version>${jooby.version}</version>
3838
</dependency>
39-
<dependency>
40-
<groupId>io.jooby</groupId>
41-
<artifactId>jooby-ssl-x509</artifactId>
42-
<version>${jooby.version}</version>
43-
</dependency>
4439
<dependency>
4540
<groupId>io.jooby</groupId>
4641
<artifactId>jooby-jackson</artifactId>
@@ -58,7 +53,7 @@
5853
</dependency>
5954
<dependency>
6055
<groupId>io.jooby</groupId>
61-
<artifactId>jooby-jetty</artifactId>
56+
<artifactId>jooby-utow</artifactId>
6257
<version>${jooby.version}</version>
6358
</dependency>
6459
<dependency>

examples/src/main/java/examples/HelloHttpsApp.java

Lines changed: 0 additions & 28 deletions
This file was deleted.
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* Jooby https://jooby.io
3+
* Apache License Version 2.0 https://jooby.io/LICENSE.txt
4+
* Copyright 2014 Edgar Espina
5+
*/
6+
package examples;
7+
8+
import io.jooby.Jooby;
9+
import io.jooby.SSLHandler;
10+
import io.jooby.ServerOptions;
11+
12+
public class HttpsApp extends Jooby {
13+
14+
{
15+
before(new SSLHandler("localhost", 8443));
16+
setServerOptions(new ServerOptions().setSecurePort(8443));
17+
18+
get("/path", ctx -> {
19+
return ctx.getScheme() + "; secure: " + ctx.isSecure();
20+
});
21+
}
22+
23+
public static void main(String[] args) {
24+
runApp(args, HttpsApp::new);
25+
}
26+
}

0 commit comments

Comments
 (0)