当前位置: 首页 > 知识库问答 >
问题:

使用spring Data Cassandra配置SSL时出错

淳于飞鸾
2023-03-14

我使用的是spring数据Cassandra项目V1.3.0无法为我的Cassandra集群(V2.0.17)配置SSL。Sprint Data Cassandra文档表示,它支持使用DataStax Java驱动程序(2.0.x)的Cassandra 2.x,因此应该不会有问题。下面是初始化cassandra集群bean的Java cassandra配置:

@Autowired
private Environment env;

@Bean
public CassandraClusterFactoryBean cluster() {
    SSLContext context = null;

    try {
        context = getSSLContext(
                env.getProperty("cassandra.connection.ssl.trustStorePath"),
                env.getProperty("cassandra.connection.ssl.trustStorePassword"),
                env.getProperty("cassandra.connection.ssl.keyStorePath"),
                env.getProperty("cassandra.connection.ssl.keyStorePassword"));
    } catch (Exception ex) {
        log.warn("Error setting SSL context for Cassandra.");
    }

    // Default cipher suites supported by C*
    String[] cipherSuites = { "TLS_RSA_WITH_AES_128_CBC_SHA",
            "TLS_RSA_WITH_AES_256_CBC_SHA" };

    CassandraClusterFactoryBean cluster = new CassandraClusterFactoryBean();
    cluster.setContactPoints(env.getProperty("cassandra.contactpoints"));
    cluster.setPort(Integer.parseInt(env.getProperty("cassandra.port")));
    cluster.setSslOptions(new SSLOptions(context, cipherSuites));
    cluster.setSslEnabled(true);
    return cluster;
}

@Bean
public CassandraMappingContext mappingContext() {
    return new BasicCassandraMappingContext();
}

@Bean
public CassandraConverter converter() {
    return new MappingCassandraConverter(mappingContext());
}

@Bean
public CassandraSessionFactoryBean session() throws Exception {

    CassandraSessionFactoryBean session = new CassandraSessionFactoryBean();
    session.setCluster(cluster().getObject());
    session.setKeyspaceName(env.getProperty("cassandra.keyspace"));
    session.setConverter(converter());
    session.setSchemaAction(SchemaAction.NONE);

    return session;
}

@Bean
public CassandraOperations cassandraTemplate() throws Exception {
    return new CassandraTemplate(session().getObject());
}

private static SSLContext getSSLContext(String truststorePath,
        String truststorePassword, String keystorePath,
        String keystorePassword) throws Exception {
    FileInputStream tsf = new FileInputStream(truststorePath);
    FileInputStream ksf = new FileInputStream(keystorePath);
    SSLContext ctx = SSLContext.getInstance("SSL");

    KeyStore ts = KeyStore.getInstance("JKS");
    ts.load(tsf, truststorePassword.toCharArray());
    TrustManagerFactory tmf = TrustManagerFactory
            .getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmf.init(ts);

    KeyStore ks = KeyStore.getInstance("JKS");
    ks.load(ksf, keystorePassword.toCharArray());
    KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory
            .getDefaultAlgorithm());
    kmf.init(ks, keystorePassword.toCharArray());

    ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(),
            new SecureRandom());
    return ctx;
}

我已经验证了用于设置SSL上下文的环境属性是否已正确填充,并且与cassandra配置文件中使用的密钥存储库和信任存储库相同。下面是关于启用客户端到节点加密的cassandra配置:

server_encryption_options:
    internode_encryption: all
    keystore: /usr/share/ssl/cassandra_client.jks
    keystore_password: cassandra
    truststore: /usr/share/ssl/cassandra_client_trust.jks
    truststore_password: cassandra
    # More advanced defaults below:
    # protocol: TLS
    # algorithm: SunX509
    store_type: JKS
    cipher_suites: [TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA] #,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA]
    # require_client_auth: true

