@@ -2403,34 +2403,72 @@ private void reloadRemoteClusterCredentials(Settings settingsWithKeystore) {
2403
2403
public Map <String , String > getAuthContextForSlowLog () {
2404
2404
if (this .securityContext .get () != null && this .securityContext .get ().getAuthentication () != null ) {
2405
2405
Authentication authentication = this .securityContext .get ().getAuthentication ();
2406
- Subject authenticatingSubject = authentication .getAuthenticatingSubject ();
2407
- Subject effetctiveSubject = authentication .getEffectiveSubject ();
2408
2406
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 );
2423
2413
}
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 );
2428
2418
}
2429
2419
return authContext ;
2430
2420
}
2431
2421
return Map .of ();
2432
2422
}
2433
2423
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
+
2434
2472
static final class ValidateLicenseForFIPS implements BiConsumer <DiscoveryNode , ClusterState > {
2435
2473
private final boolean inFipsMode ;
2436
2474
private final LicenseService licenseService ;
0 commit comments