Authentication

For clients connecting to a DSE cluster secured with DseAuthenticator, three authentication providers are included:

  • PlainTextAuthProvider: plain-text authentication using username and password.
  • DsePlainTextAuthProvider: SASL authentication using the PLAIN mechanism.
  • DseGSSAPIAuthProvider: GSSAPI authentication.

NOTE: The PlainTextAuthProvider should only be used when authenticating against Apache Cassandra® clusters, not DSE. See the OSS driver 4 manual for more on configuring that provider.

To activate a provider, you must include an auth-provider section in the configuration. For plain text, you can supply the username and password like this:

dse-java-driver {
  advanced.auth-provider {
      class = DsePlainTextAuthProvider
      username = cassandra
      password = cassandra
   }
 }

Example configuration for GSSAPI authentication:

dse-java-driver {
  advanced.auth-provider {
      class = DseGssApiAuthProvider
      login-configuration {
          principal = "user principal here ex cassandra@DATASTAX.COM"
          useKeyTab = "true"
          refreshKrb5Config = "true"
          keyTab = "Path to keytab file here"
      }
   }
 }

See the advanced.auth-provider section in dse-reference.conf for more details.

You can also pass an authenticator instance while building the session:

DseSession session =
    DseSession.builder()
        .withAuthProvider(new MyCustomAuthProvider())
        .build();

For convenience, there are shortcuts that take the credentials directly:

DseSession session =
    DseSession.builder()
        .withAuthCredentials("user", "pass")
        .build();

// Proxy authentication: connect with user1's credentials, but will act as user2
DseSession session =
    DseSession.builder()
        .withAuthCredentials("user1", "pass", "user2")
        .build();

One downside of withAuthCredentials is that the credentials are stored in clear text in memory; this means they are vulnerable to an attacker who is able to perform memory dumps. If this is not acceptable for you, consider writing your own provider implementation (DsePlainTextAuthProviderBase and DseGssApiAuthProviderBase are good starting points).

Proxy authentication

DSE allows a user to connect as another user or role:

-- Allow bob to connect as alice:
GRANT PROXY.LOGIN ON ROLE 'alice' TO 'bob'

Once connected, all authorization checks will be performed against the proxy role (alice in this example).

To use proxy authentication with the driver, you need to provide the authorization-id, in other words the name of the role you want to connect as.

Example for plain text authentication:

dse-java-driver {
  advanced.auth-provider {
      class = DsePlainTextAuthProvider
      username = bob
      password = bob's password
      authorization-id = alice
   }
 }

With the GSSAPI (Kerberos) provider:

dse-java-driver {
  advanced.auth-provider {
      class = DseGssApiAuthProvider
      authorization-id = alice
      login-configuration {
          principal = "user principal here ex bob@DATASTAX.COM"
          useKeyTab = "true"
          refreshKrb5Config = "true"
          keyTab = "Path to keytab file here"
      }
   }
 }

Proxy execution

Proxy execution is similar to proxy authentication, but it applies to a single query, not the whole session.

-- Allow bob to execute queries as alice:
GRANT PROXY.EXECUTE ON ROLE 'alice' TO 'bob'

For this scenario, you would not add the authorization-id = alice to your configuration. Instead, use ProxyAuthentication.executeAs to wrap your query with the correct authorization for the execution:

import com.datastax.dse.driver.api.core.auth.ProxyAuthentication;

SimpleStatement statement = SimpleStatement.newInstance("some query");
// executeAs returns a new instance, you need to re-assign
statement = ProxyAuthentication.executeAs("alice", statement);
session.execute(statement);