Browse Source

Ensure PKI's delegated_by_realm metadata respect run-as (#91173)

When delegated PKI authentication is used, the delegatee's realm name is
added as a metadata field. This realm name should be the effective
subject's realm instead of that of the authenticating subject. This PR
ensures this is the case.
Yang Wang 3 years ago
parent
commit
315d4c79b3

+ 5 - 0
docs/changelog/91173.yaml

@@ -0,0 +1,5 @@
+pr: 91173
+summary: Ensure PKI's `delegated_by_realm` metadata respect run-as
+area: Authentication
+type: bug
+issues: []

+ 1 - 2
x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/pki/PkiRealm.java

@@ -214,8 +214,7 @@ public class PkiRealm extends Realm implements CachingRealm {
                 "pki_delegated_by_user",
                 token.getDelegateeAuthentication().getEffectiveSubject().getUser().principal(),
                 "pki_delegated_by_realm",
-                // TODO: this should be the realm of effective subject
-                token.getDelegateeAuthentication().getAuthenticatingSubject().getRealm().getName()
+                token.getDelegateeAuthentication().getEffectiveSubject().getRealm().getName()
             );
         } else {
             metadata = Map.of("pki_dn", token.dn());

+ 20 - 0
x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/pki/PkiRealmTests.java

@@ -414,6 +414,26 @@ public class PkiRealmTests extends ESTestCase {
         assertThat(result.getValue().roles().length, is(0));
         assertThat(result.getValue().metadata().get("pki_delegated_by_user"), is("mockup_delegate_username"));
         assertThat(result.getValue().metadata().get("pki_delegated_by_realm"), is("mockup_delegate_realm"));
+
+        // Delegatee is run-as
+        final Authentication runAsAuthentication = AuthenticationTestHelper.builder().realm().build(true);
+        assertThat(runAsAuthentication.isRunAs(), is(true));
+        delegatedToken = X509AuthenticationToken.delegated(new X509Certificate[] { certificate }, runAsAuthentication);
+        realmWithDelegation.expireAll(); // clear the cache so the user is built again
+        result = authenticate(delegatedToken, realmWithDelegation);
+        assertThat(result.getStatus(), equalTo(AuthenticationResult.Status.SUCCESS));
+        assertThat(result.getValue(), is(notNullValue()));
+        assertThat(result.getValue().principal(), is("Elasticsearch Test Node"));
+        assertThat(result.getValue().roles(), is(notNullValue()));
+        assertThat(result.getValue().roles().length, is(0));
+        assertThat(
+            result.getValue().metadata().get("pki_delegated_by_user"),
+            is(runAsAuthentication.getEffectiveSubject().getUser().principal())
+        );
+        assertThat(
+            result.getValue().metadata().get("pki_delegated_by_realm"),
+            is(runAsAuthentication.getEffectiveSubject().getRealm().getName())
+        );
     }
 
     public void testAuthenticationDelegationFailure() throws Exception {