!htc #20371 allows for simple HTTPS usage from Java, fixes typo in APIs (#20373)

This commit is contained in:
Konrad Malawski 2016-04-25 12:01:03 +02:00
parent b983f19c1f
commit 0e11ec2057
28 changed files with 674 additions and 120 deletions

View file

@ -0,0 +1,27 @@
/*
* Copyright (C) 2009-2016 Lightbend Inc. <http://www.lightbend.com>
*/
package docs.http.javadsl.server;
import akka.actor.ActorSystem;
import com.typesafe.sslconfig.akka.AkkaSSLConfig;
import org.junit.Test;
import org.scalatest.junit.JUnitSuite;
/* COMPILE ONLY TEST */
public class HttpsServerExampleTest extends JUnitSuite {
@Test
public void compileOnlySpec() throws Exception {
// just making sure for it to be really compiled / run even if empty
}
void sslConfigGet() {
//#akka-ssl-config
final ActorSystem system = ActorSystem.create();
final AkkaSSLConfig sslConfig = AkkaSSLConfig.get(system);
//#
}
}

View file

@ -125,7 +125,7 @@ Disabling TLS security features, at your own risk
The following shows an example of disabling SNI for a given connection:
.. includecode:: ../../code/docs/http/scaladsl/HttpsExamplesSpec.scala
.. includecode:: ../../code/docs/http/javadsl/HttpsExamplesDocTest.java
:include: disable-sni-connection
The ``badSslConfig`` is a copy of the default ``AkkaSSLConfig`` with with the slightly changed configuration to disable SNI.

View file

@ -26,5 +26,5 @@ Akka HTTP will happily handle many thousand concurrent connections to a single o
connection-level
host-level
request-level
https-support
client-https-support
websocket-support

View file

@ -36,6 +36,7 @@ akka-http-jackson
server-side/websocket-support
routing-dsl/index
client-side/index
server-side-https-support
configuration
.. _jackson: https://github.com/FasterXML/jackson

View file

@ -0,0 +1,92 @@
.. _serverSideHTTPS-java:
Server-Side HTTPS Support
=========================
Akka HTTP supports TLS encryption on the server-side as well as on the :ref:`client-side <clientSideHTTPS>`.
The central vehicle for configuring encryption is the ``HttpsConnectionContext``, which can be created using
the static method ``ConnectionContext.https`` which is defined like this:
.. includecode:: /../../akka-http-core/src/main/scala/akka/http/javadsl/ConnectionContext.scala
:include: https-context-creation
On the server-side the ``bind``, and ``bindAndHandleXXX`` methods of the `akka.http.javadsl.Http`_ extension define an
optional ``httpsContext`` parameter, which can receive the HTTPS configuration in the form of an ``HttpsContext``
instance.
If defined encryption is enabled on all accepted connections. Otherwise it is disabled (which is the default).
For detailed documentation for client-side HTTPS support refer to :ref:`clientSideHTTPS`.
.. _akka.http.javadsl.Http: https://github.com/akka/akka/blob/master/akka-http-core/src/main/scala/akka/http/javadsl/Http.scala
SSL-Config
----------
Akka HTTP heavily relies on, and delegates most configuration of any SSL/TLS related options to
`Lightbend SSL-Config`_, which is a library specialized in providing an secure-by-default SSLContext
and related options.
Please refer to the `Lightbend SSL-Config`_ documentation for detailed documentation of all available settings.
SSL Config settings used by Akka HTTP (as well as Streaming TCP) are located under the `akka.ssl-config` namespace.
.. _Lightbend SSL-Config: http://typesafehub.github.io/ssl-config/
In order to use SSL-Config in Akka so it logs to the right ActorSystem-wise logger etc., the
``AkkaSSLConfig`` extension is provided. Obtaining it is as simple as:
.. includecode2:: ../code/docs/http/javadsl/server/HttpsServerExampleTest.java
:snippet: akka-ssl-config
While typical usage, for example for configuring http client settings would be applied globally by configuring
ssl-config in ``application.conf``, it's possible to obtain the extension and ``copy`` it while modifying any
configuration that you might need to change and then use that specific ``AkkaSSLConfig`` instance while establishing
connections be it client or server-side.
Obtaining SSL/TLS Certificates
------------------------------
In order to run an HTTPS server a certificate has to be provided, which usually is either obtained from a signing
authority or created by yourself for local or staging environment purposes.
Signing authorities often provide instructions on how to create a Java keystore (typically with reference to Tomcat
configuration). If you want to generate your own certificates, the official Oracle documentation on how to generate
keystores using the JDK keytool utility can be found `here <https://docs.oracle.com/javase/8/docs/technotes/tools/unix/keytool.html>`_.
SSL-Config provides a more targeted guide on generating certificates, so we recommend you start with the guide
titled `Generating X.509 Certificates <http://typesafehub.github.io/ssl-config/CertificateGeneration.html>`_.
Using HTTPS
-----------
Once you have obtained the server certificate, using it is as simple as preparing an ``HttpsConnectionContext``
and either setting it as the default one to be used by all servers started by the given ``Http`` extension
or passing it in explicitly when binding the server.
The below example shows how setting up HTTPS works when using the ``akka.http.javadsl.server.HttpApp`` convenience class:
.. includecode2:: ../../../../akka-http-tests/src/main/java/akka/http/javadsl/server/examples/simple/SimpleServerApp.java
:snippet: https-http-app
Further reading
---------------
The topic of properly configuring HTTPS for your web server is an always changing one,
thus we recommend staying up to date with various security breach news and of course
keep your JVM at the latest version possible, as the default settings are often updated by
Oracle in reaction to various security updates and known issues.
We also recommend having a look at the `Play documentation about securing your app`_,
as well as the techniques described in the Play documentation about setting up a `reverse proxy to terminate TLS in
front of your application`_ instead of terminating TLS inside the JVM, and therefore Akka HTTP, itself.
Other excellent articles on the subject:
- `Oracle Java SE 8: Creating a Keystore using JSSE <https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#CreateKeystore>`_
- `Java PKI Programmer's Guide <https://docs.oracle.com/javase/8/docs/technotes/guides/security/certpath/CertPathProgGuide.html>`_
- `Fixing X.509 Certificates <https://tersesystems.com/2014/03/20/fixing-x509-certificates/>`_
.. _Play documentation about securing your app: https://www.playframework.com/documentation/2.5.x/ConfiguringHttps#ssl-certificates
.. _reverse proxy to terminate TLS in front of your application: https://www.playframework.com/documentation/2.5.x/HTTPServer

