I have a Ktor server application (rest api) running with a self signed certificate.
It works fine from a browser (after a warning and a confirmation) port 80 is redirected to 8443.
But if I try this from a Ktor Apache Client:
fun main(args: Array<String>) = runBlocking {
val client = HttpClient(Apache) {
install(JsonFeature) {
serializer = GsonSerializer()
}
}
val job = GlobalScope.launch {
try {
//self-signed certificate
val resultWillFail = client.get<String>("https://10.0.0.11:8443/get-my-services")
println("${resultWillFail}")
val resultOk = client.get<String>("https://en.wikipedia.org/wiki/Main_Page") //ok
println("${resultOk}")
} catch (e: Exception) {
println("Error: ${e.message}")
}
}
job.join()
}
My request to https://10.0.0.11:8443/get-my-services will fail:
Error: General SSLEngine problem
I also tried the same using curl:
curl: (77) schannel: next InitializeSecurityContext failed: SEC_E_UNTRUSTED_ROOT (0x80090325) - The certificate chain was issued by an authority that is not trusted.
So my question would be: How to use a self signed certificate with ktor client (Apache) ?
Thanks, J
Based on Erik answer this is how I made Ktor Apache Client to accept a self-signed certificate:
fun main(args: Array<String>) = runBlocking {
val client = HttpClient(Apache) {
install(JsonFeature) {
serializer = GsonSerializer()
}
engine {
customizeClient {
setSSLContext(
SSLContextBuilder
.create()
.loadTrustMaterial(TrustSelfSignedStrategy())
.build()
)
setSSLHostnameVerifier(NoopHostnameVerifier())
}
}
}
val job = GlobalScope.launch {
try {
val sslGetResult = client.get<String>("https://10.0.0.11:8443/get-my-services")
println("${sslGetResult}")
} catch (e: Exception) {
println("Error: ${e.message}")
}
}
job.join()
}
You need to configure Apache HttpClient to ignore self signed certificates, and pass that to KTor. Based on the information here, you can ignore self signed certificate validation with the following code:
// use the TrustSelfSignedStrategy to allow Self Signed Certificates
val sslContext = SSLContextBuilder
.create()
.loadTrustMaterial(TrustSelfSignedStrategy())
.build()
val allowAllHosts = NoopHostnameVerifier()
val connectionFactory = SSLConnectionSocketFactory(sslContext, allowAllHosts)
val client = HttpClients
.custom()
.setSSLSocketFactory(connectionFactory)
.build()
The last thing you have to do is to use the client in your KTor code. I haven't tried that myself yet, but let me see know how you go.
User contributions licensed under CC BY-SA 3.0