After upgrading to spring boot 2.3.0, the spring data cassandra reactive failed to work due to authentication issue. We are using plain text username & password authentication. The issue seems to be you need to set advanced.auth-provider.class here:

    private Config cassandraConfiguration(CassandraProperties properties) {
        CassandraDriverOptions options = new CassandraDriverOptions();
        PropertyMapper map = PropertyMapper.get();
        map.from(properties.getSessionName()).whenHasText()
                .to((sessionName) -> options.add(DefaultDriverOption.SESSION_NAME, sessionName));
        map.from(properties::getUsername).whenNonNull()
                .to((username) -> options.add(DefaultDriverOption.AUTH_PROVIDER_USER_NAME, username)
                        .add(DefaultDriverOption.AUTH_PROVIDER_PASSWORD, properties.getPassword()));
        map.from(properties::getCompression).whenNonNull()
                .to((compression) -> options.add(DefaultDriverOption.PROTOCOL_COMPRESSION, compression));
        mapConnectionOptions(properties, options);
        mapPoolingOptions(properties, options);
        mapRequestOptions(properties, options);
        map.from(mapContactPoints(properties))
                .to((contactPoints) -> options.add(DefaultDriverOption.CONTACT_POINTS, contactPoints));
        map.from(properties.getLocalDatacenter()).to(
                (localDatacenter) -> options.add(DefaultDriverOption.LOAD_BALANCING_LOCAL_DATACENTER, localDatacenter));
        ConfigFactory.invalidateCaches();
        return ConfigFactory.defaultOverrides().withFallback(options.build())
                .withFallback(ConfigFactory.defaultReference()).resolve();
    }

Comment From: valeyko

I have the same issue. As workaround, you can specify auth provider class using DriverConfigLoaderBuilderCustomizer:

@Configuration
class CassandraConfiguration {
    @Bean
    fun authProviderCustomizer() = DriverConfigLoaderBuilderCustomizer { builder ->
        builder.withString(DefaultDriverOption.AUTH_PROVIDER_CLASS, "com.datastax.oss.driver.internal.core.auth.PlainTextAuthProvider")
    }
}

Comment From: wilkinsona

Thanks, @valeyko. Rather than settiing advanced.auth-provider.class, the recommendation in the documentation seems to be that withAuthCredentials(String, String) on the CqlSessionBuilder is used instead. This has the benefit of removing the reference to a class in an internal package.

You can configure the auth credentials in Spring Boot with a CqlSessionBuilderCustomizer:

@Bean
CqlSessionBuilderCustomizer authCustomizer(CassandraProperties properties) {
    return (builder) -> builder.withAuthCredentials(properties.getUsername(), properties.getPassword());
}

@valeyko @andyfromktm can you please try the above and let us know if it resolves your problem. If it does, we can update CassandraAutoConfiguration to apply this configuration automatically.

Comment From: wilkinsona

When we fix this, we should add an integration test that covers username and password authentication. With thanks to @bsideup for some guidance, we can create a Cassandra instance with its password authenticator configured using the following custom container:

static final class PasswordAuthenticatorCassandraContainer
        extends CassandraContainer<PasswordAuthenticatorCassandraContainer> {
    @Override
    protected void containerIsCreated(String containerId) {
        String config = this.copyFileFromContainer("/etc/cassandra/cassandra.yaml",
                (stream) -> StreamUtils.copyToString(stream, StandardCharsets.UTF_8));
        String updatedConfig = config.replace("authenticator: AllowAllAuthenticator",
                "authenticator: PasswordAuthenticator");
        this.copyFileToContainer(Transferable.of(updatedConfig.getBytes(StandardCharsets.UTF_8)),
                "/etc/cassandra/cassandra.yaml");
    }
}

Comment From: valeyko

Thank you, @wilkinsona, your solution works as well for me

Comment From: wilkinsona

The test that was added for this seems to flaky fairly consistently. On the first attempt, authentication fails:


2020-06-10 09:25:32.606  INFO 3332 --- [     s4-admin-0] c.d.oss.driver.internal.core.time.Clock  : Using native clock for microsecond precision |  
-- | --
  | 2020-06-10 09:25:32.612  INFO 3332 --- [        s4-io-0] c.d.o.d.i.core.channel.ChannelFactory    : [s4] Failed to connect with protocol DSE_V2, retrying with DSE_V1 |  
  | 2020-06-10 09:25:32.620  INFO 3332 --- [        s4-io-1] c.d.o.d.i.core.channel.ChannelFactory    : [s4] Failed to connect with protocol DSE_V1, retrying with V4 |  
  | 2020-06-10 09:25:32.633  WARN 3332 --- [     s4-admin-1] c.d.o.d.i.c.control.ControlConnection    : [s4] Authentication error (AuthenticationException: Authentication error on node /172.17.0.1:32835: server replied with 'Provided username cassandra and/or password are incorrect' to AuthResponse request) |  
  | 2020-06-10 09:25:32.633  WARN 3332 --- [     s4-admin-1] c.d.o.d.i.c.control.ControlConnection    : [s4] Authentication errors encountered on all contact points. Please check your authentication configuration.

It then succeeds upon retry.

Comment From: snicoll

@adutra do you have any insight as why it would be flaky?