With such code:
val html = Source.fromURL("https://scans.io/json")
Getting exception:
Exception in thread "main" javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1886)
...
I can find how to fix in Java but have no idea - how to fix it in Scala?
This issue can happen because the JDK does not use the operating systems's truststore, into which your IT would have added the self-signed certificate. The solution would be to import the proxy's self-signed certificate into your JDK's truststore (i.e. the cacerts file).
The SSLHandshakeException is thrown when an error occurs while a client and server connection fails to agree on their desired security level. This exception is one of a handful of classes that inherits from the parent SSLException class.
An SSL certificate is a bit of code on your web server that provides security for online communications. When a web browser contacts your secured website, the SSL certificate enables an encrypted connection. It's kind of like sealing a letter in an envelope before sending it through the mail.
You can achieve this by configuring a SSLContext
.
Here is a working code
import javax.net.ssl._
import java.security.cert.X509Certificate
import scala.io.Source
// Bypasses both client and server validation.
object TrustAll extends X509TrustManager {
val getAcceptedIssuers = null
override def checkClientTrusted(x509Certificates: Array[X509Certificate], s: String) = {}
override def checkServerTrusted(x509Certificates: Array[X509Certificate], s: String) = {}
}
// Verifies all host names by simply returning true.
object VerifiesAllHostNames extends HostnameVerifier {
def verify(s: String, sslSession: SSLSession) = true
}
// Main class
object Test extends App {
// SSL Context initialization and configuration
val sslContext = SSLContext.getInstance("SSL")
sslContext.init(null, Array(TrustAll), new java.security.SecureRandom())
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory)
HttpsURLConnection.setDefaultHostnameVerifier(VerifiesAllHostNames)
// Actual call
val html = Source.fromURL("https://scans.io/json")
println(html.mkString)
}
Source.fromURL
uses java.net.HttpURLConnection
behind the scene. So this code simply works because TrustAll
bypasses checkClientTrusted
and checkServerTrusted
methods.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With