我在配置Akka HTTP时遇到了一些麻烦,希望能够使用特定的SSL证书从Scala发出HTTP请求。我可以轻松地进行非SSL基础请求,但似乎找不到正确的配置Akka以使用一组证书的示例。
不幸的是,Akka HTTP网站上的文档提供了有关服务器端SSL配置的详细信息,但没有给出有关客户端配置的具体示例。
如果有这样使用的任何示例,将不胜感激。
我在配置Akka HTTP时遇到了一些麻烦,希望能够使用特定的SSL证书从Scala发出HTTP请求。我可以轻松地进行非SSL基础请求,但似乎找不到正确的配置Akka以使用一组证书的示例。
不幸的是,Akka HTTP网站上的文档提供了有关服务器端SSL配置的详细信息,但没有给出有关客户端配置的具体示例。
如果有这样使用的任何示例,将不胜感激。
我在我的小项目中做过这个,我认为即使问题已经老旧,它对于某些人可能仍然有用。您将需要创建您的keystore.pkcs12
文件。我使用的build.sbt
是:
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
HttpsServerContext
的对象,我可以在我的项目中的任何Akka-http api中使用它。我通过调用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)
}
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)