我有一个运行有自签名证书的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尝试过相同的操作
卷曲:(77)schannel:下一个InitializeSecurityContext失败:SEC_E_UNTRUSTED_ROOT(0x80090325)-颁发了证书链 由不受信任的权威机构。
所以我的问题是:如何在ktor客户端(Apache)中使用自签名证书?
谢谢, J
答案 0 :(得分: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代码中使用客户端。我还没有尝试过,但是让我知道你的情况。
答案 1 :(得分:2)
基于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()
}