I have done this in a small project of mine and I think could be useful to somenie even the question is old. You will have to create your keystore.pkcs12
file. My build.sbt
I am using:
val akkaVersion = "2.6.10"
val akkaHttpVersion = "10.2.2"
"com.typesafe.akka" %% "akka-actor" % akkaVersion,
"com.typesafe.akka" %% "akka-http" % akkaHttpVersion,
"com.typesafe.akka" %% "akka-http-spray-json" % akkaHttpVersion,
"com.typesafe.akka" %% "akka-http-testkit" % akkaHttpVersion,
"com.typesafe.akka" %% "akka-http2-support" % akkaHttpVersion
I have the HttpsServerContext
object that I can use in any Akka-http api in my project. I use by calling enableHttps(HttpsServerContext.httpsConnectionContext)
.
object HttpsServerContext {
// Step 1 - key store
val ks: KeyStore = KeyStore.getInstance("PKCS12")
val keystoreFile: InputStream = getClass.getClassLoader.getResourceAsStream("certs/keystore.pkcs12")
// alternative: new FileInputStream(new File("src/main/resources/certs/keystore.pkcs12"))
val password = "akka-https".toCharArray // TODO: fetch the password from a secure place
ks.load(keystoreFile, password)
// Step 2 - initialize a key manager
val keyManagerFactory = KeyManagerFactory.getInstance("SunX509") // PKI public key infrastructure
keyManagerFactory.init(ks, password)
// Step 3 - initialize a trust manager
val trustmanagerFactory = TrustManagerFactory.getInstance("SunX509")
trustmanagerFactory.init(ks)
// Step 4 - initialize a SSL context
val sslContext: SSLContext = SSLContext.getInstance("TLS")
sslContext.init(keyManagerFactory.getKeyManagers, trustmanagerFactory.getTrustManagers, new SecureRandom())
// Step 5 - return the HTTPS connection context
val httpsConnectionContext: HttpsConnectionContext = ConnectionContext.httpsServer(sslContext)
}
Then I have an async request handler
implicit val system = ActorSystem("HttpsRestApi")
import system.dispatcher
val asyncRequestHandler: HttpRequest => Future[HttpResponse] = {
case HttpRequest(HttpMethods.GET, Uri.Path("/home"), headers, entity, protocol) =>
Future(HttpResponse(
StatusCodes.OK, // HTTP 200
entity = HttpEntity(
ContentTypes.`text/html(UTF-8)`,
"""
|<html>
| <body>
| Async Hello Akka HTTPS
| </body>
|</html>
|""".stripMargin)
))
case HttpRequest(HttpMethods.GET, Uri.Path("/redirect"), headers, entity, protocol) =>
Future(HttpResponse(
StatusCodes.Found,
headers = List(Location("http://www.google.com"))
))
case request: HttpRequest =>
request.discardEntityBytes()
Future(HttpResponse(
StatusCodes.NotFound, // HTTP 404
entity = HttpEntity(
ContentTypes.`text/html(UTF-8)`,
"""
|<html>
| <body>
| OOPS! async page not found =(<br>try https://localhost:8553/home
| </body>
|</html>
|""".stripMargin)
))
}
val httpsBindingAsync = Http()
.newServerAt("localhost", 8443)
.enableHttps(HttpsServerContext.httpsConnectionContext)
.bind(asyncRequestHandler)