# enable or disable client/server encryption.
client_encryption_options:
    enabled: true
    keystore: /usr/share/ssl/cassandra_client.jks
    keystore_password: cassandra
    require_client_auth: true
    # Set trustore and truststore_password if require_client_auth is true
    truststore: /usr/share/ssl/cassandra_client_trust.jks
    truststore_password: cassandra
    # More advanced defaults below:
    # protocol: TLS
    # algorithm: SunX509
    store_type: JKS
    cipher_suites: [TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA] #,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA]

启动客户端应用程序时,在初始化cassandra集群时,我会出现以下错误:

17:02:39,330 WARN  [org.springframework.web.context.support.XmlWebApplicationContext] (ServerService Thread Pool -- 58) Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cassandraServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.data.cassandra.core.CassandraOperations com.cloudistics.cldtx.mwc.service.CassandraServiceImpl.cassandraOperations; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cassandraTemplate' defined in com.cloudistics.cldtx.mwc.conn.CassandraConfig: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.cassandra.core.CassandraOperations]: Factory method 'cassandraTemplate' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'session' defined in com.cloudistics.cldtx.mwc.conn.CassandraConfig: Invocation of init method failed; nested exception is com.datastax.driver.core.exceptions.NoHostAvailableException: All host(s) tried for query failed (tried: /127.0.0.1:9042 (com.datastax.driver.core.ConnectionException: [/127.0.0.1:9042] Unexpected error during transport initialization (com.datastax.driver.core.OperationTimedOutException: [/127.0.0.1:9042] Operation timed out)))17:02:39,330 WARN  [org.springframework.web.context.support.XmlWebApplicationContext] (ServerService Thread Pool -- 58) Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cassandraServiceImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.data.cassandra.core.CassandraOperations com.cloudistics.cldtx.mwc.service.CassandraServiceImpl.cassandraOperations; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cassandraTemplate' defined in com.cloudistics.cldtx.mwc.conn.CassandraConfig: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.data.cassandra.core.CassandraOperations]: Factory method 'cassandraTemplate' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'session' defined in com.cloudistics.cldtx.mwc.conn.CassandraConfig: Invocation of init method failed; nested exception is com.datastax.driver.core.exceptions.NoHostAvailableException: All host(s) tried for query failed (tried: /127.0.0.1:9042 (com.datastax.driver.core.ConnectionException: [/127.0.0.1:9042] Unexpected error during transport initialization (com.datastax.driver.core.OperationTimedOutException: [/127.0.0.1:9042] Operation timed out)))

如果有人对此有任何见解,将不胜感激。我在Datastax上按照这些说明准备服务器证书并启用客户端到节点加密。

共有1个答案

昝晗昱
2023-03-14

我可以用下面的代码来实现这一点。希望这有帮助。

Cassandra.Properties

# KeyStore Path
cassandra.cassks=classpath:cass.keystore.p12
# KeyStore Password
cassandra.casskspass=defkeypass
# KeyStore Type
cassandra.casskstype=pkcs12

# TrustStore Path
cassandra.cassts=classpath:cass.truststore.p12
# TrustStore Password
cassandra.casstspass=deftrustpass
# TrustStore Type
cassandra.casststype=pkcs12

CassandraProperties.java

@Configuration
@ConfigurationProperties("cassandra")
@PropertySource(value = "${classpath:conf/cassandra.properties}")
@Validated
@Data
public class CassandraProperties {

    @NotNull
    private Boolean ssl;

    @NotNull
    private String sslver;

    private Resource cassks;
    private String casskspass;
    private String casskstype;

    private Resource cassts;
    private String casstspass;
    private String casststype;
}

Cassandraconfig.java

public class CassandraConfig extends AbstractCassandraConfiguration {
    @Autowired
    private CassandraProperties cassandraProp;

