我只想跳过cert验证(基本上与curl相同--不安全)。
脚本语言2.12,akka-http 10.2.4
我试过这些方法,但都不起作用:
- https://gist.github.com/iRevive/4a3c7cb96374da5da80d4538f3da17cb
- https://doc.akka.io/docs/akka-http/current/client-side/client-https-support.html#disabling-hostname-verification
自定义SSL上下文
implicit val system: ActorSystem[Nothing] = ActorSystem(Behaviors.empty, "SingleRequest")
implicit val executionContext: ExecutionContextExecutor = system.executionContext
val noCertificateCheckContext = ConnectionContext.https(trustfulSslContext)
private val trustfulSslContext: SSLContext = {
object NoCheckX509TrustManager extends X509TrustManager {
override def checkClientTrusted(chain: Array[X509Certificate], authType: String) = ()
override def checkServerTrusted(chain: Array[X509Certificate], authType: String) = ()
override def getAcceptedIssuers = Array[X509Certificate]()
}
val context = SSLContext.getInstance("TLS")
context.init(Array[KeyManager](), Array(NoCheckX509TrustManager), null)
context
}
val res = Await.result(Http().singleRequest(Get(url), noCertificateCheckContext), 60 seconds)
Result:
个
java.util.concurrent.TimeoutException:[60秒]后期货超时
遵循官方文件:
implicit val system: ActorSystem[Nothing] = ActorSystem(Behaviors.empty,"SingleRequest")
implicit val executionContext: ExecutionContextExecutor = system.executionContext
val noCertificateCheckContext = ConnectionContext.httpsClient(getConnection _)
def getConnection(host: String, port: Int): SSLEngine = {
val engine = SSLContext.getDefault.createSSLEngine(host,port)
engine.setUseClientMode(true)
engine
}
val res = Http().outgoingConnectionHttps("localhost",4443, connectionContext = noCertificateCheckContext)
val response = Await.result(Source.single(Get(url)).via(res).runWith(Sink.head), 60 seconds)
val responseString =Await.result(Unmarshal(response).to[String], 60 seconds)
println(responseString)
结果:
原因:sun.安全性.验证器.验证器异常:PKIX路径构建失败:安全性提供者证书路径生成器异常:找不到所请求目标的有效证书路径
1条答案
按热度按时间5vf7fwbs1#
I tried your "Custom SSLContext" reproducer,除了超时外,日志中还产生了如下栈道:
也许你的类路径上没有slf 4j记录器?在这种情况下,它应该显示一个警告。不管怎么说,看了代码之后,这里的
sslContext
就是null
。事实确实如此:在ConnectionContext.https
被初始化之前,你已经将它传递给trustfulSslContext
了。当initializing the trustfulSslContext earlier时,它对我有效。至于你的第二种方法:禁用主机名验证并不会禁用“其余部分”的证书验证。JVM仍会验证证书是否有效--只是不再验证证书是否属于您正在连接的主机名。要接受无效证书,您必须使用自定义的
SSLContext
。您的示例可以是adapted to do that as well,但在其他条件相同的情况下,第一种方法更简单,第二种方法中不需要额外的间接。