带有自签名证书的 ktor 客户端 https 请求
ktor client https request with self-signed certificate
我有一个 Ktor 服务器应用程序(其余 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 的请求将失败:
Error: General SSLEngine problem
我也尝试过使用 curl 进行同样的操作:
curl: (77) schannel: next InitializeSecurityContext failed: SEC_E_UNTRUSTED_ROOT (0x80090325) - The certificate chain was issued
by an authority that is not trusted.
所以我的问题是:如何在 ktor 客户端 (Apache) 中使用自签名证书?
谢谢,
J
您需要将 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 代码中使用客户端。我自己还没试过,但让我看看你怎么样。
根据 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()
}
我有一个 Ktor 服务器应用程序(其余 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 的请求将失败:
Error: General SSLEngine problem
我也尝试过使用 curl 进行同样的操作:
curl: (77) schannel: next InitializeSecurityContext failed: SEC_E_UNTRUSTED_ROOT (0x80090325) - The certificate chain was issued by an authority that is not trusted.
所以我的问题是:如何在 ktor 客户端 (Apache) 中使用自签名证书?
谢谢, J
您需要将 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 代码中使用客户端。我自己还没试过,但让我看看你怎么样。
根据 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()
}