Ask Your Question
0

How can SSL be used with CqlSessionFactoryBean in Springboot Cassandra?

asked 2021-04-08 11:00:00 +0000

bukephalos gravatar image

edit retag flag offensive close merge delete

1 Answer

Sort by » oldest newest most voted
0

answered 2022-11-20 03:00:00 +0000

devzero gravatar image

To use SSL with CqlSessionFactoryBean in Springboot Cassandra, you can follow the below steps:

  1. Generate Server and client certificates.

  2. Configure Cassandra to use SSL communication by specifying SSL enabled Cassandra’s server.xml configuration file.

  3. Import the trusted certificates into your keystore.

  4. Create a keystore and truststore on your Spring Boot application.

  5. Add the following properties to your application.yml file or application.properties file:

    1. to enable SSL

      # SSL config
      cassandra.truststore.type = JKS
      cassandra.truststore.password = changeit
      cassandra.ssl = true
      cassandra.keystore.type = JKS
      cassandra.keystore.password = changeit
      
    2. for Cassandra Cluster configuration

      # Cassandra Cluster Configuration
      cassandra.contact-points = localhost
      cassandra.port = 9042
      cassandra.keyspace-name = test_keyspace
      cassandra.base-packages = com.example.demo.entity
      cassandra.username = cassandra
      cassandra.password = cassandra
      cassandra.entity-base-package = com.example.demo.entity
      cassandra.cluster-name= Test Cluster
      
  6. Finally, configure the CqlSessionFactoryBean by extending the AbstractCassandraConfiguration class and override the setSslEnabled() and setSslOptions() methods.

Here is an example:

@Configuration
@EnableCassandraRepositories
public class CassandraConfig extends AbstractCassandraConfiguration {

    @Value("${cassandra.contact-points}")
    private String contactPoints;

    @Value("${cassandra.port}")
    private int port;

    @Value("${cassandra.keyspace-name}")
    private String keySpace;

    @Value("${cassandra.ssl}")
    private boolean sslEnabled;

    @Value("${cassandra.username}")
    private String username;

    @Value("${cassandra.password}")
    private String password;

    @Value("${cassandra.entity-base-package}")
    private String entityBasePackage;

    @Value("${cassandra.cluster-name}")
    private String clusterName;

    @Value("${cassandra.truststore.password}")
    private String truststorePassword;

    @Value("${cassandra.keystore.password}")
    private String keystorePassword;

    @Value("${cassandra.truststore.type}")
    private String truststoreType;

    @Value("${cassandra.keystore.type}")
    private String keystoreType;

    @Override
    protected String getKeyspaceName() {
        return keySpace;
    }

    @Override
    protected String getContactPoints() {
        return contactPoints;
    }

    @Override
    protected int getPort() {
        return port;
    }

    @Override
    protected String getUsername() {
        return username;
    }

    @Override
    protected String getPassword() {
        return password;
    }

    @Bean
    @Override
    public CassandraClusterFactoryBean cluster() {
        final CassandraClusterFactoryBean cluster = new CassandraClusterFactoryBean();
        cluster.setContactPoints(contactPoints);
        cluster.setPort(port);
        cluster.setClusterName(clusterName);
        cluster.setUsername(username);
        cluster.setPassword(password);

        if (sslEnabled) {
            cluster.setSslEnabled(true);
            cluster.setSslOptions(getSslOptions());
        }
        return cluster;
    }

     public SSLContext sslContext() throws Exception {
        KeyStore ks = KeyStore.getInstance(keystoreType);
        ks.load(getResource("classpath:trusted-certificates.jks").getInputStream(), keystorePassword.toCharArray());

        KeyStore tks = KeyStore.getInstance(truststoreType);
        tks.load(getResource("classpath:keystore.jks").getInputStream(), truststorePassword.toCharArray());

        TrustManagerFactory tmf =
            TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(tks);

        KeyManagerFactory kmf =
            KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        kmf.init(ks, keystorePassword.toCharArray());

        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());

        return sslContext;
    }


    public SSLOptions getSslOptions() throws Exception {
        return JdkSSLOptions.builder().withSSLContext(sslContext()).build();
    }
}

As shown in the above example, we have created a class named CassandraConfig that extends AbstractCassandraConfiguration and overridden several methods getKeyspaceName(), getContactPoints(), getPort() etc. to give the respective required information. We also set up the SSL context by creating and setting up keystore and truststore files. Finally, we created the SslOptions object that will be used to configure SSL on CqlSessionFactoryBean.

With this configuration, SSL will be enabled while communicating with Cassandra using a CqlSessionFactoryBean.

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account. This space is reserved only for answers. If you would like to engage in a discussion, please instead post a comment under the question or an answer that you would like to discuss

Add Answer


Question Tools

Stats

Asked: 2021-04-08 11:00:00 +0000

Seen: 19 times

Last updated: Nov 20 '22