From 281c1dc92ccb09c57ed0eeccc3d7935b4e051ebc Mon Sep 17 00:00:00 2001 From: Joel Shepherd Date: Tue, 14 Oct 2025 00:12:10 +0000 Subject: [PATCH] Enable IAuthenticator to declare supported and alterable role options With negotiated authentication (CEP-50), nodes may be configured with multiple authenticators. Prior to this change, a number of areas in the code assumed that there was a single configured authenticator and contained logic that switched depending on the authenticator type. This logic won't work when multiple authenticators can be configured. This change eliminates most calls to DataDescriptor.getAuthenticator(), by enabling individual authenticators to declare the role attributes they support, requiring callers to specify the type of authenticator they're looking for, and directly returning whether the node can enforce authn or not rather than inferring it by the presence of an authenticator. Testing done: Unit tests for auth and config packages; d-tests for auth-related functionality (e.g. ColumnMasks). patch by Joel Shepherd; reviewed by Stefan Miklosovic, Andy Tolbert for CASSANDRA-20834 --- CHANGES.txt | 1 + .../org/apache/cassandra/auth/AuthConfig.java | 12 ++ .../cassandra/auth/CassandraRoleManager.java | 72 ++++++----- .../apache/cassandra/auth/IAuthenticator.java | 23 ++++ .../auth/MutualTlsAuthenticator.java | 5 +- .../auth/NetworkPermissionsCache.java | 2 +- .../cassandra/auth/PasswordAuthenticator.java | 37 +++++- src/java/org/apache/cassandra/auth/Roles.java | 2 +- .../cassandra/config/DatabaseDescriptor.java | 36 ++++++ .../db/virtual/CredentialsCacheKeysTable.java | 15 +-- .../cassandra/service/CassandraDaemon.java | 2 +- .../apache/cassandra/service/ClientState.java | 4 +- test/conf/cassandra-passwordauth.yaml | 93 ++++++++++++++ .../apache/cassandra/auth/AuthConfigTest.java | 117 ++++++++++++++---- 14 files changed, 347 insertions(+), 74 deletions(-) create mode 100644 test/conf/cassandra-passwordauth.yaml diff --git a/CHANGES.txt b/CHANGES.txt index bceda5b9d8..579b190f00 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 6.0-alpha2 + * Enable IAuthenticator to declare supported and alterable role options (CASSANDRA-20834) * Avoid capturing lambda allocation in UnfilteredSerializer.deserializeRowBody (CASSANDRA-21289) * Avoid Cell iterator allocation for alive rows in MetricsRecording transformation of ReadCommand (CASSANDRA-21288) * Reuse a single TrackedDataInputPlus instance per UnfilteredSerializer (CASSANDRA-21296) diff --git a/src/java/org/apache/cassandra/auth/AuthConfig.java b/src/java/org/apache/cassandra/auth/AuthConfig.java index 67d4490790..86e1f626ff 100644 --- a/src/java/org/apache/cassandra/auth/AuthConfig.java +++ b/src/java/org/apache/cassandra/auth/AuthConfig.java @@ -20,6 +20,8 @@ package org.apache.cassandra.auth; import java.util.List; +import com.google.common.annotations.VisibleForTesting; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,6 +40,16 @@ public final class AuthConfig private static boolean initialized; + /** + * Resets the initialized flag, enabling AuthConfig to be reconfigured multiple times within a single + * test case. + */ + @VisibleForTesting + static void reset() + { + initialized = false; + } + public static void applyAuth() { // some tests need this diff --git a/src/java/org/apache/cassandra/auth/CassandraRoleManager.java b/src/java/org/apache/cassandra/auth/CassandraRoleManager.java index 791ff02ba1..ec4f873b5c 100644 --- a/src/java/org/apache/cassandra/auth/CassandraRoleManager.java +++ b/src/java/org/apache/cassandra/auth/CassandraRoleManager.java @@ -21,7 +21,6 @@ import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -91,29 +90,16 @@ import static org.apache.cassandra.service.QueryState.forInternalCalls; import static org.apache.cassandra.utils.ByteBufferUtil.bytes; /** - * Responsible for the creation, maintenance and deletion of roles - * for the purposes of authentication and authorization. - * Role data is stored internally, using the roles and role_members tables - * in the system_auth keyspace. + * Responsible for the creation, maintenance and deletion of roles for the purposes of authentication and + * authorization. Role data is stored internally, using the roles and role_members tables in the system_auth + * keyspace. * - * Additionally, if org.apache.cassandra.auth.PasswordAuthenticator is used, - * encrypted passwords are also stored in the system_auth.roles table. This - * coupling between the IAuthenticator and IRoleManager implementations exists - * because setting a role's password via CQL is done with a CREATE ROLE or - * ALTER ROLE statement, the processing of which is handled by IRoleManager. - * As IAuthenticator is concerned only with credentials checking and has no - * means to modify passwords, PasswordAuthenticator depends on - * CassandraRoleManager for those functions. - * - * Alternative IAuthenticator implementations may be used in conjunction with - * CassandraRoleManager, but WITH PASSWORD = 'password' will not be supported - * in CREATE/ALTER ROLE statements. - * - * Such a configuration could be implemented using a custom IRoleManager that - * extends CassandraRoleManager and which includes Option.PASSWORD in the {@code Set