【问题标题】:ktor client https request with self-signed certificate带有自签名证书的 ktor 客户端 https 请求
【发布时间】:2019-05-13 08:02:37
【问题描述】:

我有一个使用自签名证书运行的 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()
}

我对@9​​87654321@ 的请求将失败:

错误:一般 SSLEngine 问题

我也尝试过使用 curl:

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

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

谢谢, J

【问题讨论】:

    标签: kotlin ktor


    【解决方案1】:

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

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

    【讨论】:

    • 感谢分享这个解决方案,我相信它将来会派上用场!
    【解决方案2】:

    您需要将 Apache HttpClient 配置为忽略自签名证书,并将其传递给 KTor。根据here的信息,可以忽略自签名证书验证,代码如下:

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

    您要做的最后一件事是在您的 KTor 代码中使用客户端。我自己还没有尝试过,但让我看看你是怎么做的。

    【讨论】:

    • 埃里克,你的解决方案有效!!!我对其进行了修改以与 ktor 一起使用。我将在几分钟内添加更新的代码。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2020-05-17
    • 2012-07-19
    • 1970-01-01
    • 1970-01-01
    • 2022-01-07
    • 2017-04-01
    • 1970-01-01
    • 2017-01-24
    相关资源
    最近更新 更多