Skip to content

Commit 1fded2a

Browse files
committed
Add support for Kerberos AuthProvider
1 parent dca3a6e commit 1fded2a

File tree

5 files changed

+89
-0
lines changed

5 files changed

+89
-0
lines changed

Diff for: CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
99
- Add a parameter `fetchsize` to specify a default fetch size for all the queries returning result sets. This value is
1010
the number of rows the server will return in each network frame (see
1111
[paging documentation](https://docs.datastax.com/en/developer/java-driver/latest/manual/core/paging/)).
12+
- Add support for Kerberos authentication provider.
1213
### Changed
1314
- Modify the types of some columns in the result sets of the following methods of `CassandraDatabaseMetadata` to respect
1415
the JDBC API specifications:

Diff for: pom.xml

+8
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@
114114
<!-- Versions for dependencies -->
115115
<checkstyle.version>9.3</checkstyle.version>
116116
<caffeine.version>2.9.3</caffeine.version>
117+
<cassandra-driver-krb5.version>3.0.0</cassandra-driver-krb5.version>
117118
<commons-collections.version>4.4</commons-collections.version>
118119
<commons-io.version>2.15.1</commons-io.version>
119120
<commons-lang3.version>3.14.0</commons-lang3.version>
@@ -201,6 +202,13 @@
201202
<version>${semver4j.version}</version>
202203
</dependency>
203204

205+
<!-- Kerberos Auth provider support -->
206+
<dependency>
207+
<groupId>com.instaclustr</groupId>
208+
<artifactId>cassandra-driver-kerberos</artifactId>
209+
<version>${cassandra-driver-krb5.version}</version>
210+
</dependency>
211+
204212
<!-- Unit tests libraries -->
205213
<dependency>
206214
<groupId>org.mockito</groupId>

Diff for: src/main/java/com/ing/data/cassandra/jdbc/SessionHolder.java

+13
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@
4141
import com.ing.data.cassandra.jdbc.codec.TinyintToIntCodec;
4242
import com.ing.data.cassandra.jdbc.codec.VarintToIntCodec;
4343
import com.ing.data.cassandra.jdbc.utils.ContactPoint;
44+
import com.instaclustr.cassandra.driver.auth.KerberosAuthProviderBase;
45+
import com.instaclustr.cassandra.driver.auth.ProgrammaticKerberosAuthProvider;
4446
import org.apache.commons.lang3.StringUtils;
4547
import org.apache.commons.lang3.math.NumberUtils;
4648
import org.slf4j.Logger;
@@ -65,6 +67,7 @@
6567
import static com.ing.data.cassandra.jdbc.utils.DriverUtil.JSSE_TRUSTSTORE_PASSWORD_PROPERTY;
6668
import static com.ing.data.cassandra.jdbc.utils.DriverUtil.JSSE_TRUSTSTORE_PROPERTY;
6769
import static com.ing.data.cassandra.jdbc.utils.ErrorConstants.SSL_CONFIG_FAILED;
70+
import static com.ing.data.cassandra.jdbc.utils.JdbcUrlUtil.TAG_USE_KERBEROS;
6871
import static com.ing.data.cassandra.jdbc.utils.JdbcUrlUtil.TAG_CLOUD_SECURE_CONNECT_BUNDLE;
6972
import static com.ing.data.cassandra.jdbc.utils.JdbcUrlUtil.TAG_CONFIG_FILE;
7073
import static com.ing.data.cassandra.jdbc.utils.JdbcUrlUtil.TAG_CONNECT_TIMEOUT;
@@ -203,6 +206,7 @@ private Session createSession(final Properties properties) throws SQLException {
203206
this.properties.remove(TAG_CONNECT_TIMEOUT);
204207
this.properties.remove(TAG_KEEP_ALIVE);
205208
this.properties.remove(TAG_TCP_NO_DELAY);
209+
this.properties.remove(TAG_USE_KERBEROS);
206210
LOG.info("The configuration file {} will be used and will override the parameters defined into the "
207211
+ "JDBC URL except contact points and keyspace.", configurationFilePath);
208212
} else {
@@ -234,6 +238,8 @@ private Session createSession(final Properties properties) throws SQLException {
234238
if (NumberUtils.isParsable(requestTimeoutRawValue)) {
235239
requestTimeout = Integer.parseInt(requestTimeoutRawValue);
236240
}
241+
final boolean useKerberosAuthProvider = Boolean.TRUE.toString().equals(properties.getProperty(TAG_USE_KERBEROS,
242+
StringUtils.EMPTY));
237243

238244
// Instantiate the session builder and set the contact points.
239245
final CqlSessionBuilder builder = CqlSession.builder();
@@ -328,6 +334,13 @@ private Session createSession(final Properties properties) throws SQLException {
328334
}
329335
}
330336

337+
// Set Kerberos Auth provider if required.
338+
if (useKerberosAuthProvider) {
339+
builder.withAuthProvider(new ProgrammaticKerberosAuthProvider(
340+
KerberosAuthProviderBase.KerberosAuthOptions.builder().build()
341+
));
342+
}
343+
331344
// Declare and register codecs.
332345
final List<TypeCodec<?>> codecs = new ArrayList<>();
333346
codecs.add(new TimestampToLongCodec());

Diff for: src/main/java/com/ing/data/cassandra/jdbc/utils/JdbcUrlUtil.java

+14
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,17 @@ public final class JdbcUrlUtil {
223223
*/
224224
public static final String TAG_PASSWORD = "password";
225225

226+
/**
227+
* JDBC URL parameter key for Kerberos auth provider enabling.
228+
*/
229+
public static final String KEY_USE_KERBEROS = "usekrb5";
230+
231+
/**
232+
* Property name used to retrieve the Kerberos auth provider enabling when the connection to Cassandra is
233+
* established. This property is mapped from the JDBC URL parameter {@code usekrb5}.
234+
*/
235+
public static final String TAG_USE_KERBEROS = "useKerberos";
236+
226237
/**
227238
* JDBC URL parameter key for the request timeout.
228239
*/
@@ -420,6 +431,9 @@ public static Properties parseURL(final String url) throws SQLException {
420431
if (params.containsKey(KEY_PASSWORD)) {
421432
props.setProperty(TAG_PASSWORD, params.get(KEY_PASSWORD));
422433
}
434+
if (params.containsKey(KEY_USE_KERBEROS)) {
435+
props.setProperty(TAG_USE_KERBEROS, params.get(KEY_USE_KERBEROS));
436+
}
423437
if (params.containsKey(KEY_REQUEST_TIMEOUT)) {
424438
props.setProperty(TAG_REQUEST_TIMEOUT, params.get(KEY_REQUEST_TIMEOUT));
425439
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Licensed under the Apache License, Version 2.0 (the "License");
3+
* you may not use this file except in compliance with the License.
4+
* You may obtain a copy of the License at
5+
*
6+
* http://www.apache.org/licenses/LICENSE-2.0
7+
*
8+
* Unless required by applicable law or agreed to in writing, software
9+
* distributed under the License is distributed on an "AS IS" BASIS,
10+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
* See the License for the specific language governing permissions and
12+
* limitations under the License.
13+
*/
14+
package com.ing.data.cassandra.jdbc;
15+
16+
import com.datastax.oss.driver.api.core.auth.AuthProvider;
17+
import com.instaclustr.cassandra.driver.auth.KerberosAuthProviderBase;
18+
import org.junit.jupiter.api.BeforeAll;
19+
import org.junit.jupiter.api.Test;
20+
21+
import java.util.Optional;
22+
23+
import static org.junit.jupiter.api.Assertions.assertEquals;
24+
import static org.junit.jupiter.api.Assertions.assertNotNull;
25+
import static org.junit.jupiter.api.Assertions.assertTrue;
26+
27+
28+
/**
29+
* Test connection using Kerberos Auth provider.
30+
*/
31+
class KerberosAuthProviderTest extends UsingCassandraContainerTest {
32+
33+
private static final String KEYSPACE = "system";
34+
35+
@BeforeAll
36+
static void finalizeSetUpTests() throws Exception {
37+
initConnection(KEYSPACE, "localdatacenter=datacenter1", "usekrb5=true");
38+
}
39+
40+
@Test
41+
void givenValidConnectionString_whenGetConnection_createConnectionWithKrb5Provider() throws Exception {
42+
assertNotNull(sqlConnection);
43+
assertNotNull(sqlConnection.getSession());
44+
assertNotNull(sqlConnection.getSession().getContext());
45+
final Optional<AuthProvider> configuredAuthProvider = sqlConnection.getSession().getContext().getAuthProvider();
46+
assertTrue(configuredAuthProvider.isPresent());
47+
assertTrue(KerberosAuthProviderBase.class.isAssignableFrom(configuredAuthProvider.get().getClass()));
48+
assertTrue(sqlConnection.getSession().getKeyspace().isPresent());
49+
assertEquals(KEYSPACE, sqlConnection.getSession().getKeyspace().get().asCql(true));
50+
sqlConnection.close();
51+
}
52+
53+
}

0 commit comments

Comments
 (0)