我正在使用Play 2.3.7和Scala 2.11.4,Java 7.我想使用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?
答案 0 :(得分:0)
您应该使用https://www.playframework.com/documentation/2.3.x/KeyStores和https://www.playframework.com/documentation/2.3.x/ExampleSSLConfig中定义的application.conf中的客户端证书 - 如果您需要使用自定义配置,则应直接使用解析器:
创建配置,然后是Ning构建器:
将为您提供可以传入的AHCConfig对象。&#34;使用WSClient&#34; https://www.playframework.com/documentation/2.3.x/ScalaWS的一部分。