diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/pki/PkiRealm.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/pki/PkiRealm.java index be2859cdc4538..b95bf7d220436 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/pki/PkiRealm.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/pki/PkiRealm.java @@ -325,6 +325,17 @@ public void expireAll() { } } + @Override + public void usageStats(ActionListener> listener) { + super.usageStats(ActionListener.wrap(stats -> { + stats.put("has_truststore", trustManager != null); + stats.put("has_authorization_realms", delegatedRealms != null && delegatedRealms.hasDelegation()); + stats.put("has_default_username_pattern", PkiRealmSettings.DEFAULT_USERNAME_PATTERN.equals(principalPattern.pattern())); + stats.put("is_authentication_delegated", delegationEnabled); + listener.onResponse(stats); + }, listener::onFailure)); + } + private void validateAuthenticationDelegationConfiguration(RealmConfig config) { if (delegationEnabled) { List exceptionMessages = new ArrayList<>(2); diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/pki/PkiRealmTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/pki/PkiRealmTests.java index 62637b6408f03..053be8f5bed5f 100644 --- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/pki/PkiRealmTests.java +++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/pki/PkiRealmTests.java @@ -41,6 +41,7 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.regex.Pattern; @@ -74,11 +75,12 @@ public void setup() throws Exception { when(licenseState.isAuthorizationRealmAllowed()).thenReturn(true); } - public void testTokenSupport() { + public void testTokenSupport() throws Exception { RealmConfig config = new RealmConfig(new RealmConfig.RealmIdentifier("pki", "my_pki"), globalSettings, TestEnvironment.newEnvironment(globalSettings), new ThreadContext(globalSettings)); PkiRealm realm = new PkiRealm(config, mock(UserRoleMapper.class)); + assertRealmUsageStats(realm, false, false, true, false); assertThat(realm.supports(null), is(false)); assertThat(realm.supports(new UsernamePasswordToken("", new SecureString(new char[0]))), is(false)); assertThat(realm.supports(new X509AuthenticationToken(new X509Certificate[0], randomBoolean())), is(true)); @@ -117,7 +119,6 @@ private void assertSuccessfulAuthentication(Set roles) throws Exception final String expectedUsername = PkiRealm.getPrincipalFromSubjectDN(Pattern.compile(PkiRealmSettings.DEFAULT_USERNAME_PATTERN), token, NoOpLogger.INSTANCE); final AuthenticationResult result = authenticate(token, realm); - final PlainActionFuture future; assertThat(result.getStatus(), is(AuthenticationResult.Status.SUCCESS)); User user = result.getUser(); assertThat(user, is(notNullValue())); @@ -202,6 +203,7 @@ public void testCustomUsernamePatternMatches() throws Exception { X509Certificate certificate = readCert(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt")); UserRoleMapper roleMapper = buildRoleMapper(); PkiRealm realm = buildRealm(roleMapper, settings); + assertRealmUsageStats(realm, false, false, false, false); threadContext.putTransient(PkiRealm.PKI_CERT_HEADER_NAME, new X509Certificate[] { certificate }); X509AuthenticationToken token = realm.token(threadContext); @@ -221,6 +223,7 @@ public void testCustomUsernamePatternMismatchesAndNullToken() throws Exception { X509Certificate certificate = readCert(getDataPath("/org/elasticsearch/xpack/security/transport/ssl/certs/simple/testnode.crt")); UserRoleMapper roleMapper = buildRoleMapper(); PkiRealm realm = buildRealm(roleMapper, settings); + assertRealmUsageStats(realm, false, false, false, false); threadContext.putTransient(PkiRealm.PKI_CERT_HEADER_NAME, new X509Certificate[] { certificate }); X509AuthenticationToken token = realm.token(threadContext); @@ -241,6 +244,7 @@ public void testVerificationUsingATruststore() throws Exception { .build(); ThreadContext threadContext = new ThreadContext(globalSettings); PkiRealm realm = buildRealm(roleMapper, settings); + assertRealmUsageStats(realm, true, false, true, false); threadContext.putTransient(PkiRealm.PKI_CERT_HEADER_NAME, new X509Certificate[] { certificate }); @@ -300,6 +304,8 @@ public void testAuthenticationDelegationSuccess() throws Exception { .setSecureSettings(secureSettings) .build(); PkiRealm realmWithDelegation = buildRealm(roleMapper, settings); + assertRealmUsageStats(realmWithDelegation, true, false, true, true); + AuthenticationResult result = authenticate(delegatedToken, realmWithDelegation); assertThat(result.getStatus(), equalTo(AuthenticationResult.Status.SUCCESS)); assertThat(result.getUser(), is(notNullValue())); @@ -322,6 +328,7 @@ public void testAuthenticationDelegationFailure() throws Exception { .setSecureSettings(secureSettings) .build(); PkiRealm realmNoDelegation = buildRealm(roleMapper, settings); + assertRealmUsageStats(realmNoDelegation, true, false, true, false); AuthenticationResult result = authenticate(delegatedToken, realmNoDelegation); assertThat(result.getStatus(), equalTo(AuthenticationResult.Status.CONTINUE)); @@ -342,6 +349,7 @@ public void testVerificationFailsUsingADifferentTruststore() throws Exception { .build(); ThreadContext threadContext = new ThreadContext(settings); PkiRealm realm = buildRealm(roleMapper, settings); + assertRealmUsageStats(realm, true, false, true, false); threadContext.putTransient(PkiRealm.PKI_CERT_HEADER_NAME, new X509Certificate[] { certificate }); @@ -454,6 +462,7 @@ public void testDelegatedAuthorization() throws Exception { .build(); final UserRoleMapper roleMapper = buildRoleMapper(Collections.emptySet(), token.dn()); final PkiRealm pkiRealm = buildRealm(roleMapper, realmSettings, otherRealm); + assertRealmUsageStats(pkiRealm, false, true, true, false); AuthenticationResult result = authenticate(token, pkiRealm); assertThat(result.getStatus(), equalTo(AuthenticationResult.Status.SUCCESS)); @@ -478,6 +487,17 @@ public void testX509AuthenticationTokenOrdered() throws Exception { assertThat(e.getMessage(), is("certificates chain array is not ordered")); } + private void assertRealmUsageStats(Realm realm, Boolean hasTruststore, Boolean hasAuthorizationRealms, + Boolean hasDefaultUsernamePattern, Boolean isAuthenticationDelegated) throws Exception { + final PlainActionFuture> future = new PlainActionFuture<>(); + realm.usageStats(future); + Map usage = future.get(); + assertThat(usage.get("has_truststore"), is(hasTruststore)); + assertThat(usage.get("has_authorization_realms"), is(hasAuthorizationRealms)); + assertThat(usage.get("has_default_username_pattern"), is(hasDefaultUsernamePattern)); + assertThat(usage.get("is_authentication_delegated"), is(isAuthenticationDelegated)); + } + public void testX509AuthenticationTokenCaching() throws Exception { X509Certificate[] mockCertChain = new X509Certificate[2]; mockCertChain[0] = mock(X509Certificate.class);