View file

@ -0,0 +1,72 @@
/*
* Copyright (C) 2009-2016 Lightbend Inc. <http://www.lightbend.com>
*/
package docs.http.scaladsl.server
//#imports
import java.io.InputStream
import java.security.{ SecureRandom, KeyStore }
import javax.net.ssl.{ SSLContext, TrustManagerFactory, KeyManagerFactory }
import akka.actor.ActorSystem
import akka.http.scaladsl.server.{ RouteResult, Route, Directives }
import akka.http.scaladsl.{ ConnectionContext, HttpsConnectionContext, Http }
import akka.stream.ActorMaterializer
import com.typesafe.sslconfig.akka.AkkaSSLConfig
//#
import docs.CompileOnlySpec
import org.scalatest.{ Matchers, WordSpec }
abstract class HttpsServerExampleSpec extends WordSpec with Matchers
with Directives with CompileOnlySpec {
class HowToObtainSSLConfig {
//#akka-ssl-config
implicit val system = ActorSystem()
val sslConfig = AkkaSSLConfig()
//#
}
"low level api" in compileOnlySpec {
//#low-level-default
implicit val system = ActorSystem()
implicit val mat = ActorMaterializer()
implicit val dispatcher = system.dispatcher
// Manual HTTPS configuration
val password: Array[Char] = ??? // do not store passwords in code, read them from somewhere safe!
val ks: KeyStore = KeyStore.getInstance("PKCS12")
val keystore: InputStream = getClass.getClassLoader.getResourceAsStream("server.p12")
require(keystore != null, "Keystore required!")
ks.load(keystore, password)
val keyManagerFactory: KeyManagerFactory = KeyManagerFactory.getInstance("SunX509")
keyManagerFactory.init(ks, password)
val tmf: TrustManagerFactory = TrustManagerFactory.getInstance("SunX509")
tmf.init(ks)
val sslContext: SSLContext = SSLContext.getInstance("TLS")
sslContext.init(keyManagerFactory.getKeyManagers, tmf.getTrustManagers, SecureRandom.getInstanceStrong)
val https: HttpsConnectionContext = ConnectionContext.https(sslContext)
// sets default context to HTTPS all Http() bound servers for this ActorSystem will use HTTPS from now on
Http().setDefaultServerHttpContext(https)
//#
//#bind-low-level-context
Http().bind("127.0.0.1", connectionContext = https)
// or using the high level routing DSL:
val routes: Route = get { complete("Hello world!") }
Http().bindAndHandle(routes, "127.0.0.1", 8080, connectionContext = https)
//#
}
}

