从播放应用程序访问SSL安全的网页 [英] Accessing SSL secured web page from play application

查看:93
本文介绍了从播放应用程序访问SSL安全的网页的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在从Play应用访问SSL安全页面. 如果该页面的证书不可信(因为它已过期或已自签名), 可能是其他原因)我想从我的通话中提取此信息, 相应地做一些动作. 当我在浏览器中访问此类页面时,它警告我说 证书. 当我在游戏中写这样的内容时(这里的https页面的证书不正确):

I am accessing SSL secured pages from play app. When the certificate of the page can't be trusted (because it has expired or is self signed or whatever other reason it might be) I would like to extract this information from my call and do some action accordingly. When I access such a page in the browser, it warns me that there is something wrong with the certificate. When I write something like this in play (the https page here has a bad certificate):

package controllers

import play.api.mvc.{Action, Controller}
import play.api.libs.ws.WS
import java.util.concurrent.TimeUnit

object CallHttpsController extends Controller{


  def callHttps() = Action {

    val url = "https://xceed.no-ip.org/"

    val response: play.api.libs.ws.Response = WS.url(url).get.await(3, TimeUnit.SECONDS).get

    response.status match {
      case OK => Ok("Got response: " + response.body)
      case _ => Ok("Something went wrong: "+response.status+" "+response.body)
    }
  }
}

响应状态为OK,我希望它会引发异常,表明出了点问题 带有证书.

The response status is OK, and I would expect it to throw an exception that there is something wrong with the certificate.

在无法信任证书时是否可以调用此页面并获得异常? 默认情况下是否支持游戏? 有没有人有类似的问题/需求?

Is it possible in play to call such a page and get an exception when the certificate can't be trusted? Is it supported in play be default? Does anyone had similar problem / need?

提前谢谢.

更新#1: 感谢与宁的小费. 我已经添加了对构建脚本的依赖:

UPDATE #1: Thanks to for the tip with Ning. I have added dependency to the build script:

  lazy val appDependencies = Seq(
    "com.ning" % "async-http-client" % "1.7.5"
  )

库本身确实非常有帮助.但是,要按预期使用SSL,显然需要初始化SSL上下文.我尝试了以下代码:

The library itself is very helpful indeed. However to work with SSL as expected, apparently it needs to have SSL Context initialised. I have tried the following code:

def callHttps() = Action {

    try{

      val url = "https://xceed.no-ip.org/"

      val response: play.api.libs.ws.Response = WS.url(url).get.await(3, TimeUnit.SECONDS).get // => No problem here

      Console.println(WS.client.getConfig.getSSLContext) // => null

      val sslContext = SSLContext.getDefault;
      val playConfig = play.api.Play.maybeApplication.map(_.configuration)
      val asyncHttpConfig = new AsyncHttpClientConfig.Builder()
    .setConnectionTimeoutInMs(playConfig.flatMap(_.getMilliseconds("ws.timeout")).getOrElse(120000L).toInt)
    .setRequestTimeoutInMs(playConfig.flatMap(_.getMilliseconds("ws.timeout")).getOrElse(120000L).toInt)
    .setFollowRedirects(playConfig.flatMap(_.getBoolean("ws.followRedirects")).getOrElse(true))
    .setUseProxyProperties(playConfig.flatMap(_.getBoolean("ws.useProxyProperties")).getOrElse(true))
    .setSSLContext( sslContext )

      playConfig.flatMap(_.getString("ws.useragent")).map { useragent =>
        asyncHttpConfig.setUserAgent(useragent)
      }
      val innerClient = new AsyncHttpClient(asyncHttpConfig.build())

      val resp = innerClient.prepareGet(url).execute().get() // => exception
      Console.println("All OK")

      Ok("Got response: " + resp.getResponseBody)

    }
    catch {
      case e: Exception =>
        var cause = e.getCause
        while (cause != null) {
          Console.println("Caused by: \n" + e.getLocalizedMessage + "\n" + e.getStackTraceString)
          cause = cause.getCause
        }

        Ok("Got Exception: " + e.getLocalizedMessage + "\n" + e.getStackTraceString)
    }
  }

从WS源代码中提取了一个客户端初始化,并将默认的SSL上下文传递给该客户端.然后,呼叫将按预期失败. 会尝试用游戏来筹集票... 干杯!

There is a client initialisation extracted from the WS source code, and the default SSL Context is passed to the client. The call then fails as expected. Will try to raise a ticket with play ... Cheers!

更新#2: 票务现已解决,将成为比赛2.0.4的一部分 https://play.lighthouseapp.com/projects/82401/tickets/655-ws-call-wont-fail-upon-https-call-to-a-page-with-wrong-certificate

UPDATE #2: The ticket has been now resolved and will be a part of play 2.0.4 https://play.lighthouseapp.com/projects/82401/tickets/655-ws-call-wont-fail-upon-https-call-to-a-page-with-wrong-certificate

更新#3: 现在默认设置了默认的ssl上下文.要在应用程序配置文件中将其关闭,请设置ws.acceptAnyCertificate = true

UPDATE #3: The default ssl context is now set by default. To turn that off in the application config file set ws.acceptAnyCertificate=true

有关更多信息,请参见WS.scala代码: https://github.com/playframework/Play20/blob/master/framework/src/play/src/main/scala/play/api/libs/ws/WS.scala

See the WS.scala code for more information: https://github.com/playframework/Play20/blob/master/framework/src/play/src/main/scala/play/api/libs/ws/WS.scala

推荐答案

在其play.api.libs.ws.WS类中播放!框架使用宁异步HTTP客户端库(版本1.7.0),该版本又使用 Netty网络应用程序框架(版本3.5). Netty负责SSL验证,但其结果由异步HTTP客户端库处理.

In its play.api.libs.ws.WS class the Play! framework uses the Ning Async HTTP Client Library (version 1.7.0), which in turn uses the Netty network application framework (version 3.5). Netty is responsible for SSL verification, but its result is handled by the Async HTTP Client library.

似乎SSL验证仅在最近提交的Async中得到正确修复HTTP客户端库,仅包含在1.7.5版本中.您可以尝试将较新的版本强加到您的项目中(即覆盖Play所引用的1.7.0版本!),并且可能会出现问题,以便可以在下一个Play中包含较新的库版本!释放.

It seems like SSL verification is only properly fixed in a recent commit of the Async HTTP Client library, which is only included in the 1.7.5 release. You could try forcing the newer version into your project (i.e. overriding the 1.7.0 version referenced by Play!), and maybe opening an issue so that the newer library version can be included in the next Play! release.

这篇关于从播放应用程序访问SSL安全的网页的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