@@ -2403,34 +2403,72 @@ private void reloadRemoteClusterCredentials(Settings settingsWithKeystore) {
24032403 public Map <String , String > getAuthContextForSlowLog () {
24042404 if (this .securityContext .get () != null && this .securityContext .get ().getAuthentication () != null ) {
24052405 Authentication authentication = this .securityContext .get ().getAuthentication ();
2406- Subject authenticatingSubject = authentication .getAuthenticatingSubject ();
2407- Subject effetctiveSubject = authentication .getEffectiveSubject ();
24082406 Map <String , String > authContext = new HashMap <>();
2409- if (authenticatingSubject .getUser () != null ) {
2410- authContext .put ("user.name" , authenticatingSubject .getUser ().principal ());
2411- authContext .put ("user.realm" , authenticatingSubject .getRealm ().getName ());
2412- if (authenticatingSubject .getUser ().fullName () != null ) {
2413- authContext .put ("user.full_name" , authenticatingSubject .getUser ().fullName ());
2414- }
2415- }
2416- // Only include effective user if different from authenticating user (run-as)
2417- if (effetctiveSubject .getUser () != null && effetctiveSubject .equals (authenticatingSubject ) == false ) {
2418- authContext .put ("user.effective.name" , effetctiveSubject .getUser ().principal ());
2419- authContext .put ("user.effective.realm" , effetctiveSubject .getRealm ().getName ());
2420- if (effetctiveSubject .getUser ().fullName () != null ) {
2421- authContext .put ("user.effective.full_name" , effetctiveSubject .getUser ().fullName ());
2422- }
2407+
2408+ // Handle Cross-Cluster Access (RCS 2.0) scenario
2409+ if (authentication .isCrossClusterAccess ()) {
2410+ Authentication originalAuthentication = Authentication .getAuthenticationFromCrossClusterAccessMetadata (authentication );
2411+ // Call the helper method for the originalAuthentication (from querying cluster)
2412+ populateAuthContextMap (originalAuthentication , authContext );
24232413 }
2424- authContext . put ( "auth.type" , authentication . getAuthenticationType (). name ());
2425- if ( authentication . isApiKey ()) {
2426- authContext . put ( "apikey.id" , authenticatingSubject . getMetadata (). get ( AuthenticationField . API_KEY_ID_KEY ). toString ());
2427- authContext . put ( "apikey.name" , authenticatingSubject . getMetadata (). get ( AuthenticationField . API_KEY_NAME_KEY ). toString () );
2414+ // Logic for obtaining non-cross-cluster access authentication information
2415+ else {
2416+ // Call the helper method for the authentication itself
2417+ populateAuthContextMap ( authentication , authContext );
24282418 }
24292419 return authContext ;
24302420 }
24312421 return Map .of ();
24322422 }
24332423
2424+ /**
2425+ * Helper method to populate authentication context fields for slow logs.
2426+ * This logic is common for both direct authentications and the nested
2427+ * original authentication in cross-cluster access scenarios.
2428+ *
2429+ * @param auth The Authentication object to extract details from.
2430+ * @param authContext The map to populate with authentication details.
2431+ */
2432+ private void populateAuthContextMap (Authentication auth , Map <String , String > authContext ) {
2433+ Subject authenticatingSubject = auth .getAuthenticatingSubject ();
2434+ Subject effectiveSubject = auth .getEffectiveSubject ();
2435+
2436+ // The primary user.name and user.realm fields should reflect the AUTHENTICATING user
2437+ if (authenticatingSubject .getUser () != null ) {
2438+ authContext .put ("user.name" , authenticatingSubject .getUser ().principal ());
2439+ authContext .put ("user.realm" , authenticatingSubject .getRealm ().getName ());
2440+ if (authenticatingSubject .getUser ().fullName () != null ) {
2441+ authContext .put ("user.full_name" , authenticatingSubject .getUser ().fullName ());
2442+ }
2443+ }
2444+
2445+ // Only include effective user if different from authenticating user (run-as)
2446+ if (auth .isRunAs ()) { // Use auth.isRunAs() for consistency
2447+ if (effectiveSubject .getUser () != null ) {
2448+ authContext .put ("user.effective.name" , effectiveSubject .getUser ().principal ());
2449+ authContext .put ("user.effective.realm" , effectiveSubject .getRealm ().getName ());
2450+ if (effectiveSubject .getUser ().fullName () != null ) {
2451+ authContext .put ("user.effective.full_name" , effectiveSubject .getUser ().fullName ());
2452+ }
2453+ }
2454+ }
2455+
2456+ // Auth type
2457+ authContext .put ("auth.type" , auth .getAuthenticationType ().name ());
2458+
2459+ // Add API key details if this authentication was an API key itself
2460+ if (auth .isApiKey ()) {
2461+ // These metadata fields are expected to be on the authenticating subject of the API key
2462+ // Use Objects.toString() for safety against null metadata values if not strictly guaranteed
2463+ authContext .put ("apikey.id" , Objects .toString (authenticatingSubject .getMetadata ().get (AuthenticationField .API_KEY_ID_KEY )));
2464+
2465+ Object apiKeyName = authenticatingSubject .getMetadata ().get (AuthenticationField .API_KEY_NAME_KEY );
2466+ if (apiKeyName != null ) { // Name can be null for API keys, so check explicitly
2467+ authContext .put ("apikey.name" , apiKeyName .toString ());
2468+ }
2469+ }
2470+ }
2471+
24342472 static final class ValidateLicenseForFIPS implements BiConsumer <DiscoveryNode , ClusterState > {
24352473 private final boolean inFipsMode ;
24362474 private final LicenseService licenseService ;
0 commit comments