View file

@ -3,7 +3,7 @@
Client-Side HTTPS Support
=========================
Akka HTTP supports TLS encryption on the client-side as well as on the :ref:`server-side <serverSideHTTPS>`.
Akka HTTP supports TLS encryption on the client-side as well as on the :ref:`server-side <serverSideHTTPS-scala>`.
.. warning:

View file

@ -27,5 +27,5 @@ Akka HTTP will happily handle many thousand concurrent connections to a single o
connection-level
host-level
request-level
https-support
client-https-support
websocket-support

View file

@ -12,4 +12,5 @@ Akka HTTP
low-level-server-side-api
routing-dsl/index
client-side/index
server-side-https-support
migration-from-spray

View file

@ -11,7 +11,8 @@ This means that, if you have trouble achieving something using a high-level API,
it done with a low-level API, which offers more flexibility but might require you to write more application code.
Philosophy
---------------
----------
Akka HTTP has been driven with a clear focus on providing tools for building integration layers rather than application cores. As such it regards itself as a suite of libraries rather than a framework.
A framework, as wed like to think of the term, gives you a “frame”, in which you build your application. It comes with a lot of decisions already pre-made and provides a foundation including support structures that lets you get started and deliver results quickly. In a way a framework is like a skeleton onto which you put the “flesh” of your application in order to have it come alive. As such frameworks work best if you choose them before you start application development and try to stick to the frameworks “way of doing things” as you go along.

View file

