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

Kotlin 具有自签名证书的ktor客户端https请求,kotlin,ktor,Kotlin,Ktor,我有一个Ktor服务器应用程序(restapi),它使用自签名证书运行 通过浏览器(在发出警告和确认后)将端口80重定向到8443,它可以正常工作 但如果我从Ktor Apache客户端尝试此操作: fun main(args: Array<String>) = runBlocking { val client = HttpClient(Apache) { install(JsonFeature) { serializer = Gso

我有一个Ktor服务器应用程序(restapi),它使用自签名证书运行

通过浏览器(在发出警告和确认后)将端口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()
}
fun main(args:Array)=运行阻塞{
val client=HttpClient(Apache){
安装(JsonFeature){
serializer=GsonSerializer()
}
}
val作业=GlobalScope.launch{
试一试{
//自签名证书
val resultWillFail=client.get(“https://10.0.0.11:8443/get-我的服务)
println(${resultWillFail})
val resultOk=client.get(“https://en.wikipedia.org/wiki/Main_Page好的
println(“${resultOk}”)
}捕获(e:例外){
println(“错误:${e.message}”)
}
}
job.join()
}
我的请求将失败:

错误:一般SSLEngine问题

我还使用curl尝试了同样的方法:

curl:(77)schannel:next InitializeSecurityContext失败:SEC_E_UNTRUSTED_ROOT(0x80090325)-已颁发证书链 由不受信任的机构颁发。

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

谢谢,
J

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

// 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代码中使用客户机。我自己还没有试过,但让我看看你是怎么做的。

基于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()
}
fun main(args:Array)=运行阻塞{
val client=HttpClient(Apache){
安装(JsonFeature){
serializer=GsonSerializer()
}
引擎{
定制客户端{
设置上下文(
SSLContextBuilder
.create()
.loadTrustMaterial(TrustSelfSignedStrategy())
.build()
)
setSSLHostnameVerifier(NoopHostnameVerifier())
}
}
}
val作业=GlobalScope.launch{
试一试{
val sslGetResult=client.get(“https://10.0.0.11:8443/get-我的服务)
println(${sslGetResult})
}捕获(e:例外){
println(“错误:${e.message}”)
}
}
job.join()
}

Erik,你的解决方案有效!!!我将其修改为与ktor一起使用。我将在几分钟内添加更新的代码。非常感谢。感谢您分享此解决方案,我相信它将在未来派上用场!