首页 > 解决方案 > 如何使用 feign 客户端调用带有客户端证书的休息服务

问题描述

我想访问受客户端证书保护的休息服务。如果提供了正确的证书,服务器只会接受请求。我们在项目中使用 Feign 客户端,但我找不到解决此问题的示例。它是作为拦截器添加的吗?

标签: client-certificatesfeign

解决方案


这个问题可以通过创建自定义 Feign 配置来解决,如下所示:

class CustomFeignConfiguration {

    private val log = Logger.getLogger(this.javaClass.name)

    @Value("\${client_p12_base64_encoded_string}")
    private val clientP12: String = ""

    @Value("\${client_p12_password}")
    private val clientP12Pass: String = ""

    @Bean
    fun feignClient(): Client {
        val sslSocketFactory= getSSLSocketFactory()
        log.info("CUSTOM FEIGN CLIENT CALLED")
        return Client.Default(sslSocketFactory, DefaultHostnameVerifier())
    }

    private fun getSSLSocketFactory(): SSLSocketFactory {
        val decoder = java.util.Base64.getDecoder()
        val p12 = decoder.decode(clientP12)
        val p12File = File("clientCer.p12")
        p12File.writeBytes(p12)

        try {
            val sslContext = SSLContexts
                .custom()
                .loadKeyMaterial(p12File, clientP12Pass.toCharArray(), clientP12Pass.toCharArray())
                .build()
            return sslContext.socketFactory
        } catch (exception: Exception) {
            throw RuntimeException(exception)
        }

    }
}

使用配置的 FeignClient 接口必须专门加载它

@FeignClient(name = "client", configuration = [CustomFeignConfiguration::class], url = "\${url}")
interface Client {
  ....
  ....
}

SSLContexts 库只能使用 p12 证书,我们必须将 PEM 格式的证书和密钥转换为 P12 格式。

使用以下 SSL 命令从您的 PEM 证书和密钥创建 p12 证书:

openssl pkcs12 -export -inkey domain.key -in domain.crt -out domain.p12

请记录您在运行此命令后输入的密码。

使用以下命令将此 p12 证书转换为 base64 字符串

base64 domain.p12 > domain.p12.base64

使用以下命令将此多行字符串转换为单行字符串:

tr -d "\n\r" < domain.p12.base64 > domain.p12.base64.singleline

使用此命令中的单行字符串和您之前在application.properties中记录的密码。


推荐阅读