@ -136,39 +136,10 @@ Connection will also be closed if request entity has been cancelled (e.g. by att
or consumed only partially (e.g. by using ``take`` combinator). In order to prevent this behaviour entity should be
explicitly drained by attaching it to ``Sink.ignore``.
Configuring Server-side HTTPS
-----------------------------
.. _serverSideHTTPS:
Server-Side HTTPS Support
-------------------------
Akka HTTP supports TLS encryption on the server-side as well as on the :ref:`client-side <clientSideHTTPS>`.
The central vehicle for configuring encryption is the ``HttpsConnectionContext``, which can be created using
the static method ``ConnectionContext.https`` which is defined like this:
.. includecode:: /../../akka-http-core/src/main/scala/akka/http/scaladsl/ConnectionContext.scala
:include: https-context-creation
On the server-side the ``bind``, and ``bindAndHandleXXX`` methods of the `akka.http.scaladsl.Http`_ extension define an
optional ``httpsContext`` parameter, which can receive the HTTPS configuration in the form of an ``HttpsContext``
instance.
If defined encryption is enabled on all accepted connections. Otherwise it is disabled (which is the default).
For detailed documentation for client-side HTTPS support refer to :ref:`clientSideHTTPS`.
SSL-Config
----------
Akka HTTP heavily relies on, and delegates most configuration of any SSL/TLS related options to
`Lightbend SSL-Config`_, which is a library specialized in providing an secure-by-default SSLContext
and related options.
Please refer to the `Lightbend SSL-Config`_ documentation for detailed documentation of all available settings.
SSL Config settings used by Akka HTTP (as well as Streaming TCP) are located under the `akka.ssl-config` namespace.
.. _Lightbend SSL-Config: http://typesafehub.github.io/ssl-config/
For detailed documentation about configuring and using HTTPS on the server-side refer to :ref:`serverSideHTTPS-scala`.
.. _http-server-layer-scala:
@ -277,3 +248,4 @@ anyway, which is a reasonable default for such problems.
In order to learn more about handling exceptions in the actual routing layer, which is where your application code
comes into the picture, refer to :ref:`exception-handling-scala` which focuses explicitly on explaining how exceptions
thrown in routes can be handled and transformed into :class:`HttpResponse` s with apropriate error codes and human-readable failure descriptions.

View file

@ -97,3 +97,7 @@ and split each line before we send it to an actor for further processing:
.. includecode2:: ../../code/docs/http/scaladsl/server/FileUploadExamplesSpec.scala
:snippet: stream-csv-upload
Configuring Server-side HTTPS
-----------------------------
For detailed documentation about configuring and using HTTPS on the server-side refer to :ref:`serverSideHTTPS-scala`.

View file

@ -0,0 +1,101 @@
.. _serverSideHTTPS-scala:
Server-Side HTTPS Support
=========================
Akka HTTP supports TLS encryption on the server-side as well as on the :ref:`client-side <clientSideHTTPS>`.
The central vehicle for configuring encryption is the ``HttpsConnectionContext``, which can be created using
the static method ``ConnectionContext.https`` which is defined like this:
.. includecode:: /../../akka-http-core/src/main/scala/akka/http/scaladsl/ConnectionContext.scala
:include: https-context-creation
On the server-side the ``bind``, and ``bindAndHandleXXX`` methods of the `akka.http.scaladsl.Http`_ extension define an
optional ``httpsContext`` parameter, which can receive the HTTPS configuration in the form of an ``HttpsContext``
instance.
If defined encryption is enabled on all accepted connections. Otherwise it is disabled (which is the default).
For detailed documentation for client-side HTTPS support refer to :ref:`clientSideHTTPS`.
.. _akka.http.scaladsl.Http: https://github.com/akka/akka/blob/master/akka-http-core/src/main/scala/akka/http/scaladsl/Http.scala
SSL-Config
----------
Akka HTTP heavily relies on, and delegates most configuration of any SSL/TLS related options to
`Lightbend SSL-Config`_, which is a library specialized in providing an secure-by-default SSLContext
and related options.
Please refer to the `Lightbend SSL-Config`_ documentation for detailed documentation of all available settings.
SSL Config settings used by Akka HTTP (as well as Streaming TCP) are located under the `akka.ssl-config` namespace.
.. _Lightbend SSL-Config: http://typesafehub.github.io/ssl-config/
In order to use SSL-Config in Akka so it logs to the right ActorSystem-wise logger etc., the
``AkkaSSLConfig`` extension is provided. Obtaining it is as simple as:
.. includecode2:: ../code/docs/http/scaladsl/server/HttpsServerExampleSpec.scala
:snippet: akka-ssl-config
While typical usage, for example for configuring http client settings would be applied globally by configuring
ssl-config in ``application.conf``, it's possible to obtain the extension and ``copy`` it while modifying any
configuration that you might need to change and then use that specific ``AkkaSSLConfig`` instance while establishing
connections be it client or server-side.
Obtaining SSL/TLS Certificates
------------------------------
In order to run an HTTPS server a certificate has to be provided, which usually is either obtained from a signing
authority or created by yourself for local or staging environment purposes.
Signing authorities often provide instructions on how to create a Java keystore (typically with reference to Tomcat
configuration). If you want to generate your own certificates, the official Oracle documentation on how to generate
keystores using the JDK keytool utility can be found `here <https://docs.oracle.com/javase/8/docs/technotes/tools/unix/keytool.html>`_.
SSL-Config provides a more targeted guide on generating certificates, so we recommend you start with the guide
titled `Generating X.509 Certificates <http://typesafehub.github.io/ssl-config/CertificateGeneration.html>`_.
Using HTTPS
-----------
Once you have obtained the server certificate, using it is as simple as preparing an ``HttpsConnectionContext``
and either setting it as the default one to be used by all servers started by the given ``Http`` extension
or passing it in explicitly when binding the server:
.. includecode2:: ../code/docs/http/scaladsl/server/HttpsServerExampleSpec.scala
:snippet: imports
.. includecode2:: ../code/docs/http/scaladsl/server/HttpsServerExampleSpec.scala
:snippet: low-level-default
It is also possible to pass in the context to specific ``bind...`` (or client) calls, like displayed below:
.. includecode2:: ../code/docs/http/scaladsl/server/HttpsServerExampleSpec.scala
:snippet: bind-low-level-context
Further reading
---------------
The topic of properly configuring HTTPS for your web server is an always changing one,
thus we recommend staying up to date with various security breach news and of course
keep your JVM at the latest version possible, as the default settings are often updated by
Oracle in reaction to various security updates and known issues.
We also recommend having a look at the `Play documentation about securing your app`_,
as well as the techniques described in the Play documentation about setting up a `reverse proxy to terminate TLS in
front of your application`_ instead of terminating TLS inside the JVM, and therefore Akka HTTP, itself.
Other excellent articles on the subject:
- `Oracle Java SE 8: Creating a Keystore using JSSE <https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#CreateKeystore>`_
- `Java PKI Programmer's Guide <https://docs.oracle.com/javase/8/docs/technotes/guides/security/certpath/CertPathProgGuide.html>`_
- `Fixing X.509 Certificates <https://tersesystems.com/2014/03/20/fixing-x509-certificates/>`_
.. _Play documentation about securing your app: https://www.playframework.com/documentation/2.5.x/ConfiguringHttps#ssl-certificates
.. _reverse proxy to terminate TLS in front of your application: https://www.playframework.com/documentation/2.5.x/HTTPServer