    @Bean
    public CassandraClusterFactoryBean cluster() {
        CassandraClusterFactoryBean cluster = new CassandraClusterFactoryBean();
        cluster.setContactPoints(cassandraProp.getContactpoints());
        cluster.setPort(cassandraProp.getPort());

        if (true == cassandraProp.isSSEnabled()) {

            File KeyStoreFile = null;
            File TrustStoreFile = null;
            InputStream keyStoreIS = null;
            InputStream tustStoreIS = null;
            KeyStore keyStore = null;
            KeyStore trustStore = null;
            TrustManagerFactory tmf = null;
            KeyManagerFactory kmf = null;
            SSLContext sslContext = null;
            RemoteEndpointAwareJdkSSLOptions sslOptions = null;

            try {
                KeyStoreFile = cassandraProp.getCassks().getFile();

                keyStoreIS = new FileInputStream(KeyStoreFile);
                keyStore = KeyStore.getInstance(cassandraProp.getCasskstype());
                keyStore.load(keyStoreIS, cassandraProp.getCasskspass().toCharArray());

                TrustStoreFile = cassandraProp.getCassts().getFile();
                tustStoreIS = new FileInputStream(TrustStoreFile);
                trustStore = KeyStore.getInstance(cassandraProp.getCasststype());
                trustStore.load(tustStoreIS, cassandraProp.getCasstspass().toCharArray());

                tmf = TrustManagerFactory.getInstance("SunX509");
                tmf.init(trustStore);

                kmf = KeyManagerFactory.getInstance("SunX509");
                kmf.init(keyStore, cassandraProp.getCasskspass().toCharArray());

                sslContext = SSLContext.getInstance(cassandraProp.getSslver());
                sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

                sslOptions = new RemoteEndpointAwareJdkSSLOptions.Builder().withSSLContext(sslContext).build();

            } catch (NoSuchAlgorithmException | KeyStoreException | CertificateException | IOException
                    | KeyManagementException | UnrecoverableKeyException e) {
                e.printStackTrace();
            }

            cluster.setSslEnabled(true);
            cluster.setSslOptions(sslOptions);
        }
        return cluster;
    }
}
 类似资料:
  • 我的任务是为团队的代码设置集成测试。这些测试需要对Jersey 2.27中实现的RESTendpoint执行HTTPS请求。在寻找如何执行这种测试的过程中,我偶然发现了Baeldung的这篇文章,这篇文章向我指出了Jersey测试框架和他们为此目的实现的提供者容器。我选择了Jetty容器,因为我们的代码使用了一个“滚动您自己的”Jetty实例来完成这一切。我开始实施我们的测试,但在为提供rest请

  • 我正在尝试使用服务总线配置向导配置Windows服务总线(1.1)。当我尝试配置它时,我遇到以下错误。谁能告诉我出了什么问题吗。 [错误][5/9/2014 9:32:40AM]:系统。管理。自动化。CmdletInvocationException:在机器USHP2-10-056A上启动服务服务总线网关失败:超时已过期,操作尚未完成。--- 有关服务总线的配置信息,请参见下文 管理数据库SQL实

  • 我们正在使用amazon elb进行负载平衡。我们有一个SSL证书,用www(www.domain.com)标识我们的域。我们在apache conf中添加了重定向,将非www请求重定向到www。 我们现在面临的问题是当用户请求https://domain.com用户会看到一条警告,指出连接不是私有的。 我们认为这是因为 ELB 在 APACHE 有机会重定向之前处理 SSL 终止。我们的证书适用

  • 我们正在使用cloudfront为具有自定义域的图像提供服务。 我们希望能够使用SSL访问它们,例如

  • 我正在使用本地竹配置项生成IPA文件。竹作业能够从Git存储库中获取项目并成功地构建它,但在将其导出为IPA文件时,我遇到了路径问题。 Validate/users/admin/library/developer/xcode/deriveddata/stackapp-cmvkahtnfpsmsmecbxrmhrwzekn/BUILD/products/release-iphoneOS/stacka

  • 我试图在Spring Boot中使用SOAP web服务。我可以使用Spring MVC应用程序(使用web.xml而不使用Spring boot),但是我在使用Spring boot xml free Setup进行配置时遇到了困难。 下面是我的示例服务的代码,我试图为其生成wsdl。 我的Spring Boot配置如下: 当我点击URL localhost:8080/services时,我得到