首页 > 解决方案 > 带有自签名证书的 ktor 客户端 https 请求

问题描述

我有一个使用自签名证书运行的 Ktor 服务器应用程序(rest api)。

它可以从浏览器正常工作(在警告和确认之后)端口 80 被重定向到 8443。

但是,如果我从 Ktor Apache 客户端尝试此操作:

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()
}

我对https://10.0.0.11:8443/get-my-services的请求将失败:

错误:一般 SSLEngine 问题

我也使用 curl 进行了同样的尝试:

curl: (77) schannel: next InitializeSecurityContext failed: SEC_E_UNTRUSTED_ROOT (0x80090325) - 证书链是由不受信任的权威机构颁发的。

所以我的问题是:如何将自签名证书与 ktor 客户端(Apache)一起使用?

谢谢,J

标签: kotlinktor

解决方案


根据 Erik 的回答,这就是我让 Ktor Apache Client 接受自签名证书的方式:

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()
}

推荐阅读