带有自签名证书的 ktor 客户端 https 请求

Posted

技术标签:

【中文标题】带有自签名证书的 ktor 客户端 https 请求【英文标题】:ktor client https request with self-signed certificate 【发布时间】: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

【问题讨论】:

【参考方案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 一起使用。我将在几分钟内添加更新的代码。谢谢!

以上是关于带有自签名证书的 ktor 客户端 https 请求的主要内容,如果未能解决你的问题,请参考以下文章

在 ktor httpClient(js) JS 引擎中忽略自签名证书的配置

Apollo 客户端自签名证书

https本地自签名证书添加到信任证书访问

信任来自 IIS 的自签名证书

Intranet 中的自签名 TLS 证书

AWS ELB -> 带有自签名证书的 HTTPS 后端服务器