Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Web services 如何让Play Framework WS使用我的SSLContext_Web Services_Ssl - Fatal编程技术网

Web services 如何让Play Framework WS使用我的SSLContext

Web services 如何让Play Framework WS使用我的SSLContext,web-services,ssl,Web Services,Ssl,我将Play2.3.7与Scala2.11.4、Java7一起使用。我想使用Play WS连接到HTTPS端点,该端点要求客户端提供其证书。为此,我创建了自己的SSLContext: val sslContext = { val keyStore = KeyStore.getInstance("pkcs12") keyStore.load(new FileInputStream(clientKey), clientKeyPass.to[Array]) val kmf

我将Play2.3.7与Scala2.11.4、Java7一起使用。我想使用Play WS连接到HTTPS端点,该端点要求客户端提供其证书。为此,我创建了自己的SSLContext:

  val sslContext = {
    val keyStore = KeyStore.getInstance("pkcs12")
    keyStore.load(new FileInputStream(clientKey), clientKeyPass.to[Array])
    val kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm)
    kmf.init(keyStore, clientKeyPass.to[Array])

    val trustStore = KeyStore.getInstance("jks")
    trustStore.load(new FileInputStream(trustStoreFile), trustStorePass.to[Array])
    val tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm)
    tmf.init(trustStore)

    val ctx = SSLContext.getInstance("TLSv1.2")
    ctx.init(kmf.getKeyManagers, tmf.getTrustManagers, new SecureRandom())
    ctx
  }
我知道SSLContext是有效的,因为我可以将它成功地用于URLConnection:

  def urlConnection = Action {
    val conn = new URL(url).openConnection()
    conn.asInstanceOf[HttpsURLConnection].setSSLSocketFactory(sslContext.getSocketFactory)
    conn.connect()
    Ok(scala.io.Source.fromInputStream(conn.getInputStream).getLines().mkString("\n"))
  }
但当我尝试下面两种方法中的一种时,我得到了java.nio.channels.ClosedChannelException

  def ning = Action.async {
    val builder = new AsyncHttpClientConfig.Builder()
    builder.setSSLContext(sslContext)
    val client = new NingWSClient(builder.build())
    client.url(url).get() map { _ => Ok("ok") }
  }

  def asyncHttpClient = Action {
    val builder = new AsyncHttpClientConfig.Builder()
    builder.setSSLContext(sslContext)
    val httpClient = new AsyncHttpClient(builder.build())
    httpClient.prepareGet(url).execute().get(10, TimeUnit.SECONDS)
    Ok("ok")
  }
当我按照Will Sargent的建议使用NingAsyncHttpClientConfigBuilder和解析的配置注释时,我也会遇到同样的异常,即配置引用的值与手工编制的sslContext完全相同

  def ningFromConfig = Action.async {
    val config = play.api.Configuration(ConfigFactory.parseString(
      s"""
          |ws.ssl {
          |  keyManager = {
          |    stores = [
          |      { type: "PKCS12", path: "$clientKey", password: "$clientKeyPass" }
          |    ]
          |  }
          |  trustManager = {
          |    stores = [
          |      { type: "JKS", path: "$trustStoreFile", password: "$trustStorePass" },
          |    ]
          |  }
          |}
          |# Without this one I get InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
          |ws.ssl.disabledKeyAlgorithms="RSA keySize < 1024"
       """.stripMargin))
    val parser = new DefaultWSConfigParser(config, play.api.Play.application.classloader)
    val builder = new NingAsyncHttpClientConfigBuilder(parser.parse())
    val client = new NingWSClient(builder.build())
    client.url(url).get() map { _ => Ok("ok") }
  }

如何使其与Play WS一起工作?

您应该使用和中定义的application.conf中的客户端证书-如果需要使用自定义配置,您应该直接使用解析器:

要创建一个配置,请使用Ning生成器:


这将为您提供可以传入的AHCConfig对象。在。

的“使用WSClient”一节中有一些示例,我遵循了您的建议,但不幸的是,它不起作用-请查看更新的问题,您需要打开ws.ssl.debug并查看连接终止的原因。我看到的一个区别是,在成功案例中,SSL hello中存在服务器名称扩展。你能强迫Play WS将其放在那里吗?你需要首先确定连接失败的原因。你建议从哪里开始诊断?我刚刚打开了调试跟踪,比较了正负两种情况下的输出。在否定的情况下,我注意到服务器名称扩展名的缺失。我接受了威尔的答案,因为这可能是对原始问题最好的答案。在我的情况下,它不起作用是另一回事,但它需要关于这个特殊SSL设置的一些模糊细节,现在不可能复制。当时我使用Spray HTTP客户端Akka HTTP now解决了这个问题。