【问题标题】:How to send HTTP request using Akka with SSL certificates如何使用带有 SSL 证书的 Akka 发送 HTTP 请求
【发布时间】:2018-05-14 00:26:22
【问题描述】:

在从 Scala 发出 HTTP 请求时,我在配置 Akka HTTP 以使用特定 SSL 证书时遇到了一些问题。我可以毫无问题地发出基于非 SSL 的请求,但似乎找不到关于如何配置 Akka 以与一组证书一起使用的适当示例。

遗憾的是,Akka HTTP 网站上的文档提供了有关服务器端 SSL 配置的详细信息,但没有给出客户端配置的具体示例。

任何此类用法的示例将不胜感激。

【问题讨论】:

标签: scala ssl configuration akka akka-http


【解决方案1】:

我已经在我的一个小项目中做到了这一点,我认为即使这个问题很老,我也认为它可能对某些人有用。您必须创建您的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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-12
    • 2012-07-25
    • 1970-01-01
    • 1970-01-01
    • 2017-03-21
    • 1970-01-01
    • 2014-10-12
    相关资源
    最近更新 更多