【问题标题】:Spring Cloud Vault mutual TLS authentication issueSpring Cloud Vault 双向 TLS 身份验证问题
【发布时间】:2020-09-09 19:02:51
【问题描述】:

我正在尝试设置一个 Spring Boot 应用程序以通过 TLS 与我的 Vault 服务器通信。我想使用相互证书身份验证。我可以使用 TLS 设置 Vault 服务器,并且可以使用 CLI 使用客户端证书登录它。但是,spring boot 应用程序无法将其客户端证书提供给 Vault 服务器 - 每次我运行我的应用程序时,Vault 服务器都会打印:

http: TLS handshake error from 127.0.0.1:33288: tls: client didn't provide a certificate

客户端(我的 spring boot 应用)打印:

org.springframework.vault.authentication.VaultLoginException:
Cannot login using org.springframework.web.client.ResourceAccessException:
I/O error on POST request for "https://localhost:8200/v1/auth/cert/login": 
Received fatal alert: bad_certificate;
nested exception is javax.net.ssl.SSLHandshakeException:
Received fatal alert: bad_certificate
... (a stack trace for VaultLoginException)

这是我的bootstrap.yml

spring:
    application.name: vault-demo

    cloud.vault:
        host: localhost
        port: 8200
        scheme: https
        uri: https://localhost:8200
        connection-timeout: 5000
        read-timeout: 15000
        config.order: -10

        authentication: CERT        

        ssl:
            trust-store: classpath:keystore.jks
            trust-store-password: changeit

            key-store: classpath:client-cert.jks
            key-store-password: changeit
            cert-auth-path: cert

我找不到任何关于需要在spring.cloud.vault.* 下配置的各种属性的文档。

我的client-cert.jks 商店有客户端证书和密钥。启用 SSL 详细日志,我可以看到:

*** ServerHelloDone
Warning: no suitable certificate found - continuing without client authentication
*** Certificate chain

这表明客户端在其信任库中找到了服务器的证书,但它没有将客户端的证书发送到服务器。

另外,如果我使用curl发送登录请求,则成功:

curl -k --request POST \
--cert work/ca/certs/client.cert.pem \
--key work/ca/private/client.decrypted.key.pem \
--data @payload.json \
https://localhost:8200/v1/auth/cert/login

# gives me back a JSON with newly issued token.

我也尝试使用配置类并将javax.net.ssl.keyStore 和相关属性作为JAVA_OPTS 传递,但绝对没有区别 - 保险库一直说客户端没有发送证书:

@Configuration
public class AppConfig extends AbstractVaultConfiguration {

    @Value("${vault.uri}")
    URI vaultUri;

    @Override
    public VaultEndpoint vaultEndpoint() {
        return VaultEndpoint.from(vaultUri);
    }

    @Override
    public ClientAuthentication clientAuthentication() {
        try {
            RestTemplate restTemplate = new RestTemplate();
            HttpClientBuilder httpClientBuilder = HttpClients.custom()
                    .setSSLContext(SSLContext.getDefault())
                        .useSystemProperties();

            restTemplate.setRequestFactory(
                    new HttpComponentsClientHttpRequestFactory(
                            httpClientBuilder.build()));

            return new ClientCertificateAuthentication(restTemplate);

        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }
}

谁能指出我遗漏了什么/做错了什么?

【问题讨论】:

  • 快速谷歌搜索显示:cloud.spring.io/spring-cloud-static/spring-cloud-vault/…。正确的值为cert,需要将客户端证书和密钥加载到java keystore中。
  • 谢谢@Marc,是的,我应该使用cert - 现在想通了。该值基本上来自vault auth list 命令的输出。但即使在那之后,结果也是一样的。客户端未发送其证书。为了更清楚,我更新了问题。

标签: spring-boot ssl spring-cloud hashicorp-vault spring-cloud-vault-config


【解决方案1】:

问题是我的 Vault 配置未正确指定 tls_client_ca_file 属性。将其设置为根 CA 证书,一切正常。也不需要添加AppConfig 类。

【讨论】:

    猜你喜欢
    • 2020-04-07
    • 2018-11-12
    • 1970-01-01
    • 2018-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-13
    • 2019-04-08
    相关资源
    最近更新 更多