From 24429182425fe9a152c45484279d922c2d1cddd4 Mon Sep 17 00:00:00 2001
From: Justin Cranford
Date: Mon, 11 Oct 2021 16:57:08 -0400
Subject: [PATCH 01/25] Return API KEY name in _authentication response
Responses to POST /_security/api_key includes id, name, metadata,
api_key (shared secret), and encoded (base64 of id:api_key).
Requests to GET /_security/_authenticate returns data about the user,
but not the API KEY.
When authenticating using an API KEY, return API KEY info map in the
response. The initial feature request asked for 'name'. However, the
request's Authentication header contains 'encoded', so the decoded
'id' will be returned for convenience too.
When authenticating using any other method, API KEY info map is
omitted.
Closes #70306
---
.../runConfigurations/Debug_Elasticsearch.xml | 2 +-
.../client/security/AuthenticateResponse.java | 77 +++++++++++++++++--
.../security/AuthenticateResponseTests.java | 64 ++++++++++-----
.../security/CreateTokenResponseTests.java | 9 ++-
...elegatePkiAuthenticationResponseTests.java | 2 +-
.../xpack/core/security/SecurityContext.java | 23 +++---
.../security/authc/ApiKeyServiceField.java | 21 +++++
.../core/security/authc/Authentication.java | 21 +++--
.../security/authc/AuthenticationField.java | 2 -
.../security/authc/AuthenticationResult.java | 16 ++--
.../ManageOwnApiKeyClusterPrivilege.java | 4 +-
.../security/authc/AuthenticationTests.java | 3 +-
.../ManageOwnApiKeyClusterPrivilegeTests.java | 9 ++-
.../xpack/security/apikey/ApiKeyRestIT.java | 37 +++++++++
.../xpack/security/authc/FileRealmAuthIT.java | 4 +
.../security/authc/NativeRealmAuthIT.java | 4 +
.../xpack/security/authc/PkiRealmAuthIT.java | 4 +
.../security/authc/ReservedRealmAuthIT.java | 4 +
.../authc/SecurityRealmSmokeTestCase.java | 25 ++++++
.../audit/logfile/LoggingAuditTrail.java | 7 +-
.../xpack/security/authc/ApiKeyService.java | 63 +++++++--------
.../xpack/security/authc/TokenService.java | 3 +-
.../security/authz/AuthorizationService.java | 4 +-
.../xpack/security/authz/RBACEngine.java | 4 +-
.../ingest/SetSecurityUserProcessor.java | 8 +-
.../xpack/security/SecurityContextTests.java | 21 ++---
.../logfile/LoggingAuditTrailFilterTests.java | 21 ++---
.../audit/logfile/LoggingAuditTrailTests.java | 7 +-
.../security/authc/ApiKeyServiceTests.java | 49 ++++++------
.../xpack/security/authz/RBACEngineTests.java | 12 +--
.../authz/store/CompositeRolesStoreTests.java | 22 +++---
.../ingest/SetSecurityUserProcessorTests.java | 28 +++----
.../rest-api-spec/test/api_key/10_basic.yml | 1 +
.../test/authenticate/10_basic.yml | 1 +
34 files changed, 396 insertions(+), 186 deletions(-)
create mode 100644 x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/ApiKeyServiceField.java
diff --git a/.idea/runConfigurations/Debug_Elasticsearch.xml b/.idea/runConfigurations/Debug_Elasticsearch.xml
index 84bb4dbb313c4..6b58e18d22266 100644
--- a/.idea/runConfigurations/Debug_Elasticsearch.xml
+++ b/.idea/runConfigurations/Debug_Elasticsearch.xml
@@ -12,4 +12,4 @@
-
+
\ No newline at end of file
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/AuthenticateResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/AuthenticateResponse.java
index c56cf8f7cd522..4ae09ee4dd9d9 100644
--- a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/AuthenticateResponse.java
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/AuthenticateResponse.java
@@ -44,19 +44,29 @@ public final class AuthenticateResponse implements ToXContentObject {
static final ParseField REALM_TYPE = new ParseField("type");
static final ParseField AUTHENTICATION_TYPE = new ParseField("authentication_type");
static final ParseField TOKEN = new ParseField("token");
+ static final ParseField API_KEY_INFO = new ParseField("api_key"); // authentication.api_key={"id":"abc123","name":"my-api-key"}
+ static final ParseField API_KEY_INFO_ID = new ParseField("id");
+ static final ParseField API_KEY_INFO_NAME = new ParseField("name");
@SuppressWarnings("unchecked")
private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>(
- "client_security_authenticate_response", true,
- a -> new AuthenticateResponse(
- new User((String) a[0], ((List) a[1]), (Map) a[2],
+ "client_security_authenticate_response", true,
+ a -> new AuthenticateResponse(
+ new User((String) a[0], ((List) a[1]), (Map) a[2],
(String) a[3], (String) a[4]), (Boolean) a[5], (RealmInfo) a[6], (RealmInfo) a[7], (String) a[8],
- (Map) a[9]));
+ (Map) a[9], (ApiKeyInfo) a[10]));
+
static {
final ConstructingObjectParser realmInfoParser = new ConstructingObjectParser<>("realm_info", true,
a -> new RealmInfo((String) a[0], (String) a[1]));
realmInfoParser.declareString(constructorArg(), REALM_NAME);
realmInfoParser.declareString(constructorArg(), REALM_TYPE);
+
+ final ConstructingObjectParser apiKeyInfoParser = new ConstructingObjectParser<>("api_key", true,
+ a -> new ApiKeyInfo((String) a[0], (String) a[1]));
+ apiKeyInfoParser.declareString(constructorArg(), API_KEY_INFO_ID);
+ apiKeyInfoParser.declareString(constructorArg(), API_KEY_INFO_NAME);
+
PARSER.declareString(constructorArg(), USERNAME);
PARSER.declareStringArray(constructorArg(), ROLES);
PARSER.
*/
public static AuthenticationResult terminate(String message, @Nullable Exception cause) {
- return new AuthenticationResult(Status.TERMINATE, null, message, cause, null);
+ return new AuthenticationResult(Status.TERMINATE, null, message, cause, null, null);
}
/**
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ManageOwnApiKeyClusterPrivilege.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ManageOwnApiKeyClusterPrivilege.java
index 5df9ed4e60031..ec05af02a8706 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ManageOwnApiKeyClusterPrivilege.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ManageOwnApiKeyClusterPrivilege.java
@@ -13,6 +13,7 @@
import org.elasticsearch.xpack.core.security.action.GetApiKeyRequest;
import org.elasticsearch.xpack.core.security.action.InvalidateApiKeyRequest;
import org.elasticsearch.xpack.core.security.action.apikey.QueryApiKeyRequest;
+import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.Authentication.AuthenticationType;
import org.elasticsearch.xpack.core.security.authz.permission.ClusterPermission;
@@ -26,7 +27,6 @@
public class ManageOwnApiKeyClusterPrivilege implements NamedClusterPrivilege {
public static final ManageOwnApiKeyClusterPrivilege INSTANCE = new ManageOwnApiKeyClusterPrivilege();
private static final String PRIVILEGE_NAME = "manage_own_api_key";
- public static final String API_KEY_ID_KEY = "_security_api_key_id";
private final ClusterPermission permission;
@@ -115,7 +115,7 @@ private boolean checkIfUserIsOwnerOfApiKeys(Authentication authentication, Strin
private boolean isCurrentAuthenticationUsingSameApiKeyIdFromRequest(Authentication authentication, String apiKeyId) {
if (AuthenticationType.API_KEY == authentication.getAuthenticationType()) {
// API key id from authentication must match the id from request
- final String authenticatedApiKeyId = (String) authentication.getMetadata().get(API_KEY_ID_KEY);
+ final String authenticatedApiKeyId = (String) authentication.getMetadata().get(ApiKeyServiceField.API_KEY_ID_KEY);
if (Strings.hasText(apiKeyId)) {
return apiKeyId.equals(authenticatedApiKeyId);
}
diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authc/AuthenticationTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authc/AuthenticationTests.java
index 1ad0a8a5e238b..6b73356e7e8b7 100644
--- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authc/AuthenticationTests.java
+++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authc/AuthenticationTests.java
@@ -23,7 +23,6 @@
import java.util.Set;
import java.util.stream.Collectors;
-import static org.elasticsearch.xpack.core.security.authz.privilege.ManageOwnApiKeyClusterPrivilege.API_KEY_ID_KEY;
import static org.hamcrest.Matchers.is;
public class AuthenticationTests extends ESTestCase {
@@ -187,7 +186,7 @@ public static Authentication randomApiKeyAuthentication(User user, String apiKey
null,
VersionUtils.randomVersionBetween(random(), Version.V_7_0_0, Version.CURRENT),
AuthenticationType.API_KEY,
- Map.of(API_KEY_ID_KEY, apiKeyId));
+ Map.of(ApiKeyServiceField.API_KEY_ID_KEY, apiKeyId));
}
private boolean realmIsSingleton(RealmRef realmRef) {
diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/ManageOwnApiKeyClusterPrivilegeTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/ManageOwnApiKeyClusterPrivilegeTests.java
index e5afe013e6b7c..3dbd61d22f789 100644
--- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/ManageOwnApiKeyClusterPrivilegeTests.java
+++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/ManageOwnApiKeyClusterPrivilegeTests.java
@@ -15,6 +15,7 @@
import org.elasticsearch.xpack.core.security.action.InvalidateApiKeyRequest;
import org.elasticsearch.xpack.core.security.action.apikey.QueryApiKeyAction;
import org.elasticsearch.xpack.core.security.action.apikey.QueryApiKeyRequest;
+import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.Authentication.AuthenticationType;
import org.elasticsearch.xpack.core.security.authz.permission.ClusterPermission;
@@ -33,8 +34,8 @@ public void testAuthenticationWithApiKeyAllowsAccessToApiKeyActionsWhenItIsOwner
ManageOwnApiKeyClusterPrivilege.INSTANCE.buildPermission(ClusterPermission.builder()).build();
final String apiKeyId = randomAlphaOfLengthBetween(4, 7);
- final Authentication authentication = createMockAuthentication("joe","_es_api_key",
- AuthenticationType.API_KEY, Map.of("_security_api_key_id", apiKeyId));
+ final Authentication authentication = createMockAuthentication("joe", "_es_api_key",
+ AuthenticationType.API_KEY, Map.of(ApiKeyServiceField.API_KEY_ID_KEY, apiKeyId));
final TransportRequest getApiKeyRequest = GetApiKeyRequest.usingApiKeyId(apiKeyId, randomBoolean());
final TransportRequest invalidateApiKeyRequest = InvalidateApiKeyRequest.usingApiKeyId(apiKeyId, randomBoolean());
@@ -48,8 +49,8 @@ public void testAuthenticationWithApiKeyDeniesAccessToApiKeyActionsWhenItIsNotOw
ManageOwnApiKeyClusterPrivilege.INSTANCE.buildPermission(ClusterPermission.builder()).build();
final String apiKeyId = randomAlphaOfLengthBetween(4, 7);
- final Authentication authentication = createMockAuthentication("joe","_es_api_key",
- AuthenticationType.API_KEY, Map.of("_security_api_key_id", randomAlphaOfLength(7)));
+ final Authentication authentication = createMockAuthentication("joe", "_es_api_key",
+ AuthenticationType.API_KEY, Map.of(ApiKeyServiceField.API_KEY_ID_KEY, randomAlphaOfLength(7)));
final TransportRequest getApiKeyRequest = GetApiKeyRequest.usingApiKeyId(apiKeyId, randomBoolean());
final TransportRequest invalidateApiKeyRequest = InvalidateApiKeyRequest.usingApiKeyId(apiKeyId, randomBoolean());
diff --git a/x-pack/plugin/security/qa/security-trial/src/javaRestTest/java/org/elasticsearch/xpack/security/apikey/ApiKeyRestIT.java b/x-pack/plugin/security/qa/security-trial/src/javaRestTest/java/org/elasticsearch/xpack/security/apikey/ApiKeyRestIT.java
index 3e6c185654ff2..29767e2f95a13 100644
--- a/x-pack/plugin/security/qa/security-trial/src/javaRestTest/java/org/elasticsearch/xpack/security/apikey/ApiKeyRestIT.java
+++ b/x-pack/plugin/security/qa/security-trial/src/javaRestTest/java/org/elasticsearch/xpack/security/apikey/ApiKeyRestIT.java
@@ -28,11 +28,18 @@
import java.util.Map;
import java.util.Set;
+import static org.hamcrest.Matchers.allOf;
+import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.everyItem;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
+import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.isA;
import static org.hamcrest.Matchers.lessThanOrEqualTo;
+import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
/**
@@ -63,6 +70,36 @@ public void cleanUp() throws IOException {
invalidateApiKeysForUser(END_USER);
}
+ public void testAuthenticateResponseApiKey() throws IOException {
+ final Map createApiKeyRequestBody = Map.of("name", "my-api-key-name", "metadata", Map.of("a", "b"));
+
+ final Request createApiKeyRequest = new Request("POST", "_security/api_key");
+ createApiKeyRequest.setJsonEntity(XContentTestUtils.convertToXContent(createApiKeyRequestBody, XContentType.JSON).utf8ToString());
+
+ final Response createApiKeyResponse = adminClient().performRequest(createApiKeyRequest);
+ final Map createApiKeyResponseAsMap = responseAsMap(createApiKeyResponse); // keys: id, name, api_key, encoded
+ final String encoded = (String) createApiKeyResponseAsMap.get("encoded"); // encoded=Base64(id:api_key)
+
+ final Request authenticateRequest = new Request("GET", "_security/_authenticate");
+ authenticateRequest.setOptions(authenticateRequest.getOptions().toBuilder().addHeader(
+ "Authorization", "ApiKey " + encoded));
+
+ final Response authenticateResponse = client().performRequest(authenticateRequest);
+ assertOK(authenticateResponse);
+ final Map authenticate = responseAsMap(authenticateResponse); // keys: username, roles, full_name, etc
+
+ // If authentication type is API_KEY, authentication.api_key={"id":"abc123","name":"my-api-key"}
+ // If authentication type is other, authentication.api_key not present.
+ assertThat(authenticate.get("api_key"), instanceOf(Map.class)); // implies hasKey()
+ final Map, ?> apiKey = (Map, ?>) authenticate.get("api_key"); // assert Map below
+ assertThat(apiKey.keySet(), allOf(
+ everyItem(instanceOf(String.class)), // assert apiKey Map,?> is safe to cast to Map
+ containsInAnyOrder("id", "name")) // assert apiKey Map exactly contains these keys (and no others)
+ );
+ assertThat(apiKey.get("id"), allOf(instanceOf(String.class), not(equalTo(""))));
+ assertThat(apiKey.get("name"), allOf(instanceOf(String.class), not(equalTo(""))));
+ }
+
public void testGrantApiKeyForOtherUserWithPassword() throws IOException {
Request request = new Request("POST", "_security/api_key/grant");
request.setOptions(RequestOptions.DEFAULT.toBuilder().addHeader("Authorization",
diff --git a/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/FileRealmAuthIT.java b/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/FileRealmAuthIT.java
index b610f9db2064f..fc6e32472adbf 100644
--- a/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/FileRealmAuthIT.java
+++ b/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/FileRealmAuthIT.java
@@ -9,11 +9,14 @@
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.common.settings.SecureString;
+import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken;
import java.io.IOException;
import java.util.Map;
+import static org.hamcrest.Matchers.is;
+
/**
* Integration Rest Test for testing authentication when all possible realms are configured
*/
@@ -33,6 +36,7 @@ public void testAuthenticationUsingFileRealm() throws IOException {
assertUsername(authenticate, USERNAME);
assertRealm(authenticate, "file", "file0");
assertRoles(authenticate, ROLE_NAME);
+ assertApiKeyInfo(authenticate, Authentication.AuthenticationType.REALM);
}
}
diff --git a/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/NativeRealmAuthIT.java b/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/NativeRealmAuthIT.java
index e849332bd791b..d0995bbed172b 100644
--- a/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/NativeRealmAuthIT.java
+++ b/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/NativeRealmAuthIT.java
@@ -9,6 +9,7 @@
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.common.settings.SecureString;
+import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken;
import org.junit.After;
import org.junit.Before;
@@ -18,6 +19,8 @@
import java.util.Map;
import java.util.Set;
+import static org.hamcrest.Matchers.is;
+
/**
* Integration Rest Test for testing authentication when all possible realms are configured
*/
@@ -48,6 +51,7 @@ public void testAuthenticationUsingNativeRealm() throws IOException {
assertUsername(authenticate, USERNAME);
assertRealm(authenticate, "native", "native1");
assertRoles(authenticate, ROLE_NAME);
+ assertApiKeyInfo(authenticate, Authentication.AuthenticationType.REALM);
}
}
diff --git a/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/PkiRealmAuthIT.java b/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/PkiRealmAuthIT.java
index c32dbbc07a8dc..bd416f56b327f 100644
--- a/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/PkiRealmAuthIT.java
+++ b/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/PkiRealmAuthIT.java
@@ -10,10 +10,13 @@
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.ThreadContext;
+import org.elasticsearch.xpack.core.security.authc.Authentication;
import java.io.IOException;
import java.util.Map;
+import static org.hamcrest.Matchers.is;
+
/**
* Integration Rest Test for testing authentication when all possible realms are configured
*/
@@ -39,6 +42,7 @@ public void testAuthenticationUsingPkiRealm() throws IOException {
assertUsername(authenticate, USERNAME);
assertRealm(authenticate, "pki", "pki4");
assertRoles(authenticate, new String[0]);
+ assertApiKeyInfo(authenticate, Authentication.AuthenticationType.REALM);
}
}
diff --git a/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/ReservedRealmAuthIT.java b/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/ReservedRealmAuthIT.java
index 7c99b7c31eba6..1f2d723858372 100644
--- a/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/ReservedRealmAuthIT.java
+++ b/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/ReservedRealmAuthIT.java
@@ -9,12 +9,15 @@
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.common.settings.SecureString;
+import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken;
import org.junit.Before;
import java.io.IOException;
import java.util.Map;
+import static org.hamcrest.Matchers.is;
+
/**
* Integration Rest Test for testing authentication when all possible realms are configured
*/
@@ -39,6 +42,7 @@ public void testAuthenticationUsingReservedRealm() throws IOException {
assertUsername(authenticate, USERNAME);
assertRealm(authenticate, "reserved", "reserved");
assertRoles(authenticate, ROLE_NAME);
+ assertApiKeyInfo(authenticate, Authentication.AuthenticationType.REALM);
}
}
diff --git a/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/SecurityRealmSmokeTestCase.java b/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/SecurityRealmSmokeTestCase.java
index cf3e2ed576a6f..3cd3dbb106998 100644
--- a/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/SecurityRealmSmokeTestCase.java
+++ b/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/SecurityRealmSmokeTestCase.java
@@ -25,6 +25,8 @@
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.test.rest.ESRestTestCase;
+import org.elasticsearch.xpack.core.security.authc.Authentication.AuthenticationType;
+import org.hamcrest.core.Every;
import org.junit.BeforeClass;
import java.io.FileNotFoundException;
@@ -35,10 +37,16 @@
import java.util.List;
import java.util.Map;
+import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.arrayContainingInAnyOrder;
+import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.everyItem;
import static org.hamcrest.Matchers.hasEntry;
+import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.Matchers.instanceOf;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.not;
public abstract class SecurityRealmSmokeTestCase extends ESRestTestCase {
@@ -105,6 +113,23 @@ protected void assertRoles(Map authenticateResponse, String... r
);
}
+ protected void assertApiKeyInfo(Map authenticateResponse, AuthenticationType type) {
+ // If authentication type is API_KEY, authentication.api_key={"id":"abc123","name":"my-api-key"}
+ // If authentication type is other, authentication.api_key not present.
+ if (AuthenticationType.API_KEY.equals(type)) {
+ assertThat(authenticateResponse.get("api_key"), instanceOf(Map.class)); // implies hasKey()
+ final Map, ?> apiKey = (Map, ?>) authenticateResponse.get("api_key"); // assert Map below
+ assertThat(apiKey.keySet(), allOf(
+ everyItem(instanceOf(String.class)), // assert apiKey Map,?> is safe to cast to Map
+ containsInAnyOrder("id", "name")) // assert apiKey Map exactly contains these keys (and no others)
+ );
+ assertThat(apiKey.get("id"), allOf(instanceOf(String.class), not(equalTo(""))));
+ assertThat(apiKey.get("name"), allOf(instanceOf(String.class), not(equalTo(""))));
+ } else {
+ assertThat(authenticateResponse, not(hasKey("api_key")));
+ }
+ }
+
protected void createUser(String username, SecureString password, List roles) throws IOException {
final RestHighLevelClient client = getHighLevelAdminClient();
client.security().putUser(
diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrail.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrail.java
index 74f7b08eb7424..239a9eeedf197 100644
--- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrail.java
+++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrail.java
@@ -71,6 +71,7 @@
import org.elasticsearch.xpack.core.security.action.user.PutUserRequest;
import org.elasticsearch.xpack.core.security.action.user.SetEnabledAction;
import org.elasticsearch.xpack.core.security.action.user.SetEnabledRequest;
+import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.AuthenticationToken;
import org.elasticsearch.xpack.core.security.authc.service.ServiceAccountSettings;
@@ -1297,12 +1298,12 @@ LogEntryBuilder withAuthentication(Authentication authentication) {
logEntry.with(PRINCIPAL_FIELD_NAME, authentication.getUser().principal());
logEntry.with(AUTHENTICATION_TYPE_FIELD_NAME, authentication.getAuthenticationType().toString());
if (Authentication.AuthenticationType.API_KEY == authentication.getAuthenticationType()) {
- logEntry.with(API_KEY_ID_FIELD_NAME, (String) authentication.getMetadata().get(ApiKeyService.API_KEY_ID_KEY));
- String apiKeyName = (String) authentication.getMetadata().get(ApiKeyService.API_KEY_NAME_KEY);
+ logEntry.with(API_KEY_ID_FIELD_NAME, (String) authentication.getMetadata().get(ApiKeyServiceField.API_KEY_ID_KEY));
+ String apiKeyName = (String) authentication.getMetadata().get(ApiKeyServiceField.API_KEY_NAME_KEY);
if (apiKeyName != null) {
logEntry.with(API_KEY_NAME_FIELD_NAME, apiKeyName);
}
- String creatorRealmName = (String) authentication.getMetadata().get(ApiKeyService.API_KEY_CREATOR_REALM_NAME);
+ String creatorRealmName = (String) authentication.getMetadata().get(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME);
if (creatorRealmName != null) {
// can be null for API keys created before version 7.7
logEntry.with(PRINCIPAL_REALM_FIELD_NAME, creatorRealmName);
diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/ApiKeyService.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/ApiKeyService.java
index d0c8637bd1caf..c89e8a360b533 100644
--- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/ApiKeyService.java
+++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/ApiKeyService.java
@@ -85,6 +85,7 @@
import org.elasticsearch.xpack.core.security.action.GetApiKeyResponse;
import org.elasticsearch.xpack.core.security.action.InvalidateApiKeyResponse;
import org.elasticsearch.xpack.core.security.action.apikey.QueryApiKeyResponse;
+import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.Authentication.RealmRef;
import org.elasticsearch.xpack.core.security.authc.AuthenticationResult;
@@ -135,8 +136,6 @@
import static org.elasticsearch.xpack.core.ClientHelper.executeAsyncWithOrigin;
import static org.elasticsearch.xpack.core.security.authc.Authentication.AuthenticationType;
import static org.elasticsearch.xpack.core.security.authc.Authentication.VERSION_API_KEY_ROLES_AS_BYTES;
-import static org.elasticsearch.xpack.core.security.authc.AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY;
-import static org.elasticsearch.xpack.core.security.authc.AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY;
import static org.elasticsearch.xpack.core.security.index.RestrictedIndicesNames.SECURITY_MAIN_ALIAS;
import static org.elasticsearch.xpack.security.Security.SECURITY_CRYPTO_THREAD_POOL_NAME;
@@ -144,13 +143,6 @@ public class ApiKeyService {
private static final Logger logger = LogManager.getLogger(ApiKeyService.class);
private static final DeprecationLogger deprecationLogger = DeprecationLogger.getLogger(ApiKeyService.class);
- public static final String API_KEY_ID_KEY = "_security_api_key_id";
- public static final String API_KEY_NAME_KEY = "_security_api_key_name";
- public static final String API_KEY_METADATA_KEY = "_security_api_key_metadata";
- public static final String API_KEY_REALM_NAME = "_es_api_key";
- public static final String API_KEY_REALM_TYPE = "_es_api_key";
- public static final String API_KEY_CREATOR_REALM_NAME = "_security_api_key_creator_realm_name";
- public static final String API_KEY_CREATOR_REALM_TYPE = "_security_api_key_creator_realm_type";
public static final Setting PASSWORD_HASHING_ALGORITHM = new Setting<>(
"xpack.security.authc.api_key.hashing.algorithm", "pbkdf2", Function.identity(), v -> {
@@ -414,9 +406,10 @@ public Authentication createApiKeyAuthentication(AuthenticationResult authResult
throw new IllegalArgumentException("API Key authn result must be successful");
}
final User user = authResult.getUser();
- final RealmRef authenticatedBy = new RealmRef(ApiKeyService.API_KEY_REALM_NAME, ApiKeyService.API_KEY_REALM_TYPE, nodeName);
+ final RealmRef authenticatedBy = new RealmRef(ApiKeyServiceField.API_KEY_REALM_NAME, ApiKeyServiceField.API_KEY_REALM_TYPE,
+ nodeName);
return new Authentication(user, authenticatedBy, null, Version.CURRENT, Authentication.AuthenticationType.API_KEY,
- authResult.getMetadata());
+ authResult.getMetadata());
}
void loadApiKeyAndValidateCredentials(ThreadContext ctx, ApiKeyCredentials credentials,
@@ -495,11 +488,11 @@ public void getRoleForApiKey(Authentication authentication, ActionListener metadata = authentication.getMetadata();
- final String apiKeyId = (String) metadata.get(API_KEY_ID_KEY);
- @SuppressWarnings("unchecked")
- final Map roleDescriptors = (Map) metadata.get(API_KEY_ROLE_DESCRIPTORS_KEY);
- @SuppressWarnings("unchecked")
- final Map authnRoleDescriptors = (Map) metadata.get(API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY);
+ final String apiKeyId = (String) metadata.get(ApiKeyServiceField.API_KEY_ID_KEY);
+ @SuppressWarnings("unchecked") final Map roleDescriptors =
+ (Map) metadata.get(ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY);
+ @SuppressWarnings("unchecked") final Map authnRoleDescriptors =
+ (Map) metadata.get(ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY);
if (roleDescriptors == null && authnRoleDescriptors == null) {
listener.onFailure(new ElasticsearchSecurityException("no role descriptors found for API key"));
@@ -521,15 +514,15 @@ public Tuple getApiKeyIdAndRoleBytes(Authentication auth
.onOrAfter(VERSION_API_KEY_ROLES_AS_BYTES) : "This method only applies to authentication objects created on or after v7.9.0";
final Map metadata = authentication.getMetadata();
- final BytesReference bytesReference =
- (BytesReference) metadata.get(limitedBy ? API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY : API_KEY_ROLE_DESCRIPTORS_KEY);
+ final BytesReference bytesReference = (BytesReference) metadata.get(limitedBy
+ ? ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY : ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY);
if (limitedBy && bytesReference.length() == 2 && "{}".equals(bytesReference.utf8ToString())) {
- if (ServiceAccountSettings.REALM_NAME.equals(metadata.get(API_KEY_CREATOR_REALM_NAME))
+ if (ServiceAccountSettings.REALM_NAME.equals(metadata.get(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME))
&& "elastic/fleet-server".equals(authentication.getUser().principal())) {
- return new Tuple<>((String) metadata.get(API_KEY_ID_KEY), FLEET_SERVER_ROLE_DESCRIPTOR_BYTES_V_7_14);
+ return new Tuple<>((String) metadata.get(ApiKeyServiceField.API_KEY_ID_KEY), FLEET_SERVER_ROLE_DESCRIPTOR_BYTES_V_7_14);
}
}
- return new Tuple<>((String) metadata.get(API_KEY_ID_KEY), bytesReference);
+ return new Tuple<>((String) metadata.get(ApiKeyServiceField.API_KEY_ID_KEY), bytesReference);
}
public static class ApiKeyRoleDescriptors {
@@ -718,14 +711,14 @@ void validateApiKeyExpiration(ApiKeyDoc apiKeyDoc, ApiKeyCredentials credentials
Map metadata = (Map) apiKeyDoc.creator.get("metadata");
final User apiKeyUser = new User(principal, Strings.EMPTY_ARRAY, fullName, email, metadata, true);
final Map authResultMetadata = new HashMap<>();
- authResultMetadata.put(API_KEY_CREATOR_REALM_NAME, apiKeyDoc.creator.get("realm"));
- authResultMetadata.put(API_KEY_CREATOR_REALM_TYPE, apiKeyDoc.creator.get("realm_type"));
- authResultMetadata.put(API_KEY_ROLE_DESCRIPTORS_KEY, apiKeyDoc.roleDescriptorsBytes);
- authResultMetadata.put(API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, apiKeyDoc.limitedByRoleDescriptorsBytes);
- authResultMetadata.put(API_KEY_ID_KEY, credentials.getId());
- authResultMetadata.put(API_KEY_NAME_KEY, apiKeyDoc.name);
+ authResultMetadata.put(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME, apiKeyDoc.creator.get("realm"));
+ authResultMetadata.put(ApiKeyServiceField.API_KEY_CREATOR_REALM_TYPE, apiKeyDoc.creator.get("realm_type"));
+ authResultMetadata.put(ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY, apiKeyDoc.roleDescriptorsBytes);
+ authResultMetadata.put(ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, apiKeyDoc.limitedByRoleDescriptorsBytes);
+ authResultMetadata.put(ApiKeyServiceField.API_KEY_ID_KEY, credentials.getId());
+ authResultMetadata.put(ApiKeyServiceField.API_KEY_NAME_KEY, apiKeyDoc.name);
if (apiKeyDoc.metadataFlattened != null) {
- authResultMetadata.put(API_KEY_METADATA_KEY, apiKeyDoc.metadataFlattened);
+ authResultMetadata.put(ApiKeyServiceField.API_KEY_METADATA_KEY, apiKeyDoc.metadataFlattened);
}
listener.onResponse(AuthenticationResult.success(apiKeyUser, authResultMetadata));
} else {
@@ -770,7 +763,7 @@ static ApiKeyCredentials getCredentialsFromHeader(ThreadContext threadContext) {
public static boolean isApiKeyAuthentication(Authentication authentication) {
final Authentication.AuthenticationType authType = authentication.getAuthenticationType();
if (Authentication.AuthenticationType.API_KEY == authType) {
- assert API_KEY_REALM_TYPE.equals(authentication.getAuthenticatedBy().getType())
+ assert ApiKeyServiceField.API_KEY_REALM_TYPE.equals(authentication.getAuthenticatedBy().getType())
: "API key authentication must have API key realm type";
return true;
} else {
@@ -1221,14 +1214,15 @@ AtomicLong getLastEvictionCheckedAt() {
/**
* Returns realm name for the authenticated user.
- * If the user is authenticated by realm type {@value API_KEY_REALM_TYPE}
+ * If the user is authenticated by realm type {@value ApiKeyServiceField#API_KEY_REALM_TYPE}
* then it will return the realm name of user who created this API key.
+ *
* @param authentication {@link Authentication}
* @return realm name
*/
public static String getCreatorRealmName(final Authentication authentication) {
if (AuthenticationType.API_KEY == authentication.getAuthenticationType()) {
- return (String) authentication.getMetadata().get(API_KEY_CREATOR_REALM_NAME);
+ return (String) authentication.getMetadata().get(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME);
} else {
return authentication.getSourceRealm().getName();
}
@@ -1236,14 +1230,15 @@ public static String getCreatorRealmName(final Authentication authentication) {
/**
* Returns realm type for the authenticated user.
- * If the user is authenticated by realm type {@value API_KEY_REALM_TYPE}
+ * If the user is authenticated by realm type {@value ApiKeyServiceField#API_KEY_REALM_TYPE}
* then it will return the realm name of user who created this API key.
+ *
* @param authentication {@link Authentication}
* @return realm type
*/
public static String getCreatorRealmType(final Authentication authentication) {
if (AuthenticationType.API_KEY == authentication.getAuthenticationType()) {
- return (String) authentication.getMetadata().get(API_KEY_CREATOR_REALM_TYPE);
+ return (String) authentication.getMetadata().get(ApiKeyServiceField.API_KEY_CREATOR_REALM_TYPE);
} else {
return authentication.getSourceRealm().getType();
}
@@ -1260,7 +1255,7 @@ public static Map getApiKeyMetadata(Authentication authenticatio
throw new IllegalArgumentException("authentication type must be [api_key], got ["
+ authentication.getAuthenticationType().name().toLowerCase(Locale.ROOT) + "]");
}
- final Object apiKeyMetadata = authentication.getMetadata().get(ApiKeyService.API_KEY_METADATA_KEY);
+ final Object apiKeyMetadata = authentication.getMetadata().get(ApiKeyServiceField.API_KEY_METADATA_KEY);
if (apiKeyMetadata != null) {
final Tuple> tuple =
XContentHelper.convertToMap((BytesReference) apiKeyMetadata, false, XContentType.JSON);
diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/TokenService.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/TokenService.java
index 254eb4024615e..f2bbe1a05b9a2 100644
--- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/TokenService.java
+++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/TokenService.java
@@ -325,7 +325,8 @@ private void createOAuth2Tokens(String accessToken, String refreshToken, Version
new IllegalArgumentException("originating client authentication must be provided")));
} else {
final Authentication tokenAuth = new Authentication(authentication.getUser(), authentication.getAuthenticatedBy(),
- authentication.getLookedUpBy(), tokenVersion, AuthenticationType.TOKEN, authentication.getMetadata());
+ authentication.getLookedUpBy(), tokenVersion, AuthenticationType.TOKEN,
+ authentication.getMetadata());
final String storedAccessToken;
final String storedRefreshToken;
if (tokenVersion.onOrAfter(VERSION_HASHED_TOKENS)) {
diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/AuthorizationService.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/AuthorizationService.java
index 7dad6ee9a0d07..9a5ac8528ecc1 100644
--- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/AuthorizationService.java
+++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/AuthorizationService.java
@@ -50,6 +50,7 @@
import org.elasticsearch.xpack.core.security.action.user.GetUserPrivilegesResponse;
import org.elasticsearch.xpack.core.security.action.user.HasPrivilegesRequest;
import org.elasticsearch.xpack.core.security.action.user.HasPrivilegesResponse;
+import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.Authentication.AuthenticationType;
import org.elasticsearch.xpack.core.security.authc.AuthenticationFailureHandler;
@@ -75,7 +76,6 @@
import org.elasticsearch.xpack.security.audit.AuditTrail;
import org.elasticsearch.xpack.security.audit.AuditTrailService;
import org.elasticsearch.xpack.security.audit.AuditUtil;
-import org.elasticsearch.xpack.security.authc.ApiKeyService;
import org.elasticsearch.xpack.security.authz.interceptor.RequestInterceptor;
import org.elasticsearch.xpack.security.authz.store.CompositeRolesStore;
import org.elasticsearch.xpack.security.operator.OperatorPrivileges.OperatorPrivilegesService;
@@ -718,7 +718,7 @@ private ElasticsearchSecurityException denialException(Authentication authentica
}
// check for authentication by API key
if (AuthenticationType.API_KEY == authentication.getAuthenticationType()) {
- final String apiKeyId = (String) authentication.getMetadata().get(ApiKeyService.API_KEY_ID_KEY);
+ final String apiKeyId = (String) authentication.getMetadata().get(ApiKeyServiceField.API_KEY_ID_KEY);
assert apiKeyId != null : "api key id must be present in the metadata";
userText = "API key id [" + apiKeyId + "] of " + userText;
} else if (false == authentication.isServiceAccount()) {
diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/RBACEngine.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/RBACEngine.java
index f235cdee019e0..3f17d160b8a2a 100644
--- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/RBACEngine.java
+++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/RBACEngine.java
@@ -52,6 +52,7 @@
import org.elasticsearch.xpack.core.security.action.user.HasPrivilegesRequest;
import org.elasticsearch.xpack.core.security.action.user.HasPrivilegesResponse;
import org.elasticsearch.xpack.core.security.action.user.UserRequest;
+import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.Authentication.AuthenticationType;
import org.elasticsearch.xpack.core.security.authc.esnative.NativeRealmSettings;
@@ -75,7 +76,6 @@
import org.elasticsearch.xpack.core.security.support.StringMatcher;
import org.elasticsearch.xpack.core.security.user.User;
import org.elasticsearch.xpack.core.sql.SqlAsyncActionNames;
-import org.elasticsearch.xpack.security.authc.ApiKeyService;
import org.elasticsearch.xpack.security.authc.esnative.ReservedRealm;
import org.elasticsearch.xpack.security.authz.store.CompositeRolesStore;
@@ -190,7 +190,7 @@ boolean checkSameUserPermissions(String action, TransportRequest request, Authen
if (AuthenticationType.API_KEY == authentication.getAuthenticationType()) {
assert authentication.getLookedUpBy() == null : "runAs not supported for api key authentication";
// if authenticated by API key then the request must also contain same API key id
- String authenticatedApiKeyId = (String) authentication.getMetadata().get(ApiKeyService.API_KEY_ID_KEY);
+ String authenticatedApiKeyId = (String) authentication.getMetadata().get(ApiKeyServiceField.API_KEY_ID_KEY);
if (Strings.hasText(getApiKeyRequest.getApiKeyId())) {
return getApiKeyRequest.getApiKeyId().equals(authenticatedApiKeyId);
} else {
diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessor.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessor.java
index 4cb5d154df777..dccc58cc5e690 100644
--- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessor.java
+++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessor.java
@@ -14,6 +14,7 @@
import org.elasticsearch.ingest.Processor;
import org.elasticsearch.xpack.core.XPackSettings;
import org.elasticsearch.xpack.core.security.SecurityContext;
+import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.user.User;
import org.elasticsearch.xpack.security.authc.ApiKeyService;
@@ -122,14 +123,13 @@ public IngestDocument execute(IngestDocument ingestDocument) throws Exception {
if (Authentication.AuthenticationType.API_KEY == authentication.getAuthenticationType()) {
final String apiKey = "api_key";
final Object existingApiKeyField = userObject.get(apiKey);
- @SuppressWarnings("unchecked")
- final Map apiKeyField =
+ @SuppressWarnings("unchecked") final Map apiKeyField =
existingApiKeyField instanceof Map ? (Map) existingApiKeyField : new HashMap<>();
- Object apiKeyName = authentication.getMetadata().get(ApiKeyService.API_KEY_NAME_KEY);
+ Object apiKeyName = authentication.getMetadata().get(ApiKeyServiceField.API_KEY_NAME_KEY);
if (apiKeyName != null) {
apiKeyField.put("name", apiKeyName);
}
- Object apiKeyId = authentication.getMetadata().get(ApiKeyService.API_KEY_ID_KEY);
+ Object apiKeyId = authentication.getMetadata().get(ApiKeyServiceField.API_KEY_ID_KEY);
if (apiKeyId != null) {
apiKeyField.put("id", apiKeyId);
}
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityContextTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityContextTests.java
index 4be9bb184f0e4..e624665b3a2a8 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityContextTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityContextTests.java
@@ -15,6 +15,7 @@
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.VersionUtils;
import org.elasticsearch.xpack.core.security.SecurityContext;
+import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.Authentication.AuthenticationType;
import org.elasticsearch.xpack.core.security.authc.Authentication.RealmRef;
@@ -31,8 +32,6 @@
import java.util.concurrent.atomic.AtomicReference;
import static org.elasticsearch.xpack.core.security.authc.Authentication.VERSION_API_KEY_ROLES_AS_BYTES;
-import static org.elasticsearch.xpack.core.security.authc.AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY;
-import static org.elasticsearch.xpack.core.security.authc.AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY;
import static org.hamcrest.Matchers.instanceOf;
public class SecurityContextTests extends ESTestCase {
@@ -143,8 +142,8 @@ public void testExecuteAfterRewritingAuthenticationWillConditionallyRewriteNewAp
User user = new User("test", null, new User("authUser"));
RealmRef authBy = new RealmRef("_es_api_key", "_es_api_key", "node1");
final Map metadata = Map.of(
- API_KEY_ROLE_DESCRIPTORS_KEY, new BytesArray("{\"a role\": {\"cluster\": [\"all\"]}}"),
- API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, new BytesArray("{\"limitedBy role\": {\"cluster\": [\"all\"]}}")
+ ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY, new BytesArray("{\"a role\": {\"cluster\": [\"all\"]}}"),
+ ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, new BytesArray("{\"limitedBy role\": {\"cluster\": [\"all\"]}}")
);
final Authentication original = new Authentication(user, authBy, authBy, Version.V_8_0_0,
AuthenticationType.API_KEY, metadata);
@@ -154,9 +153,9 @@ API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, new BytesArray("{\"limitedBy role\": {\"cl
securityContext.executeAfterRewritingAuthentication(originalCtx -> {
Authentication authentication = securityContext.getAuthentication();
assertEquals(Map.of("a role", Map.of("cluster", List.of("all"))),
- authentication.getMetadata().get(API_KEY_ROLE_DESCRIPTORS_KEY));
+ authentication.getMetadata().get(ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY));
assertEquals(Map.of("limitedBy role", Map.of("cluster", List.of("all"))),
- authentication.getMetadata().get(API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY));
+ authentication.getMetadata().get(ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY));
}, Version.V_7_8_0);
// If target is new node, no need to rewrite the new style API key metadata
@@ -170,8 +169,8 @@ public void testExecuteAfterRewritingAuthenticationWillConditionallyRewriteOldAp
User user = new User("test", null, new User("authUser"));
RealmRef authBy = new RealmRef("_es_api_key", "_es_api_key", "node1");
final Map metadata = Map.of(
- API_KEY_ROLE_DESCRIPTORS_KEY, Map.of("a role", Map.of("cluster", List.of("all"))),
- API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, Map.of("limitedBy role", Map.of("cluster", List.of("all")))
+ ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY, Map.of("a role", Map.of("cluster", List.of("all"))),
+ ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, Map.of("limitedBy role", Map.of("cluster", List.of("all")))
);
final Authentication original = new Authentication(user, authBy, authBy, Version.V_7_8_0, AuthenticationType.API_KEY, metadata);
original.writeToContext(threadContext);
@@ -186,9 +185,11 @@ public void testExecuteAfterRewritingAuthenticationWillConditionallyRewriteOldAp
securityContext.executeAfterRewritingAuthentication(originalCtx -> {
Authentication authentication = securityContext.getAuthentication();
assertEquals("{\"a role\":{\"cluster\":[\"all\"]}}",
- ((BytesReference)authentication.getMetadata().get(API_KEY_ROLE_DESCRIPTORS_KEY)).utf8ToString());
+ ((BytesReference) authentication.getMetadata()
+ .get(ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY)).utf8ToString());
assertEquals("{\"limitedBy role\":{\"cluster\":[\"all\"]}}",
- ((BytesReference)authentication.getMetadata().get(API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY)).utf8ToString());
+ ((BytesReference) authentication.getMetadata()
+ .get(ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY)).utf8ToString());
}, VersionUtils.randomVersionBetween(random(), VERSION_API_KEY_ROLES_AS_BYTES, Version.CURRENT));
}
}
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailFilterTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailFilterTests.java
index d58570044f65e..3ea712c3e7f84 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailFilterTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailFilterTests.java
@@ -27,6 +27,7 @@
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportRequest;
import org.elasticsearch.xpack.core.security.audit.logfile.CapturingLogger;
+import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.Authentication.RealmRef;
import org.elasticsearch.xpack.core.security.authc.AuthenticationToken;
@@ -932,7 +933,7 @@ public void testRealmsFilter() throws Exception {
createApiKeyAuthentication(apiKeyService, createAuthentication(user, filteredRealm));
auditTrail.accessGranted(randomAlphaOfLength(8), authentication, "_action", request, authzInfo(new String[]{"role1"}));
if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY &&
- false == authentication.getMetadata().containsKey(ApiKeyService.API_KEY_CREATOR_REALM_NAME)) {
+ false == authentication.getMetadata().containsKey(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME)) {
if (filterMissingRealm) {
assertThat("AccessGranted message: not filtered out by the missing realm filter", logOutput.size(), is(0));
} else {
@@ -948,7 +949,7 @@ public void testRealmsFilter() throws Exception {
createApiKeyAuthentication(apiKeyService, createAuthentication(user, unfilteredRealm));
auditTrail.accessGranted(randomAlphaOfLength(8), authentication, "_action", request, authzInfo(new String[]{"role1"}));
if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY &&
- false == authentication.getMetadata().containsKey(ApiKeyService.API_KEY_CREATOR_REALM_NAME)) {
+ false == authentication.getMetadata().containsKey(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME)) {
if (filterMissingRealm) {
assertThat("AccessGranted message: not filtered out by the missing realm filter", logOutput.size(), is(0));
} else {
@@ -976,7 +977,7 @@ public void testRealmsFilter() throws Exception {
createApiKeyAuthentication(apiKeyService, createAuthentication(user, filteredRealm));
auditTrail.accessGranted(randomAlphaOfLength(8), authentication, "internal:_action", request, authzInfo(new String[]{"role1"}));
if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY &&
- false == authentication.getMetadata().containsKey(ApiKeyService.API_KEY_CREATOR_REALM_NAME)) {
+ false == authentication.getMetadata().containsKey(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME)) {
if (filterMissingRealm) {
assertThat("AccessGranted internal message: not filtered out by the missing realm filter", logOutput.size(), is(0));
} else {
@@ -992,7 +993,7 @@ public void testRealmsFilter() throws Exception {
createApiKeyAuthentication(apiKeyService, createAuthentication(user, unfilteredRealm));
auditTrail.accessGranted(randomAlphaOfLength(8), authentication, "internal:_action", request, authzInfo(new String[] { "role1" }));
if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY &&
- false == authentication.getMetadata().containsKey(ApiKeyService.API_KEY_CREATOR_REALM_NAME)) {
+ false == authentication.getMetadata().containsKey(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME)) {
if (filterMissingRealm) {
assertThat("AccessGranted internal message: not filtered out by the missing realm filter", logOutput.size(), is(0));
} else {
@@ -1009,7 +1010,7 @@ public void testRealmsFilter() throws Exception {
createApiKeyAuthentication(apiKeyService, createAuthentication(user, filteredRealm));
auditTrail.accessDenied(randomAlphaOfLength(8), authentication, "_action", request, authzInfo(new String[]{"role1"}));
if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY &&
- false == authentication.getMetadata().containsKey(ApiKeyService.API_KEY_CREATOR_REALM_NAME)) {
+ false == authentication.getMetadata().containsKey(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME)) {
if (filterMissingRealm) {
assertThat("AccessDenied message: not filtered out by the missing realm filter", logOutput.size(), is(0));
} else {
@@ -1025,7 +1026,7 @@ public void testRealmsFilter() throws Exception {
createApiKeyAuthentication(apiKeyService, createAuthentication(user, unfilteredRealm));
auditTrail.accessDenied(randomAlphaOfLength(8), authentication, "_action", request, authzInfo(new String[]{"role1"}));
if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY &&
- false == authentication.getMetadata().containsKey(ApiKeyService.API_KEY_CREATOR_REALM_NAME)) {
+ false == authentication.getMetadata().containsKey(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME)) {
if (filterMissingRealm) {
assertThat("AccessDenied message: not filtered out by the missing realm filter", logOutput.size(), is(0));
} else {
@@ -1053,7 +1054,7 @@ public void testRealmsFilter() throws Exception {
createApiKeyAuthentication(apiKeyService, createAuthentication(user, filteredRealm));
auditTrail.accessDenied(randomAlphaOfLength(8), authentication, "internal:_action", request, authzInfo(new String[]{"role1"}));
if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY &&
- false == authentication.getMetadata().containsKey(ApiKeyService.API_KEY_CREATOR_REALM_NAME)) {
+ false == authentication.getMetadata().containsKey(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME)) {
if (filterMissingRealm) {
assertThat("AccessDenied internal message: not filtered out by the missing realm filter", logOutput.size(), is(0));
} else {
@@ -1070,7 +1071,7 @@ public void testRealmsFilter() throws Exception {
auditTrail.accessDenied(randomAlphaOfLength(8), authentication, "internal:_action",
request, authzInfo(new String[]{"role1"}));
if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY &&
- false == authentication.getMetadata().containsKey(ApiKeyService.API_KEY_CREATOR_REALM_NAME)) {
+ false == authentication.getMetadata().containsKey(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME)) {
if (filterMissingRealm) {
assertThat("AccessDenied internal message: not filtered out by the missing realm filter", logOutput.size(), is(0));
} else {
@@ -1105,7 +1106,7 @@ public void testRealmsFilter() throws Exception {
createApiKeyAuthentication(apiKeyService, createAuthentication(user, filteredRealm));
auditTrail.tamperedRequest(randomAlphaOfLength(8), authentication, "_action", request);
if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY &&
- false == authentication.getMetadata().containsKey(ApiKeyService.API_KEY_CREATOR_REALM_NAME)) {
+ false == authentication.getMetadata().containsKey(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME)) {
if (filterMissingRealm) {
assertThat("Tampered message: not filtered out by the missing realm filter", logOutput.size(), is(0));
} else {
@@ -1121,7 +1122,7 @@ public void testRealmsFilter() throws Exception {
createApiKeyAuthentication(apiKeyService, createAuthentication(user, unfilteredRealm));
auditTrail.tamperedRequest(randomAlphaOfLength(8), authentication, "_action", request);
if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY &&
- false == authentication.getMetadata().containsKey(ApiKeyService.API_KEY_CREATOR_REALM_NAME)) {
+ false == authentication.getMetadata().containsKey(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME)) {
if (filterMissingRealm) {
assertThat("Tampered message: not filtered out by the missing realm filter", logOutput.size(), is(0));
} else {
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailTests.java
index 7a9273b33ab34..80f341399c6c2 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailTests.java
@@ -76,6 +76,7 @@
import org.elasticsearch.xpack.core.security.action.user.SetEnabledAction;
import org.elasticsearch.xpack.core.security.action.user.SetEnabledRequest;
import org.elasticsearch.xpack.core.security.audit.logfile.CapturingLogger;
+import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.Authentication.AuthenticationType;
import org.elasticsearch.xpack.core.security.authc.Authentication.RealmRef;
@@ -2415,12 +2416,12 @@ private static void authentication(Authentication authentication, MapBuilder();
@@ -463,10 +462,10 @@ public void testValidateApiKey() throws Exception {
assertThat(result.getUser().email(), is("test@user.com"));
assertThat(result.getUser().roles(), is(emptyArray()));
assertThat(result.getUser().metadata(), is(Collections.emptyMap()));
- assertThat(result.getMetadata().get(API_KEY_ROLE_DESCRIPTORS_KEY), equalTo(apiKeyDoc.roleDescriptorsBytes));
- assertThat(result.getMetadata().get(API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY),
+ assertThat(result.getMetadata().get(ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY), equalTo(apiKeyDoc.roleDescriptorsBytes));
+ assertThat(result.getMetadata().get(ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY),
equalTo(apiKeyDoc.limitedByRoleDescriptorsBytes));
- assertThat(result.getMetadata().get(ApiKeyService.API_KEY_CREATOR_REALM_NAME), is("realm1"));
+ assertThat(result.getMetadata().get(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME), is("realm1"));
apiKeyDoc = buildApiKeyDoc(hash, Clock.systemUTC().instant().minus(1L, ChronoUnit.HOURS).toEpochMilli(), false);
future = new PlainActionFuture<>();
@@ -492,15 +491,15 @@ public void testGetRolesForApiKeyNotInContext() throws Exception {
try (XContentBuilder builder = JsonXContent.contentBuilder()) {
superUserRdMap = XContentHelper.convertToMap(XContentType.JSON.xContent(),
BytesReference.bytes(SUPERUSER_ROLE_DESCRIPTOR
- .toXContent(builder, ToXContent.EMPTY_PARAMS, true))
+ .toXContent(builder, ToXContent.EMPTY_PARAMS, true))
.streamInput(),
false);
}
Map authMetadata = new HashMap<>();
- authMetadata.put(ApiKeyService.API_KEY_ID_KEY, randomAlphaOfLength(12));
- authMetadata.put(API_KEY_ROLE_DESCRIPTORS_KEY,
+ authMetadata.put(ApiKeyServiceField.API_KEY_ID_KEY, randomAlphaOfLength(12));
+ authMetadata.put(ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY,
Collections.singletonMap(SUPERUSER_ROLE_DESCRIPTOR.getName(), superUserRdMap));
- authMetadata.put(API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
+ authMetadata.put(ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
Collections.singletonMap(SUPERUSER_ROLE_DESCRIPTOR.getName(), superUserRdMap));
final Authentication authentication = new Authentication(new User("joe"), new RealmRef("apikey", "apikey", "node"), null,
@@ -518,7 +517,7 @@ public void testGetRolesForApiKeyNotInContext() throws Exception {
@SuppressWarnings("unchecked")
public void testGetRolesForApiKey() throws Exception {
Map authMetadata = new HashMap<>();
- authMetadata.put(ApiKeyService.API_KEY_ID_KEY, randomAlphaOfLength(12));
+ authMetadata.put(ApiKeyServiceField.API_KEY_ID_KEY, randomAlphaOfLength(12));
boolean emptyApiKeyRoleDescriptor = randomBoolean();
final RoleDescriptor roleARoleDescriptor = new RoleDescriptor("a role", new String[] { "monitor" },
new RoleDescriptor.IndicesPrivileges[] {
@@ -529,7 +528,7 @@ public void testGetRolesForApiKey() throws Exception {
roleARDMap = XContentHelper.convertToMap(XContentType.JSON.xContent(),
BytesReference.bytes(roleARoleDescriptor.toXContent(builder, ToXContent.EMPTY_PARAMS, true)).streamInput(), false);
}
- authMetadata.put(API_KEY_ROLE_DESCRIPTORS_KEY,
+ authMetadata.put(ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY,
(emptyApiKeyRoleDescriptor) ? randomFrom(Arrays.asList(null, Collections.emptyMap()))
: Collections.singletonMap("a role", roleARDMap));
@@ -545,7 +544,7 @@ public void testGetRolesForApiKey() throws Exception {
.streamInput(),
false);
}
- authMetadata.put(API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, Collections.singletonMap("limited role", limitedRdMap));
+ authMetadata.put(ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, Collections.singletonMap("limited role", limitedRdMap));
final Authentication authentication = new Authentication(new User("joe"), new RealmRef("apikey", "apikey", "node"), null,
VersionUtils.randomVersionBetween(random(), Version.V_7_0_0, Version.V_7_8_1),
@@ -581,11 +580,11 @@ public void testGetRolesForApiKey() throws Exception {
public void testGetApiKeyIdAndRoleBytes() {
Map authMetadata = new HashMap<>();
final String apiKeyId = randomAlphaOfLength(12);
- authMetadata.put(ApiKeyService.API_KEY_ID_KEY, apiKeyId);
+ authMetadata.put(ApiKeyServiceField.API_KEY_ID_KEY, apiKeyId);
final BytesReference roleBytes = new BytesArray("{\"a role\": {\"cluster\": [\"all\"]}}");
final BytesReference limitedByRoleBytes = new BytesArray("{\"limitedBy role\": {\"cluster\": [\"all\"]}}");
- authMetadata.put(API_KEY_ROLE_DESCRIPTORS_KEY, roleBytes);
- authMetadata.put(API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, limitedByRoleBytes);
+ authMetadata.put(ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY, roleBytes);
+ authMetadata.put(ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, limitedByRoleBytes);
final Authentication authentication = new Authentication(new User("joe"), new RealmRef("apikey", "apikey", "node"), null,
Version.CURRENT, AuthenticationType.API_KEY, authMetadata);
@@ -1286,14 +1285,14 @@ public static Authentication createApiKeyAuthentication(ApiKeyService apiKeyServ
// maybe remove realm name to simulate old API Key authentication
assert authenticationResult.getStatus() == AuthenticationResult.Status.SUCCESS;
Map authenticationResultMetadata = new HashMap<>(authenticationResult.getMetadata());
- authenticationResultMetadata.remove(ApiKeyService.API_KEY_CREATOR_REALM_NAME);
+ authenticationResultMetadata.remove(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME);
authenticationResult = AuthenticationResult.success(authenticationResult.getUser(), authenticationResultMetadata);
}
if (randomBoolean()) {
// simulate authentication with nameless API Key, see https://github.com/elastic/elasticsearch/issues/59484
assert authenticationResult.getStatus() == AuthenticationResult.Status.SUCCESS;
Map authenticationResultMetadata = new HashMap<>(authenticationResult.getMetadata());
- authenticationResultMetadata.remove(ApiKeyService.API_KEY_NAME_KEY);
+ authenticationResultMetadata.remove(ApiKeyServiceField.API_KEY_NAME_KEY);
authenticationResult = AuthenticationResult.success(authenticationResult.getUser(), authenticationResultMetadata);
}
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/RBACEngineTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/RBACEngineTests.java
index 52f926511df9b..bf87ee0640a4e 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/RBACEngineTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/RBACEngineTests.java
@@ -46,6 +46,7 @@
import org.elasticsearch.xpack.core.security.action.user.HasPrivilegesResponse;
import org.elasticsearch.xpack.core.security.action.user.PutUserAction;
import org.elasticsearch.xpack.core.security.action.user.UserRequest;
+import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.Authentication.AuthenticationType;
import org.elasticsearch.xpack.core.security.authc.esnative.NativeRealmSettings;
@@ -65,7 +66,6 @@
import org.elasticsearch.xpack.core.security.authz.privilege.Privilege;
import org.elasticsearch.xpack.core.security.index.RestrictedIndicesNames;
import org.elasticsearch.xpack.core.security.user.User;
-import org.elasticsearch.xpack.security.authc.ApiKeyService;
import org.elasticsearch.xpack.security.authc.esnative.ReservedRealm;
import org.elasticsearch.xpack.security.authz.RBACEngine.RBACAuthorizationInfo;
import org.elasticsearch.xpack.security.authz.store.CompositeRolesStore;
@@ -246,7 +246,7 @@ public void testSameUserPermissionDoesNotAllowChangePasswordForApiKey() {
when(authentication.getUser()).thenReturn(user);
when(authentication.getAuthenticatedBy()).thenReturn(authenticatedBy);
when(authentication.getAuthenticationType()).thenReturn(Authentication.AuthenticationType.API_KEY);
- when(authenticatedBy.getType()).thenReturn(ApiKeyService.API_KEY_REALM_TYPE);
+ when(authenticatedBy.getType()).thenReturn(ApiKeyServiceField.API_KEY_REALM_TYPE);
assertThat(request, instanceOf(UserRequest.class));
assertFalse(engine.checkSameUserPermissions(action, request, authentication));
@@ -311,7 +311,7 @@ public void testSameUserPermissionAllowsSelfApiKeyInfoRetrievalWhenAuthenticated
when(authentication.getUser()).thenReturn(user);
when(authentication.getAuthenticatedBy()).thenReturn(authenticatedBy);
when(authentication.getAuthenticationType()).thenReturn(AuthenticationType.API_KEY);
- when(authentication.getMetadata()).thenReturn(Map.of(ApiKeyService.API_KEY_ID_KEY, apiKeyId));
+ when(authentication.getMetadata()).thenReturn(Map.of(ApiKeyServiceField.API_KEY_ID_KEY, apiKeyId));
assertTrue(engine.checkSameUserPermissions(GetApiKeyAction.NAME, request, authentication));
}
@@ -324,8 +324,8 @@ public void testSameUserPermissionDeniesApiKeyInfoRetrievalWhenAuthenticatedByAD
final Authentication.RealmRef authenticatedBy = mock(Authentication.RealmRef.class);
when(authentication.getUser()).thenReturn(user);
when(authentication.getAuthenticatedBy()).thenReturn(authenticatedBy);
- when(authenticatedBy.getType()).thenReturn(ApiKeyService.API_KEY_REALM_TYPE);
- when(authentication.getMetadata()).thenReturn(Map.of(ApiKeyService.API_KEY_ID_KEY, randomAlphaOfLengthBetween(4, 7)));
+ when(authenticatedBy.getType()).thenReturn(ApiKeyServiceField.API_KEY_REALM_TYPE);
+ when(authentication.getMetadata()).thenReturn(Map.of(ApiKeyServiceField.API_KEY_ID_KEY, randomAlphaOfLengthBetween(4, 7)));
assertFalse(engine.checkSameUserPermissions(GetApiKeyAction.NAME, request, authentication));
}
@@ -341,7 +341,7 @@ public void testSameUserPermissionDeniesApiKeyInfoRetrievalWhenLookedupByIsPrese
when(authentication.getAuthenticatedBy()).thenReturn(authenticatedBy);
when(authentication.getLookedUpBy()).thenReturn(lookedupBy);
when(authentication.getAuthenticationType()).thenReturn(AuthenticationType.API_KEY);
- when(authentication.getMetadata()).thenReturn(Map.of(ApiKeyService.API_KEY_ID_KEY, randomAlphaOfLengthBetween(4, 7)));
+ when(authentication.getMetadata()).thenReturn(Map.of(ApiKeyServiceField.API_KEY_ID_KEY, randomAlphaOfLengthBetween(4, 7)));
final AssertionError assertionError = expectThrows(AssertionError.class, () -> engine.checkSameUserPermissions(GetApiKeyAction.NAME,
request, authentication));
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java
index 26b4e014e4d39..bc86c55911112 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java
@@ -50,6 +50,7 @@
import org.elasticsearch.xpack.core.XPackSettings;
import org.elasticsearch.xpack.core.security.action.saml.SamlAuthenticateAction;
import org.elasticsearch.xpack.core.security.action.user.PutUserAction;
+import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.Authentication.AuthenticationType;
import org.elasticsearch.xpack.core.security.authc.Authentication.RealmRef;
@@ -112,9 +113,6 @@
import static org.elasticsearch.mock.orig.Mockito.times;
import static org.elasticsearch.mock.orig.Mockito.verifyNoMoreInteractions;
import static org.elasticsearch.test.ActionListenerUtils.anyActionListener;
-import static org.elasticsearch.xpack.core.security.authc.AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY;
-import static org.elasticsearch.xpack.core.security.authc.AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY;
-import static org.elasticsearch.xpack.security.authc.ApiKeyService.API_KEY_ID_KEY;
import static org.elasticsearch.xpack.security.authc.ApiKeyServiceTests.Utils.createApiKeyAuthentication;
import static org.elasticsearch.xpack.core.security.test.TestRestrictedIndices.RESTRICTED_INDICES_AUTOMATON;
import static org.hamcrest.Matchers.anyOf;
@@ -1309,11 +1307,11 @@ public void testCacheEntryIsReusedForIdenticalApiKeyRoles() {
null,
Version.CURRENT,
AuthenticationType.API_KEY,
- Map.of(API_KEY_ID_KEY,
+ Map.of(ApiKeyServiceField.API_KEY_ID_KEY,
"key-id-1",
- API_KEY_ROLE_DESCRIPTORS_KEY,
+ ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY,
roleBytes,
- API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
+ ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
limitedByRoleBytes));
doCallRealMethod().when(apiKeyService).getApiKeyIdAndRoleBytes(eq(authentication), anyBoolean());
@@ -1331,11 +1329,11 @@ public void testCacheEntryIsReusedForIdenticalApiKeyRoles() {
null,
Version.CURRENT,
AuthenticationType.API_KEY,
- Map.of(API_KEY_ID_KEY,
+ Map.of(ApiKeyServiceField.API_KEY_ID_KEY,
"key-id-2",
- API_KEY_ROLE_DESCRIPTORS_KEY,
+ ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY,
roleBytes,
- API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
+ ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
limitedByRoleBytes));
doCallRealMethod().when(apiKeyService).getApiKeyIdAndRoleBytes(eq(authentication), anyBoolean());
roleFuture = new PlainActionFuture<>();
@@ -1352,11 +1350,11 @@ public void testCacheEntryIsReusedForIdenticalApiKeyRoles() {
null,
Version.CURRENT,
AuthenticationType.API_KEY,
- Map.of(API_KEY_ID_KEY,
+ Map.of(ApiKeyServiceField.API_KEY_ID_KEY,
"key-id-3",
- API_KEY_ROLE_DESCRIPTORS_KEY,
+ ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY,
anotherRoleBytes,
- API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
+ ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
limitedByRoleBytes));
doCallRealMethod().when(apiKeyService).getApiKeyIdAndRoleBytes(eq(authentication), anyBoolean());
roleFuture = new PlainActionFuture<>();
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessorTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessorTests.java
index 459f66444a999..1564a8f0b344c 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessorTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessorTests.java
@@ -18,12 +18,12 @@
import org.elasticsearch.xpack.core.security.SecurityContext;
import org.elasticsearch.xpack.core.security.action.ApiKeyTests;
import org.elasticsearch.xpack.core.security.action.service.TokenInfo;
+import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.Authentication.AuthenticationType;
import org.elasticsearch.xpack.core.security.authc.support.AuthenticationContextSerializer;
import org.elasticsearch.xpack.core.security.support.ValidationTests;
import org.elasticsearch.xpack.core.security.user.User;
-import org.elasticsearch.xpack.security.authc.ApiKeyService;
import org.elasticsearch.xpack.security.ingest.SetSecurityUserProcessor.Property;
import org.junit.Before;
import org.mockito.Mockito;
@@ -249,17 +249,18 @@ public void testOverwriteExistingField() throws Exception {
public void testApiKeyPopulation() throws Exception {
User user = new User(randomAlphaOfLengthBetween(4, 12), null, null);
Authentication.RealmRef realmRef = new Authentication.RealmRef(
- ApiKeyService.API_KEY_REALM_NAME, ApiKeyService.API_KEY_REALM_TYPE, "_node_name");
+ ApiKeyServiceField.API_KEY_REALM_NAME, ApiKeyServiceField.API_KEY_REALM_TYPE, "_node_name");
final Map authMetadata = new HashMap<>(Map.of(
- ApiKeyService.API_KEY_ID_KEY, "api_key_id",
- ApiKeyService.API_KEY_NAME_KEY, "api_key_name",
- ApiKeyService.API_KEY_CREATOR_REALM_NAME, "creator_realm_name",
- ApiKeyService.API_KEY_CREATOR_REALM_TYPE, "creator_realm_type"
+ ApiKeyServiceField.API_KEY_ID_KEY, "api_key_id",
+ ApiKeyServiceField.API_KEY_NAME_KEY, "api_key_name",
+ ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME, "creator_realm_name",
+ ApiKeyServiceField.API_KEY_CREATOR_REALM_TYPE, "creator_realm_type"
));
final Map apiKeyMetadata = ApiKeyTests.randomMetadata();
if (apiKeyMetadata != null) {
- authMetadata.put(ApiKeyService.API_KEY_METADATA_KEY, XContentTestUtils.convertToXContent(apiKeyMetadata, XContentType.JSON));
+ authMetadata.put(ApiKeyServiceField.API_KEY_METADATA_KEY,
+ XContentTestUtils.convertToXContent(apiKeyMetadata, XContentType.JSON));
}
Authentication auth = new Authentication(user, realmRef, null, Version.CURRENT,
@@ -290,17 +291,18 @@ public void testApiKeyPopulation() throws Exception {
public void testWillNotOverwriteExistingApiKeyAndRealm() throws Exception {
User user = new User(randomAlphaOfLengthBetween(4, 12), null, null);
Authentication.RealmRef realmRef = new Authentication.RealmRef(
- ApiKeyService.API_KEY_REALM_NAME, ApiKeyService.API_KEY_REALM_TYPE, "_node_name");
+ ApiKeyServiceField.API_KEY_REALM_NAME, ApiKeyServiceField.API_KEY_REALM_TYPE, "_node_name");
final Map authMetadata = new HashMap<>(Map.of(
- ApiKeyService.API_KEY_ID_KEY, "api_key_id",
- ApiKeyService.API_KEY_NAME_KEY, "api_key_name",
- ApiKeyService.API_KEY_CREATOR_REALM_NAME, "creator_realm_name",
- ApiKeyService.API_KEY_CREATOR_REALM_TYPE, "creator_realm_type"
+ ApiKeyServiceField.API_KEY_ID_KEY, "api_key_id",
+ ApiKeyServiceField.API_KEY_NAME_KEY, "api_key_name",
+ ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME, "creator_realm_name",
+ ApiKeyServiceField.API_KEY_CREATOR_REALM_TYPE, "creator_realm_type"
));
final Map apiKeyMetadata = ApiKeyTests.randomMetadata();
if (apiKeyMetadata != null) {
- authMetadata.put(ApiKeyService.API_KEY_METADATA_KEY, XContentTestUtils.convertToXContent(apiKeyMetadata, XContentType.JSON));
+ authMetadata.put(ApiKeyServiceField.API_KEY_METADATA_KEY,
+ XContentTestUtils.convertToXContent(apiKeyMetadata, XContentType.JSON));
}
Authentication auth = new Authentication(user, realmRef, null, Version.CURRENT,
diff --git a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/api_key/10_basic.yml b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/api_key/10_basic.yml
index 46acbe9569f00..0c5efe9fe7eec 100644
--- a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/api_key/10_basic.yml
+++ b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/api_key/10_basic.yml
@@ -124,6 +124,7 @@ teardown:
- length: { roles: 0 }
- match: { authentication_realm.name: "_es_api_key" }
- match: { authentication_realm.type: "_es_api_key" }
+ - match: { api_key.name: "my-api-key" }
- do:
security.clear_api_key_cache:
diff --git a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/authenticate/10_basic.yml b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/authenticate/10_basic.yml
index 9cc6634c6103e..58586c03b978b 100644
--- a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/authenticate/10_basic.yml
+++ b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/authenticate/10_basic.yml
@@ -36,3 +36,4 @@ teardown:
- match: { roles.0: "superuser" }
- match: { full_name: "Authenticate User" }
- match: { authentication_type: "realm" }
+ - match: { api_key: null }
From bc1bac470d08b47478d2983e73663cbd3d140f87 Mon Sep 17 00:00:00 2001
From: Justin Cranford
Date: Mon, 11 Oct 2021 17:00:58 -0400
Subject: [PATCH 02/25] Return API KEY name in _authentication response
Responses to POST /_security/api_key includes id, name, metadata,
api_key (shared secret), and encoded (base64 of id:api_key).
Requests to GET /_security/_authenticate returns data about the user,
but not the API KEY.
When authenticating using an API KEY, return API KEY info map in the
response. The initial feature request asked for 'name'. However, the
request's Authentication header contains 'encoded', so the decoded
'id' will be returned for convenience too.
When authenticating using any other method, API KEY info map is
omitted.
Closes #70306
---
.idea/runConfigurations/Debug_Elasticsearch.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.idea/runConfigurations/Debug_Elasticsearch.xml b/.idea/runConfigurations/Debug_Elasticsearch.xml
index 6b58e18d22266..84bb4dbb313c4 100644
--- a/.idea/runConfigurations/Debug_Elasticsearch.xml
+++ b/.idea/runConfigurations/Debug_Elasticsearch.xml
@@ -12,4 +12,4 @@
-
\ No newline at end of file
+
From 945cb3498ff2813280f4d2cb8e8863eefaa1d707 Mon Sep 17 00:00:00 2001
From: Justin Cranford
Date: Thu, 14 Oct 2021 14:58:04 -0400
Subject: [PATCH 03/25] Resolve PR feedback.
---
.../security/authc/ApiKeyServiceField.java | 3 ++
.../core/security/authc/Authentication.java | 34 +++++++++++++-----
.../security/authc/AuthenticationResult.java | 16 +++------
...elegatePkiAuthenticationResponseTests.java | 7 ++++
.../xpack/security/apikey/ApiKeyRestIT.java | 35 +++++++++----------
.../xpack/security/authc/FileRealmAuthIT.java | 2 +-
.../security/authc/NativeRealmAuthIT.java | 4 +--
.../xpack/security/authc/PkiRealmAuthIT.java | 2 +-
.../security/authc/ReservedRealmAuthIT.java | 2 +-
.../authc/SecurityRealmSmokeTestCase.java | 17 ++-------
.../xpack/security/authc/TokenService.java | 3 +-
.../rest-api-spec/test/api_key/10_basic.yml | 1 +
12 files changed, 66 insertions(+), 60 deletions(-)
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/ApiKeyServiceField.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/ApiKeyServiceField.java
index 4a0b68df1945d..594d2ec1cc77e 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/ApiKeyServiceField.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/ApiKeyServiceField.java
@@ -18,4 +18,7 @@ public class ApiKeyServiceField {
public static final String API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY = "_security_api_key_limited_by_role_descriptors";
public static final String API_KEY_CREATOR_REALM_NAME = "_security_api_key_creator_realm_name";
public static final String API_KEY_CREATOR_REALM_TYPE = "_security_api_key_creator_realm_type";
+
+ private ApiKeyServiceField() {
+ }
}
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java
index 9588ed9a23da7..b2ddcf54020db 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java
@@ -58,6 +58,7 @@ public Authentication(User user, RealmRef authenticatedBy, RealmRef lookedUpBy,
this.version = version;
this.type = type;
this.metadata = metadata;
+ this.requireNonNullApiKeyMetadataAndIdValue(type, metadata);
}
public Authentication(StreamInput in) throws IOException {
@@ -69,8 +70,23 @@ public Authentication(StreamInput in) throws IOException {
this.lookedUpBy = null;
}
this.version = in.getVersion();
- type = AuthenticationType.values()[in.readVInt()];
- metadata = in.readMap();
+ this.type = AuthenticationType.values()[in.readVInt()];
+ this.metadata = in.readMap();
+ this.requireNonNullApiKeyMetadataAndIdValue(type, metadata);
+ }
+
+ /**
+ * For ApiKeys, assert metadata map is non-null, and assert value for id key is non-null.
+ * Do not assert value for name key is non-null. Name is mandatory now, but it was not required in older versions.
+ *
+ * @param type If type=API_KEY, metadata map and id value have always been mandatory.
+ * @param metadata Map of metadata.
+ */
+ private void requireNonNullApiKeyMetadataAndIdValue(AuthenticationType type, Map metadata) {
+ if (AuthenticationType.API_KEY.equals(type)) {
+ Objects.requireNonNull(metadata);
+ Objects.requireNonNull(metadata.get(ApiKeyServiceField.API_KEY_ID_KEY));
+ }
}
public User getUser() {
@@ -252,12 +268,14 @@ public void toXContentFragment(XContentBuilder builder) throws IOException {
builder.endObject();
builder.field(User.Fields.AUTHENTICATION_TYPE.getPreferredName(), getAuthenticationType().name().toLowerCase(Locale.ROOT));
if (isApiKey()) {
- builder.field("api_key",
- Map.of(
- "id", this.metadata.get(ApiKeyServiceField.API_KEY_ID_KEY),
- "name", this.metadata.get(ApiKeyServiceField.API_KEY_NAME_KEY)
- )
- ); // authentication.api_key={"id":"abc123", "name":"my-api-key"}
+ final Map apiKeyInfoMap;
+ if (this.metadata.containsKey(ApiKeyServiceField.API_KEY_NAME_KEY)) { // Map.of() does not accept nulls, check if name present
+ apiKeyInfoMap = Map.of("id", this.metadata.get(ApiKeyServiceField.API_KEY_ID_KEY),
+ "name", this.metadata.get(ApiKeyServiceField.API_KEY_NAME_KEY)); // newer API KEYs include name
+ } else {
+ apiKeyInfoMap = Map.of("id", this.metadata.get(ApiKeyServiceField.API_KEY_ID_KEY)); // older API KEYs lack name
+ }
+ builder.field("api_key", apiKeyInfoMap); // authentication.api_key={"id":"abc123", "name":"my-api-key"}
}
}
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/AuthenticationResult.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/AuthenticationResult.java
index 991bae6b43dc6..bcc2bfde049e3 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/AuthenticationResult.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/AuthenticationResult.java
@@ -24,7 +24,7 @@
*
*/
public final class AuthenticationResult {
- private static final AuthenticationResult NOT_HANDLED = new AuthenticationResult(Status.CONTINUE, null, null, null, null, null);
+ private static final AuthenticationResult NOT_HANDLED = new AuthenticationResult(Status.CONTINUE, null, null, null, null);
public static String THREAD_CONTEXT_KEY = "_xpack_security_auth_result";
@@ -39,16 +39,14 @@ public enum Status {
private final String message;
private final Exception exception;
private final Map metadata;
- private final Map apikeyinfo;
private AuthenticationResult(Status status, @Nullable User user, @Nullable String message, @Nullable Exception exception,
- @Nullable Map metadata, @Nullable Map apikeyinfo) {
+ @Nullable Map metadata) {
this.status = status;
this.user = user;
this.message = message;
this.exception = exception;
this.metadata = metadata == null ? Collections.emptyMap() : Collections.unmodifiableMap(metadata);
- this.apikeyinfo = apikeyinfo;
}
public Status getStatus() {
@@ -71,10 +69,6 @@ public Map getMetadata() {
return metadata;
}
- public Map getApiKeyInfo() {
- return apikeyinfo;
- }
-
/**
* Creates an {@code AuthenticationResult} that indicates that the supplied {@link User}
* has been successfully authenticated.
@@ -96,7 +90,7 @@ public static AuthenticationResult success(User user) {
* @see #success(User)
*/
public static AuthenticationResult success(User user, @Nullable Map metadata) {
- return new AuthenticationResult(Status.SUCCESS, user, null, null, metadata, null);
+ return new AuthenticationResult(Status.SUCCESS, user, null, null, metadata);
}
/**
@@ -123,7 +117,7 @@ public static AuthenticationResult notHandled() {
*/
public static AuthenticationResult unsuccessful(String message, @Nullable Exception cause) {
Objects.requireNonNull(message);
- return new AuthenticationResult(Status.CONTINUE, null, message, cause, null, null);
+ return new AuthenticationResult(Status.CONTINUE, null, message, cause, null);
}
/**
@@ -137,7 +131,7 @@ public static AuthenticationResult unsuccessful(String message, @Nullable Except
*
*/
public static AuthenticationResult terminate(String message, @Nullable Exception cause) {
- return new AuthenticationResult(Status.TERMINATE, null, message, cause, null, null);
+ return new AuthenticationResult(Status.TERMINATE, null, message, cause, null);
}
/**
diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/action/DelegatePkiAuthenticationResponseTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/action/DelegatePkiAuthenticationResponseTests.java
index 460c90d571aaa..f3cc916c65f9a 100644
--- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/action/DelegatePkiAuthenticationResponseTests.java
+++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/action/DelegatePkiAuthenticationResponseTests.java
@@ -16,6 +16,7 @@
import org.elasticsearch.xcontent.XContentParser;
import org.elasticsearch.test.AbstractXContentTestCase;
import org.elasticsearch.xpack.core.security.action.DelegatePkiAuthenticationResponse;
+import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.user.User;
@@ -136,6 +137,12 @@ public static Authentication createAuthentication() {
final String lookupRealmType = randomFrom("file", "native", "ldap", "active_directory", "saml", "kerberos");
final String nodeName = "node_name";
final Authentication.AuthenticationType authenticationType = randomFrom(Authentication.AuthenticationType.values());
+ if (Authentication.AuthenticationType.API_KEY.equals(authenticationType)) {
+ metadata.put(ApiKeyServiceField.API_KEY_ID_KEY, randomAlphaOfLengthBetween(1, 10));
+ if (randomBoolean()) {
+ metadata.put(ApiKeyServiceField.API_KEY_NAME_KEY, randomAlphaOfLengthBetween(1, 10));
+ }
+ }
return new Authentication(
new User(username, roles, fullName, email, metadata, true),
new Authentication.RealmRef(authenticationRealmName, authenticationRealmType, nodeName),
diff --git a/x-pack/plugin/security/qa/security-trial/src/javaRestTest/java/org/elasticsearch/xpack/security/apikey/ApiKeyRestIT.java b/x-pack/plugin/security/qa/security-trial/src/javaRestTest/java/org/elasticsearch/xpack/security/apikey/ApiKeyRestIT.java
index 29767e2f95a13..c7c06ed6b6471 100644
--- a/x-pack/plugin/security/qa/security-trial/src/javaRestTest/java/org/elasticsearch/xpack/security/apikey/ApiKeyRestIT.java
+++ b/x-pack/plugin/security/qa/security-trial/src/javaRestTest/java/org/elasticsearch/xpack/security/apikey/ApiKeyRestIT.java
@@ -28,16 +28,12 @@
import java.util.Map;
import java.util.Set;
-import static org.hamcrest.Matchers.allOf;
-import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.everyItem;
+import static org.hamcrest.Matchers.emptyString;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
-import static org.hamcrest.Matchers.hasKey;
+import static org.hamcrest.Matchers.hasEntry;
import static org.hamcrest.Matchers.instanceOf;
-import static org.hamcrest.Matchers.is;
-import static org.hamcrest.Matchers.isA;
import static org.hamcrest.Matchers.lessThanOrEqualTo;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
@@ -70,34 +66,35 @@ public void cleanUp() throws IOException {
invalidateApiKeysForUser(END_USER);
}
+ @SuppressWarnings({"unchecked"})
public void testAuthenticateResponseApiKey() throws IOException {
- final Map createApiKeyRequestBody = Map.of("name", "my-api-key-name", "metadata", Map.of("a", "b"));
+ final String expectedApiKeyName = "my-api-key-name";
+ final Map expectedApiKeyMetadata = Map.of("not", "returned");
+ final Map createApiKeyRequestBody = Map.of("name", expectedApiKeyName, "metadata", expectedApiKeyMetadata);
final Request createApiKeyRequest = new Request("POST", "_security/api_key");
createApiKeyRequest.setJsonEntity(XContentTestUtils.convertToXContent(createApiKeyRequestBody, XContentType.JSON).utf8ToString());
final Response createApiKeyResponse = adminClient().performRequest(createApiKeyRequest);
- final Map createApiKeyResponseAsMap = responseAsMap(createApiKeyResponse); // keys: id, name, api_key, encoded
- final String encoded = (String) createApiKeyResponseAsMap.get("encoded"); // encoded=Base64(id:api_key)
+ final Map createApiKeyResponseMap = responseAsMap(createApiKeyResponse); // keys: id, name, api_key, encoded
+ final String actualApiKeyId = (String) createApiKeyResponseMap.get("id");
+ final String actualApiKeyName = (String) createApiKeyResponseMap.get("name");
+ final String actualApiKeyEncoded = (String) createApiKeyResponseMap.get("encoded"); // Base64(id:api_key)
+ assertThat(actualApiKeyId, not(emptyString()));
+ assertThat(actualApiKeyName, equalTo(expectedApiKeyName));
+ assertThat(actualApiKeyEncoded, not(emptyString()));
final Request authenticateRequest = new Request("GET", "_security/_authenticate");
authenticateRequest.setOptions(authenticateRequest.getOptions().toBuilder().addHeader(
- "Authorization", "ApiKey " + encoded));
+ "Authorization", "ApiKey " + actualApiKeyEncoded));
final Response authenticateResponse = client().performRequest(authenticateRequest);
assertOK(authenticateResponse);
final Map authenticate = responseAsMap(authenticateResponse); // keys: username, roles, full_name, etc
- // If authentication type is API_KEY, authentication.api_key={"id":"abc123","name":"my-api-key"}
+ // If authentication type is API_KEY, authentication.api_key={"id":"abc123","name":"my-api-key"}. No encoded, api_key, or metadata.
// If authentication type is other, authentication.api_key not present.
- assertThat(authenticate.get("api_key"), instanceOf(Map.class)); // implies hasKey()
- final Map, ?> apiKey = (Map, ?>) authenticate.get("api_key"); // assert Map below
- assertThat(apiKey.keySet(), allOf(
- everyItem(instanceOf(String.class)), // assert apiKey Map,?> is safe to cast to Map
- containsInAnyOrder("id", "name")) // assert apiKey Map exactly contains these keys (and no others)
- );
- assertThat(apiKey.get("id"), allOf(instanceOf(String.class), not(equalTo(""))));
- assertThat(apiKey.get("name"), allOf(instanceOf(String.class), not(equalTo(""))));
+ assertThat(authenticate, hasEntry("api_key", Map.of("id", actualApiKeyId, "name", expectedApiKeyName)));
}
public void testGrantApiKeyForOtherUserWithPassword() throws IOException {
diff --git a/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/FileRealmAuthIT.java b/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/FileRealmAuthIT.java
index fc6e32472adbf..608af3115cce6 100644
--- a/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/FileRealmAuthIT.java
+++ b/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/FileRealmAuthIT.java
@@ -36,7 +36,7 @@ public void testAuthenticationUsingFileRealm() throws IOException {
assertUsername(authenticate, USERNAME);
assertRealm(authenticate, "file", "file0");
assertRoles(authenticate, ROLE_NAME);
- assertApiKeyInfo(authenticate, Authentication.AuthenticationType.REALM);
+ assertNoApiKeyInfo(authenticate, Authentication.AuthenticationType.REALM);
}
}
diff --git a/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/NativeRealmAuthIT.java b/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/NativeRealmAuthIT.java
index d0995bbed172b..b0fae01b5d09b 100644
--- a/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/NativeRealmAuthIT.java
+++ b/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/NativeRealmAuthIT.java
@@ -19,8 +19,6 @@
import java.util.Map;
import java.util.Set;
-import static org.hamcrest.Matchers.is;
-
/**
* Integration Rest Test for testing authentication when all possible realms are configured
*/
@@ -51,7 +49,7 @@ public void testAuthenticationUsingNativeRealm() throws IOException {
assertUsername(authenticate, USERNAME);
assertRealm(authenticate, "native", "native1");
assertRoles(authenticate, ROLE_NAME);
- assertApiKeyInfo(authenticate, Authentication.AuthenticationType.REALM);
+ assertNoApiKeyInfo(authenticate, Authentication.AuthenticationType.REALM);
}
}
diff --git a/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/PkiRealmAuthIT.java b/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/PkiRealmAuthIT.java
index bd416f56b327f..aa3d60ca3af8a 100644
--- a/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/PkiRealmAuthIT.java
+++ b/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/PkiRealmAuthIT.java
@@ -42,7 +42,7 @@ public void testAuthenticationUsingPkiRealm() throws IOException {
assertUsername(authenticate, USERNAME);
assertRealm(authenticate, "pki", "pki4");
assertRoles(authenticate, new String[0]);
- assertApiKeyInfo(authenticate, Authentication.AuthenticationType.REALM);
+ assertNoApiKeyInfo(authenticate, Authentication.AuthenticationType.REALM);
}
}
diff --git a/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/ReservedRealmAuthIT.java b/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/ReservedRealmAuthIT.java
index 1f2d723858372..9167d0500ccac 100644
--- a/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/ReservedRealmAuthIT.java
+++ b/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/ReservedRealmAuthIT.java
@@ -42,7 +42,7 @@ public void testAuthenticationUsingReservedRealm() throws IOException {
assertUsername(authenticate, USERNAME);
assertRealm(authenticate, "reserved", "reserved");
assertRoles(authenticate, ROLE_NAME);
- assertApiKeyInfo(authenticate, Authentication.AuthenticationType.REALM);
+ assertNoApiKeyInfo(authenticate, Authentication.AuthenticationType.REALM);
}
}
diff --git a/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/SecurityRealmSmokeTestCase.java b/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/SecurityRealmSmokeTestCase.java
index 3cd3dbb106998..7cfcef6324b81 100644
--- a/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/SecurityRealmSmokeTestCase.java
+++ b/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/SecurityRealmSmokeTestCase.java
@@ -113,21 +113,10 @@ protected void assertRoles(Map authenticateResponse, String... r
);
}
- protected void assertApiKeyInfo(Map authenticateResponse, AuthenticationType type) {
- // If authentication type is API_KEY, authentication.api_key={"id":"abc123","name":"my-api-key"}
+ protected void assertNoApiKeyInfo(Map authenticateResponse, AuthenticationType type) {
+ // If authentication type is API_KEY, authentication.api_key={"id":"abc123","name":"my-api-key"}. No encoded, api_key, or metadata.
// If authentication type is other, authentication.api_key not present.
- if (AuthenticationType.API_KEY.equals(type)) {
- assertThat(authenticateResponse.get("api_key"), instanceOf(Map.class)); // implies hasKey()
- final Map, ?> apiKey = (Map, ?>) authenticateResponse.get("api_key"); // assert Map below
- assertThat(apiKey.keySet(), allOf(
- everyItem(instanceOf(String.class)), // assert apiKey Map,?> is safe to cast to Map
- containsInAnyOrder("id", "name")) // assert apiKey Map exactly contains these keys (and no others)
- );
- assertThat(apiKey.get("id"), allOf(instanceOf(String.class), not(equalTo(""))));
- assertThat(apiKey.get("name"), allOf(instanceOf(String.class), not(equalTo(""))));
- } else {
- assertThat(authenticateResponse, not(hasKey("api_key")));
- }
+ assertThat(authenticateResponse, not(hasKey("api_key")));
}
protected void createUser(String username, SecureString password, List roles) throws IOException {
diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/TokenService.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/TokenService.java
index f2bbe1a05b9a2..254eb4024615e 100644
--- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/TokenService.java
+++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/TokenService.java
@@ -325,8 +325,7 @@ private void createOAuth2Tokens(String accessToken, String refreshToken, Version
new IllegalArgumentException("originating client authentication must be provided")));
} else {
final Authentication tokenAuth = new Authentication(authentication.getUser(), authentication.getAuthenticatedBy(),
- authentication.getLookedUpBy(), tokenVersion, AuthenticationType.TOKEN,
- authentication.getMetadata());
+ authentication.getLookedUpBy(), tokenVersion, AuthenticationType.TOKEN, authentication.getMetadata());
final String storedAccessToken;
final String storedRefreshToken;
if (tokenVersion.onOrAfter(VERSION_HASHED_TOKENS)) {
diff --git a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/api_key/10_basic.yml b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/api_key/10_basic.yml
index 0c5efe9fe7eec..b575ddccb449a 100644
--- a/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/api_key/10_basic.yml
+++ b/x-pack/plugin/src/yamlRestTest/resources/rest-api-spec/test/api_key/10_basic.yml
@@ -124,6 +124,7 @@ teardown:
- length: { roles: 0 }
- match: { authentication_realm.name: "_es_api_key" }
- match: { authentication_realm.type: "_es_api_key" }
+ - match: { api_key.id: "${api_key_id}" }
- match: { api_key.name: "my-api-key" }
- do:
From 6339ad61accabdcc95ed1074db18a8e682ef8dcd Mon Sep 17 00:00:00 2001
From: Justin Cranford
Date: Fri, 15 Oct 2021 00:39:07 -0400
Subject: [PATCH 04/25] Add api_key id+name in Authentication metadata.
---
.../elasticsearch/xpack/security/SecurityContextTests.java | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityContextTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityContextTests.java
index e624665b3a2a8..1db8d95d56f83 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityContextTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityContextTests.java
@@ -142,6 +142,8 @@ public void testExecuteAfterRewritingAuthenticationWillConditionallyRewriteNewAp
User user = new User("test", null, new User("authUser"));
RealmRef authBy = new RealmRef("_es_api_key", "_es_api_key", "node1");
final Map metadata = Map.of(
+ ApiKeyServiceField.API_KEY_ID_KEY, randomAlphaOfLengthBetween(1, 10),
+ ApiKeyServiceField.API_KEY_NAME_KEY, randomAlphaOfLengthBetween(1, 10),
ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY, new BytesArray("{\"a role\": {\"cluster\": [\"all\"]}}"),
ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, new BytesArray("{\"limitedBy role\": {\"cluster\": [\"all\"]}}")
);
@@ -169,6 +171,8 @@ public void testExecuteAfterRewritingAuthenticationWillConditionallyRewriteOldAp
User user = new User("test", null, new User("authUser"));
RealmRef authBy = new RealmRef("_es_api_key", "_es_api_key", "node1");
final Map metadata = Map.of(
+ ApiKeyServiceField.API_KEY_ID_KEY, randomAlphaOfLengthBetween(1, 10),
+ ApiKeyServiceField.API_KEY_NAME_KEY, randomAlphaOfLengthBetween(1, 10),
ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY, Map.of("a role", Map.of("cluster", List.of("all"))),
ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, Map.of("limitedBy role", Map.of("cluster", List.of("all")))
);
From fa4542c8bbb4d5bafc69bab4eac9fee038aea386 Mon Sep 17 00:00:00 2001
From: Justin Cranford
Date: Fri, 15 Oct 2021 09:25:13 -0400
Subject: [PATCH 05/25] Fix another test lacking mandatory api_key id. Fix
merge issue.
---
...elegatePkiAuthenticationResponseTests.java | 7 ++++++
.../authz/store/CompositeRolesStoreTests.java | 22 +++++++++----------
2 files changed, 17 insertions(+), 12 deletions(-)
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/DelegatePkiAuthenticationResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/DelegatePkiAuthenticationResponseTests.java
index 404f269cf545b..0ffa88bddf9fb 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/DelegatePkiAuthenticationResponseTests.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/DelegatePkiAuthenticationResponseTests.java
@@ -13,6 +13,7 @@
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.xcontent.XContentParser;
import org.elasticsearch.xcontent.XContentType;
+import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.user.User;
@@ -77,6 +78,12 @@ protected Authentication createAuthentication() {
final String lookupRealmType = randomFrom("file", "native", "ldap", "active_directory", "saml", "kerberos");
final String nodeName = randomAlphaOfLengthBetween(1, 10);
final Authentication.AuthenticationType authenticationType = randomFrom(Authentication.AuthenticationType.values());
+ if (Authentication.AuthenticationType.API_KEY.equals(authenticationType)) {
+ metadata.put(ApiKeyServiceField.API_KEY_ID_KEY, randomAlphaOfLengthBetween(1, 10));
+ if (randomBoolean()) {
+ metadata.put(ApiKeyServiceField.API_KEY_NAME_KEY, randomAlphaOfLengthBetween(1, 10));
+ }
+ }
return new Authentication(
new User(username, roles, fullName, email, metadata, true),
new Authentication.RealmRef(authenticationRealmName, authenticationRealmType, nodeName),
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java
index de1cafd620023..4b4b3387eb3f0 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java
@@ -50,6 +50,7 @@
import org.elasticsearch.xpack.core.XPackSettings;
import org.elasticsearch.xpack.core.security.action.saml.SamlAuthenticateAction;
import org.elasticsearch.xpack.core.security.action.user.PutUserAction;
+import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.Authentication.AuthenticationType;
import org.elasticsearch.xpack.core.security.authc.Authentication.RealmRef;
@@ -113,9 +114,6 @@
import static org.elasticsearch.mock.orig.Mockito.verifyNoMoreInteractions;
import static org.elasticsearch.test.ActionListenerUtils.anyActionListener;
import static org.elasticsearch.xpack.core.security.SecurityField.DOCUMENT_LEVEL_SECURITY_FEATURE;
-import static org.elasticsearch.xpack.core.security.authc.AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY;
-import static org.elasticsearch.xpack.core.security.authc.AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY;
-import static org.elasticsearch.xpack.security.authc.ApiKeyService.API_KEY_ID_KEY;
import static org.elasticsearch.xpack.security.authc.ApiKeyServiceTests.Utils.createApiKeyAuthentication;
import static org.elasticsearch.xpack.core.security.test.TestRestrictedIndices.RESTRICTED_INDICES_AUTOMATON;
import static org.hamcrest.Matchers.anyOf;
@@ -1310,11 +1308,11 @@ public void testCacheEntryIsReusedForIdenticalApiKeyRoles() {
null,
Version.CURRENT,
AuthenticationType.API_KEY,
- Map.of(API_KEY_ID_KEY,
+ Map.of(ApiKeyServiceField.API_KEY_ID_KEY,
"key-id-1",
- API_KEY_ROLE_DESCRIPTORS_KEY,
+ ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY,
roleBytes,
- API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
+ ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
limitedByRoleBytes));
doCallRealMethod().when(apiKeyService).getApiKeyIdAndRoleBytes(eq(authentication), anyBoolean());
@@ -1332,11 +1330,11 @@ public void testCacheEntryIsReusedForIdenticalApiKeyRoles() {
null,
Version.CURRENT,
AuthenticationType.API_KEY,
- Map.of(API_KEY_ID_KEY,
+ Map.of(ApiKeyServiceField.API_KEY_ID_KEY,
"key-id-2",
- API_KEY_ROLE_DESCRIPTORS_KEY,
+ ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY,
roleBytes,
- API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
+ ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
limitedByRoleBytes));
doCallRealMethod().when(apiKeyService).getApiKeyIdAndRoleBytes(eq(authentication), anyBoolean());
roleFuture = new PlainActionFuture<>();
@@ -1353,11 +1351,11 @@ public void testCacheEntryIsReusedForIdenticalApiKeyRoles() {
null,
Version.CURRENT,
AuthenticationType.API_KEY,
- Map.of(API_KEY_ID_KEY,
+ Map.of(ApiKeyServiceField.API_KEY_ID_KEY,
"key-id-3",
- API_KEY_ROLE_DESCRIPTORS_KEY,
+ ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY,
anotherRoleBytes,
- API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
+ ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
limitedByRoleBytes));
doCallRealMethod().when(apiKeyService).getApiKeyIdAndRoleBytes(eq(authentication), anyBoolean());
roleFuture = new PlainActionFuture<>();
From 6dfe2a7e2024a8f1ec10bacc281e1b785a8c16aa Mon Sep 17 00:00:00 2001
From: Justin Cranford
Date: Fri, 15 Oct 2021 12:05:51 -0400
Subject: [PATCH 06/25] Make API KEY info map validation code reusable.
---
.../core/security/authc/Authentication.java | 35 ++++++++++++++-----
1 file changed, 26 insertions(+), 9 deletions(-)
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java
index b2ddcf54020db..189647b4250e3 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java
@@ -58,7 +58,7 @@ public Authentication(User user, RealmRef authenticatedBy, RealmRef lookedUpBy,
this.version = version;
this.type = type;
this.metadata = metadata;
- this.requireNonNullApiKeyMetadataAndIdValue(type, metadata);
+ this.verifyApiKeyInfoAndCreateApiKeyInfoMap(); // authentication.api_key={"id":"ab12", "name":"my-key"}
}
public Authentication(StreamInput in) throws IOException {
@@ -72,7 +72,7 @@ public Authentication(StreamInput in) throws IOException {
this.version = in.getVersion();
this.type = AuthenticationType.values()[in.readVInt()];
this.metadata = in.readMap();
- this.requireNonNullApiKeyMetadataAndIdValue(type, metadata);
+ this.verifyApiKeyInfoAndCreateApiKeyInfoMap(); // authentication.api_key={"id":"ab12", "name":"my-key"}
}
/**
@@ -268,15 +268,32 @@ public void toXContentFragment(XContentBuilder builder) throws IOException {
builder.endObject();
builder.field(User.Fields.AUTHENTICATION_TYPE.getPreferredName(), getAuthenticationType().name().toLowerCase(Locale.ROOT));
if (isApiKey()) {
- final Map apiKeyInfoMap;
- if (this.metadata.containsKey(ApiKeyServiceField.API_KEY_NAME_KEY)) { // Map.of() does not accept nulls, check if name present
- apiKeyInfoMap = Map.of("id", this.metadata.get(ApiKeyServiceField.API_KEY_ID_KEY),
- "name", this.metadata.get(ApiKeyServiceField.API_KEY_NAME_KEY)); // newer API KEYs include name
- } else {
- apiKeyInfoMap = Map.of("id", this.metadata.get(ApiKeyServiceField.API_KEY_ID_KEY)); // older API KEYs lack name
+ builder.field("api_key", verifyApiKeyInfoAndCreateApiKeyInfoMap()); // authentication.api_key={"id":"ab12", "name":"my-key"}
+ }
+ }
+
+ /**
+ * If authenticationType=API_KEY then validate and return API KEY info map, otherwise return null map.
+ *
+ * @return Map of API KEY info, or null for other authentication types.
+ * @throws IllegalArgumentException Error if API KEY id is missing or null, or if API KEY name present but null.
+ */
+ private Map verifyApiKeyInfoAndCreateApiKeyInfoMap() throws IllegalArgumentException {
+ if (isApiKey()) {
+ final String apiKeyId = (String) this.metadata.get(ApiKeyServiceField.API_KEY_ID_KEY);
+ if (apiKeyId == null) { // checks for both errors: 1) metadata.containsKey==false, 2) metadata.get==null
+ throw new IllegalArgumentException("If AuthenticationType=API_KEY, User metadata must contain non-null API KEY id");
+ }
+ if (this.metadata.containsKey(ApiKeyServiceField.API_KEY_NAME_KEY)) { // handle older API KEYs where name was not mandatory
+ final String apiKeyName = (String) this.metadata.get(ApiKeyServiceField.API_KEY_NAME_KEY);
+ if (apiKeyName == null) {
+ throw new IllegalArgumentException("If AuthenticationType=API_KEY, User metadata with API KEY name must be non-null");
+ }
+ return Map.of("id", apiKeyId, "name", apiKeyName); // newer API KEYs include name
}
- builder.field("api_key", apiKeyInfoMap); // authentication.api_key={"id":"abc123", "name":"my-api-key"}
+ return Map.of("id", apiKeyId); // older API KEYs lack name
}
+ return null;
}
@Override
From 940a9cb2f99623d73358f2ebaf0481d700b881ce Mon Sep 17 00:00:00 2001
From: Justin Cranford
Date: Fri, 15 Oct 2021 12:06:45 -0400
Subject: [PATCH 07/25] Remove unused method.
---
.../xpack/core/security/authc/Authentication.java | 14 --------------
1 file changed, 14 deletions(-)
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java
index 189647b4250e3..5fe1fc7593d9c 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java
@@ -75,20 +75,6 @@ public Authentication(StreamInput in) throws IOException {
this.verifyApiKeyInfoAndCreateApiKeyInfoMap(); // authentication.api_key={"id":"ab12", "name":"my-key"}
}
- /**
- * For ApiKeys, assert metadata map is non-null, and assert value for id key is non-null.
- * Do not assert value for name key is non-null. Name is mandatory now, but it was not required in older versions.
- *
- * @param type If type=API_KEY, metadata map and id value have always been mandatory.
- * @param metadata Map of metadata.
- */
- private void requireNonNullApiKeyMetadataAndIdValue(AuthenticationType type, Map metadata) {
- if (AuthenticationType.API_KEY.equals(type)) {
- Objects.requireNonNull(metadata);
- Objects.requireNonNull(metadata.get(ApiKeyServiceField.API_KEY_ID_KEY));
- }
- }
-
public User getUser() {
return user;
}
From 70dbd86d69817ccf2aa3eb199306ef8cd40f69f1 Mon Sep 17 00:00:00 2001
From: Justin Cranford
Date: Fri, 15 Oct 2021 16:07:10 -0400
Subject: [PATCH 08/25] Fix client tests.
---
.../client/security/AuthenticateResponse.java | 24 ++++++++++---------
.../security/AuthenticateResponseTests.java | 9 +++++--
.../security/CreateTokenResponseTests.java | 6 ++++-
...elegatePkiAuthenticationResponseTests.java | 12 ++++++++--
4 files changed, 35 insertions(+), 16 deletions(-)
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/AuthenticateResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/AuthenticateResponse.java
index 4ae09ee4dd9d9..fd07484fc0a66 100644
--- a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/AuthenticateResponse.java
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/AuthenticateResponse.java
@@ -65,7 +65,7 @@ public final class AuthenticateResponse implements ToXContentObject {
final ConstructingObjectParser apiKeyInfoParser = new ConstructingObjectParser<>("api_key", true,
a -> new ApiKeyInfo((String) a[0], (String) a[1]));
apiKeyInfoParser.declareString(constructorArg(), API_KEY_INFO_ID);
- apiKeyInfoParser.declareString(constructorArg(), API_KEY_INFO_NAME);
+ apiKeyInfoParser.declareString(optionalConstructorArg(), API_KEY_INFO_NAME);
PARSER.declareString(constructorArg(), USERNAME);
PARSER.declareStringArray(constructorArg(), ROLES);
@@ -90,15 +90,15 @@ public final class AuthenticateResponse implements ToXContentObject {
@Nullable
private final ApiKeyInfo apikeyinfo; // authentication.api_key={"id":"abc123","name":"my-api-key"}
- public AuthenticateResponse(User user, boolean enabled, RealmInfo authenticationRealm,
- RealmInfo lookupRealm, String authenticationType) {
- this(user, enabled, authenticationRealm, lookupRealm, authenticationType, null, null);
- }
-
- public AuthenticateResponse(User user, boolean enabled, RealmInfo authenticationRealm,
- RealmInfo lookupRealm, String authenticationType, @Nullable Map token) {
- this(user, enabled, authenticationRealm, lookupRealm, authenticationType, token, null);
- }
+// public AuthenticateResponse(User user, boolean enabled, RealmInfo authenticationRealm,
+// RealmInfo lookupRealm, String authenticationType) {
+// this(user, enabled, authenticationRealm, lookupRealm, authenticationType, null, null);
+// }
+//
+// public AuthenticateResponse(User user, boolean enabled, RealmInfo authenticationRealm,
+// RealmInfo lookupRealm, String authenticationType, @Nullable Map token) {
+// this(user, enabled, authenticationRealm, lookupRealm, authenticationType, token, null);
+// }
public AuthenticateResponse(User user, boolean enabled, RealmInfo authenticationRealm,
RealmInfo lookupRealm, String authenticationType, @Nullable Map token,
@@ -182,7 +182,9 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws
if (apikeyinfo != null) {
builder.startObject(AuthenticateResponse.API_KEY_INFO.getPreferredName());
builder.field(AuthenticateResponse.API_KEY_INFO_ID.getPreferredName(), apikeyinfo.getId());
- builder.field(AuthenticateResponse.API_KEY_INFO_NAME.getPreferredName(), apikeyinfo.getName());
+ if (apikeyinfo.getName() != null) {
+ builder.field(AuthenticateResponse.API_KEY_INFO_NAME.getPreferredName(), apikeyinfo.getName());
+ }
builder.endObject();
}
return builder.endObject();
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/AuthenticateResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/AuthenticateResponseTests.java
index 2d16d7b012812..1496048785af3 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/AuthenticateResponseTests.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/AuthenticateResponseTests.java
@@ -82,7 +82,9 @@ protected AuthenticateResponse createTestInstance() {
final AuthenticateResponse.ApiKeyInfo apiKeyInfo;
if ("api_key".equals(authenticationType)) {
- apiKeyInfo = new AuthenticateResponse.ApiKeyInfo(randomAlphaOfLength(16), randomAlphaOfLength(20));
+ final String apiKeyId = randomAlphaOfLength(16); // mandatory
+ final String apiKeyName = randomBoolean() ? randomAlphaOfLength(20) : null; // optional
+ apiKeyInfo = new AuthenticateResponse.ApiKeyInfo(apiKeyId, apiKeyName);
} else {
apiKeyInfo = null;
}
@@ -178,7 +180,10 @@ private AuthenticateResponse mutate(AuthenticateResponse response) {
originalUser.getFullName(), originalUser.getEmail()), response.enabled(), response.getAuthenticationRealm(),
response.getLookupRealm(), response.getAuthenticationType(), response.getToken(),
response.getApiKeyInfo() == null
- ? new AuthenticateResponse.ApiKeyInfo(randomAlphaOfLength(16), randomAlphaOfLength(20)) : null
+ ? new AuthenticateResponse.ApiKeyInfo(
+ randomAlphaOfLength(16), // mandatory
+ randomBoolean() ? randomAlphaOfLength(20) : null // optional
+ ) : null
);
default:
fail("Random number " + randomSwitchCase + " did not match any switch cases");
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/CreateTokenResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/CreateTokenResponseTests.java
index a17703e228e3e..8f066fbf9fb10 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/CreateTokenResponseTests.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/CreateTokenResponseTests.java
@@ -35,7 +35,11 @@ public void testFromXContent() throws IOException {
true, new AuthenticateResponse.RealmInfo(randomAlphaOfLength(5), randomAlphaOfLength(7)),
new AuthenticateResponse.RealmInfo(randomAlphaOfLength(5), randomAlphaOfLength(5)), "realm",
Map.of("servicetoken1", randomAlphaOfLengthBetween(3, 8)),
- new AuthenticateResponse.ApiKeyInfo(randomAlphaOfLength(16), randomAlphaOfLength(20)));
+ new AuthenticateResponse.ApiKeyInfo(
+ randomAlphaOfLength(16), // mandatory
+ randomBoolean() ? randomAlphaOfLength(20) : null // optional
+ )
+ );
final XContentType xContentType = randomFrom(XContentType.values());
final XContentBuilder builder = XContentFactory.contentBuilder(xContentType);
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/DelegatePkiAuthenticationResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/DelegatePkiAuthenticationResponseTests.java
index 0ffa88bddf9fb..56ac5d05d3a59 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/DelegatePkiAuthenticationResponseTests.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/DelegatePkiAuthenticationResponseTests.java
@@ -30,7 +30,7 @@ public class DelegatePkiAuthenticationResponseTests extends
AbstractResponseTestCase {
- @Override
+ @Override
protected org.elasticsearch.xpack.core.security.action.DelegatePkiAuthenticationResponse createServerTestInstance(
XContentType xContentType) {
return new org.elasticsearch.xpack.core.security.action.DelegatePkiAuthenticationResponse(randomAlphaOfLength(6),
@@ -100,7 +100,15 @@ AuthenticateResponse createServerAuthenticationResponse(Authentication authentic
authentication.getAuthenticatedBy().getName(): authentication.getLookedUpBy().getName(),
authentication.getLookedUpBy() == null?
authentication.getAuthenticatedBy().getType(): authentication.getLookedUpBy().getType());
+ final AuthenticateResponse.ApiKeyInfo apiKeyInfo;
+ if (Authentication.AuthenticationType.API_KEY.equals(authentication.getAuthenticationType())) {
+ final String apiKeyId = (String) authentication.getMetadata().get(ApiKeyServiceField.API_KEY_ID_KEY); // mandatory
+ final String apiKeyName = (String) authentication.getMetadata().get(ApiKeyServiceField.API_KEY_NAME_KEY); // optional
+ apiKeyInfo = new AuthenticateResponse.ApiKeyInfo(apiKeyId, apiKeyName);
+ } else {
+ apiKeyInfo = null;
+ }
return new AuthenticateResponse(cUser, user.enabled(), authenticatedBy, lookedUpBy,
- authentication.getAuthenticationType().toString().toLowerCase(Locale.ROOT), null, null);
+ authentication.getAuthenticationType().toString().toLowerCase(Locale.ROOT), null, apiKeyInfo);
}
}
From 95a7777a57c0da737f586b10ed6fd6ea83125b73 Mon Sep 17 00:00:00 2001
From: Justin Cranford
Date: Fri, 15 Oct 2021 16:38:13 -0400
Subject: [PATCH 09/25] Remove whitespace edits.
---
.../client/security/AuthenticateResponse.java | 11 -------
.../security/AuthenticateResponseTests.java | 31 +++++++------------
.../security/CreateTokenResponseTests.java | 2 +-
...elegatePkiAuthenticationResponseTests.java | 2 +-
.../core/security/authc/Authentication.java | 6 ++--
.../authc/SecurityRealmSmokeTestCase.java | 5 ---
6 files changed, 17 insertions(+), 40 deletions(-)
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/AuthenticateResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/AuthenticateResponse.java
index fd07484fc0a66..f5f17922371f4 100644
--- a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/AuthenticateResponse.java
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/AuthenticateResponse.java
@@ -55,7 +55,6 @@ public final class AuthenticateResponse implements ToXContentObject {
new User((String) a[0], ((List) a[1]), (Map) a[2],
(String) a[3], (String) a[4]), (Boolean) a[5], (RealmInfo) a[6], (RealmInfo) a[7], (String) a[8],
(Map) a[9], (ApiKeyInfo) a[10]));
-
static {
final ConstructingObjectParser realmInfoParser = new ConstructingObjectParser<>("realm_info", true,
a -> new RealmInfo((String) a[0], (String) a[1]));
@@ -90,16 +89,6 @@ public final class AuthenticateResponse implements ToXContentObject {
@Nullable
private final ApiKeyInfo apikeyinfo; // authentication.api_key={"id":"abc123","name":"my-api-key"}
-// public AuthenticateResponse(User user, boolean enabled, RealmInfo authenticationRealm,
-// RealmInfo lookupRealm, String authenticationType) {
-// this(user, enabled, authenticationRealm, lookupRealm, authenticationType, null, null);
-// }
-//
-// public AuthenticateResponse(User user, boolean enabled, RealmInfo authenticationRealm,
-// RealmInfo lookupRealm, String authenticationType, @Nullable Map token) {
-// this(user, enabled, authenticationRealm, lookupRealm, authenticationType, token, null);
-// }
-
public AuthenticateResponse(User user, boolean enabled, RealmInfo authenticationRealm,
RealmInfo lookupRealm, String authenticationType, @Nullable Map token,
@Nullable ApiKeyInfo apikeyinfo) {
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/AuthenticateResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/AuthenticateResponseTests.java
index 1496048785af3..f53c66995f745 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/AuthenticateResponseTests.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/AuthenticateResponseTests.java
@@ -61,10 +61,11 @@ protected AuthenticateResponse createTestInstance() {
final String fullName = randomFrom(random(), null, randomAlphaOfLengthBetween(0, 4));
final String email = randomFrom(random(), null, randomAlphaOfLengthBetween(0, 4));
final boolean enabled = randomBoolean();
-
- final String authenticationRealmType = randomFrom("service_account");
+ final String authenticationRealmName = randomAlphaOfLength(5);
+ final String authenticationRealmType = randomFrom(
+ "service_account");
final AuthenticateResponse.RealmInfo authenticationRealm =
- new AuthenticateResponse.RealmInfo(randomAlphaOfLength(5), authenticationRealmType);
+ new AuthenticateResponse.RealmInfo(authenticationRealmName, authenticationRealmType);
final AuthenticateResponse.RealmInfo lookupRealm;
final Map tokenInfo;
@@ -113,49 +114,41 @@ private AuthenticateResponse mutate(AuthenticateResponse response) {
case 1:
return new AuthenticateResponse(new User(originalUser.getUsername() + "wrong", originalUser.getRoles(),
originalUser.getMetadata(), originalUser.getFullName(), originalUser.getEmail()), response.enabled(),
- response.getAuthenticationRealm(), response.getLookupRealm(), response.getAuthenticationType(), response.getToken(),
- response.getApiKeyInfo());
+ response.getAuthenticationRealm(), response.getLookupRealm(), response.getAuthenticationType(), response.getToken(), response.getApiKeyInfo());
case 2:
final List wrongRoles = new ArrayList<>(originalUser.getRoles());
wrongRoles.add(randomAlphaOfLengthBetween(1, 4));
return new AuthenticateResponse(new User(originalUser.getUsername(), wrongRoles, originalUser.getMetadata(),
originalUser.getFullName(), originalUser.getEmail()), response.enabled(), response.getAuthenticationRealm(),
- response.getLookupRealm(), response.getAuthenticationType(), response.getToken(),
- response.getApiKeyInfo());
+ response.getLookupRealm(), response.getAuthenticationType(), response.getToken(), response.getApiKeyInfo());
case 3:
final Map wrongMetadata = new HashMap<>(originalUser.getMetadata());
wrongMetadata.put("wrong_string", randomAlphaOfLengthBetween(0, 4));
return new AuthenticateResponse(new User(originalUser.getUsername(), originalUser.getRoles(), wrongMetadata,
originalUser.getFullName(), originalUser.getEmail()), response.enabled(), response.getAuthenticationRealm(),
- response.getLookupRealm(), response.getAuthenticationType(), response.getToken(),
- response.getApiKeyInfo());
+ response.getLookupRealm(), response.getAuthenticationType(), response.getToken(), response.getApiKeyInfo());
case 4:
return new AuthenticateResponse(new User(originalUser.getUsername(), originalUser.getRoles(), originalUser.getMetadata(),
originalUser.getFullName() + "wrong", originalUser.getEmail()), response.enabled(),
- response.getAuthenticationRealm(), response.getLookupRealm(), response.getAuthenticationType(), response.getToken(),
- response.getApiKeyInfo());
+ response.getAuthenticationRealm(), response.getLookupRealm(), response.getAuthenticationType(), response.getToken(), response.getApiKeyInfo());
case 5:
return new AuthenticateResponse(new User(originalUser.getUsername(), originalUser.getRoles(), originalUser.getMetadata(),
originalUser.getFullName(), originalUser.getEmail() + "wrong"), response.enabled(),
- response.getAuthenticationRealm(), response.getLookupRealm(), response.getAuthenticationType(), response.getToken(),
- response.getApiKeyInfo());
+ response.getAuthenticationRealm(), response.getLookupRealm(), response.getAuthenticationType(), response.getToken(), response.getApiKeyInfo());
case 6:
return new AuthenticateResponse(new User(originalUser.getUsername(), originalUser.getRoles(), originalUser.getMetadata(),
originalUser.getFullName(), originalUser.getEmail()), response.enabled() == false, response.getAuthenticationRealm(),
- response.getLookupRealm(), response.getAuthenticationType(), response.getToken(),
- response.getApiKeyInfo());
+ response.getLookupRealm(), response.getAuthenticationType(), response.getToken(), response.getApiKeyInfo());
case 7:
return new AuthenticateResponse(new User(originalUser.getUsername(), originalUser.getRoles(), originalUser.getMetadata(),
originalUser.getFullName(), originalUser.getEmail()), response.enabled(), response.getAuthenticationRealm(),
new AuthenticateResponse.RealmInfo(randomAlphaOfLength(5), randomAlphaOfLength(5)),
- response.getAuthenticationType(), response.getToken(),
- response.getApiKeyInfo());
+ response.getAuthenticationType(), response.getToken(), response.getApiKeyInfo());
case 8:
return new AuthenticateResponse(new User(originalUser.getUsername(), originalUser.getRoles(), originalUser.getMetadata(),
originalUser.getFullName(), originalUser.getEmail()), response.enabled(),
new AuthenticateResponse.RealmInfo(randomAlphaOfLength(5), randomAlphaOfLength(5)), response.getLookupRealm(),
- response.getAuthenticationType(), response.getToken(),
- response.getApiKeyInfo());
+ response.getAuthenticationType(), response.getToken(), response.getApiKeyInfo());
case 9:
return new AuthenticateResponse(new User(originalUser.getUsername(), originalUser.getRoles(), originalUser.getMetadata(),
originalUser.getFullName(), originalUser.getEmail()), response.enabled(), response.getAuthenticationRealm(),
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/CreateTokenResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/CreateTokenResponseTests.java
index 8f066fbf9fb10..cb390aecf2f23 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/CreateTokenResponseTests.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/CreateTokenResponseTests.java
@@ -34,7 +34,7 @@ public void testFromXContent() throws IOException {
Arrays.asList(randomAlphaOfLength(9))),
true, new AuthenticateResponse.RealmInfo(randomAlphaOfLength(5), randomAlphaOfLength(7)),
new AuthenticateResponse.RealmInfo(randomAlphaOfLength(5), randomAlphaOfLength(5)), "realm",
- Map.of("servicetoken1", randomAlphaOfLengthBetween(3, 8)),
+ null,
new AuthenticateResponse.ApiKeyInfo(
randomAlphaOfLength(16), // mandatory
randomBoolean() ? randomAlphaOfLength(20) : null // optional
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/DelegatePkiAuthenticationResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/DelegatePkiAuthenticationResponseTests.java
index 56ac5d05d3a59..ef35d76f0b388 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/DelegatePkiAuthenticationResponseTests.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/DelegatePkiAuthenticationResponseTests.java
@@ -30,7 +30,7 @@ public class DelegatePkiAuthenticationResponseTests extends
AbstractResponseTestCase {
- @Override
+ @Override
protected org.elasticsearch.xpack.core.security.action.DelegatePkiAuthenticationResponse createServerTestInstance(
XContentType xContentType) {
return new org.elasticsearch.xpack.core.security.action.DelegatePkiAuthenticationResponse(randomAlphaOfLength(6),
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java
index 5fe1fc7593d9c..718fb4fd76fca 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java
@@ -35,7 +35,7 @@ public class Authentication implements ToXContentObject {
public static final Version VERSION_API_KEY_ROLES_AS_BYTES = Version.V_7_9_0;
- private final User user; // user contains metadata
+ private final User user;
private final RealmRef authenticatedBy;
private final RealmRef lookedUpBy;
private final Version version;
@@ -70,8 +70,8 @@ public Authentication(StreamInput in) throws IOException {
this.lookedUpBy = null;
}
this.version = in.getVersion();
- this.type = AuthenticationType.values()[in.readVInt()];
- this.metadata = in.readMap();
+ type = AuthenticationType.values()[in.readVInt()];
+ metadata = in.readMap();
this.verifyApiKeyInfoAndCreateApiKeyInfoMap(); // authentication.api_key={"id":"ab12", "name":"my-key"}
}
diff --git a/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/SecurityRealmSmokeTestCase.java b/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/SecurityRealmSmokeTestCase.java
index 7cfcef6324b81..88852cde5e23e 100644
--- a/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/SecurityRealmSmokeTestCase.java
+++ b/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/SecurityRealmSmokeTestCase.java
@@ -26,7 +26,6 @@
import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.test.rest.ESRestTestCase;
import org.elasticsearch.xpack.core.security.authc.Authentication.AuthenticationType;
-import org.hamcrest.core.Every;
import org.junit.BeforeClass;
import java.io.FileNotFoundException;
@@ -37,15 +36,11 @@
import java.util.List;
import java.util.Map;
-import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.arrayContainingInAnyOrder;
-import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.equalTo;
-import static org.hamcrest.Matchers.everyItem;
import static org.hamcrest.Matchers.hasEntry;
import static org.hamcrest.Matchers.hasKey;
import static org.hamcrest.Matchers.instanceOf;
-import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
public abstract class SecurityRealmSmokeTestCase extends ESRestTestCase {
From 707c774dda522a33c07e4e05ab39a954e9684ab2 Mon Sep 17 00:00:00 2001
From: Justin Cranford
Date: Fri, 15 Oct 2021 17:56:57 -0400
Subject: [PATCH 10/25] Remove unused import. Fix long lines.
---
.../client/security/AuthenticateResponseTests.java | 9 ++++++---
.../client/security/CreateTokenResponseTests.java | 1 -
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/AuthenticateResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/AuthenticateResponseTests.java
index f53c66995f745..0d075c4b39665 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/AuthenticateResponseTests.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/AuthenticateResponseTests.java
@@ -114,7 +114,8 @@ private AuthenticateResponse mutate(AuthenticateResponse response) {
case 1:
return new AuthenticateResponse(new User(originalUser.getUsername() + "wrong", originalUser.getRoles(),
originalUser.getMetadata(), originalUser.getFullName(), originalUser.getEmail()), response.enabled(),
- response.getAuthenticationRealm(), response.getLookupRealm(), response.getAuthenticationType(), response.getToken(), response.getApiKeyInfo());
+ response.getAuthenticationRealm(), response.getLookupRealm(), response.getAuthenticationType(), response.getToken(),
+ response.getApiKeyInfo());
case 2:
final List wrongRoles = new ArrayList<>(originalUser.getRoles());
wrongRoles.add(randomAlphaOfLengthBetween(1, 4));
@@ -130,11 +131,13 @@ private AuthenticateResponse mutate(AuthenticateResponse response) {
case 4:
return new AuthenticateResponse(new User(originalUser.getUsername(), originalUser.getRoles(), originalUser.getMetadata(),
originalUser.getFullName() + "wrong", originalUser.getEmail()), response.enabled(),
- response.getAuthenticationRealm(), response.getLookupRealm(), response.getAuthenticationType(), response.getToken(), response.getApiKeyInfo());
+ response.getAuthenticationRealm(), response.getLookupRealm(), response.getAuthenticationType(), response.getToken(),
+ response.getApiKeyInfo());
case 5:
return new AuthenticateResponse(new User(originalUser.getUsername(), originalUser.getRoles(), originalUser.getMetadata(),
originalUser.getFullName(), originalUser.getEmail() + "wrong"), response.enabled(),
- response.getAuthenticationRealm(), response.getLookupRealm(), response.getAuthenticationType(), response.getToken(), response.getApiKeyInfo());
+ response.getAuthenticationRealm(), response.getLookupRealm(), response.getAuthenticationType(), response.getToken(),
+ response.getApiKeyInfo());
case 6:
return new AuthenticateResponse(new User(originalUser.getUsername(), originalUser.getRoles(), originalUser.getMetadata(),
originalUser.getFullName(), originalUser.getEmail()), response.enabled() == false, response.getAuthenticationRealm(),
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/CreateTokenResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/CreateTokenResponseTests.java
index cb390aecf2f23..f27886f5478f8 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/CreateTokenResponseTests.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/CreateTokenResponseTests.java
@@ -17,7 +17,6 @@
import java.io.IOException;
import java.util.Arrays;
-import java.util.Map;
import static org.hamcrest.Matchers.equalTo;
From 328c544dfbc25a7cdd8744a59f7481a7c91360fb Mon Sep 17 00:00:00 2001
From: Justin Cranford
Date: Wed, 20 Oct 2021 11:36:17 -0400
Subject: [PATCH 11/25] Move ApiKeyServiceFields to AuthenticationFields
---
...elegatePkiAuthenticationResponseTests.java | 10 ++--
.../xpack/core/security/SecurityContext.java | 17 ++++---
.../security/authc/ApiKeyServiceField.java | 24 ----------
.../core/security/authc/Authentication.java | 10 ++--
.../security/authc/AuthenticationField.java | 11 +++++
.../ManageOwnApiKeyClusterPrivilege.java | 4 +-
...elegatePkiAuthenticationResponseTests.java | 6 +--
.../security/authc/AuthenticationTests.java | 2 +-
.../ManageOwnApiKeyClusterPrivilegeTests.java | 6 +--
.../audit/logfile/LoggingAuditTrail.java | 8 ++--
.../xpack/security/authc/ApiKeyService.java | 47 +++++++++----------
.../security/authz/AuthorizationService.java | 4 +-
.../xpack/security/authz/RBACEngine.java | 4 +-
.../ingest/SetSecurityUserProcessor.java | 6 +--
.../xpack/security/SecurityContextTests.java | 27 +++++------
.../logfile/LoggingAuditTrailFilterTests.java | 22 ++++-----
.../audit/logfile/LoggingAuditTrailTests.java | 8 ++--
.../security/authc/ApiKeyServiceTests.java | 46 +++++++++---------
.../xpack/security/authz/RBACEngineTests.java | 12 ++---
.../authz/store/CompositeRolesStoreTests.java | 20 ++++----
.../ingest/SetSecurityUserProcessorTests.java | 26 +++++-----
21 files changed, 150 insertions(+), 170 deletions(-)
delete mode 100644 x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/ApiKeyServiceField.java
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/DelegatePkiAuthenticationResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/DelegatePkiAuthenticationResponseTests.java
index ef35d76f0b388..32ed46f0b9014 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/DelegatePkiAuthenticationResponseTests.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/DelegatePkiAuthenticationResponseTests.java
@@ -13,8 +13,8 @@
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.xcontent.XContentParser;
import org.elasticsearch.xcontent.XContentType;
-import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
import org.elasticsearch.xpack.core.security.authc.Authentication;
+import org.elasticsearch.xpack.core.security.authc.AuthenticationField;
import org.elasticsearch.xpack.core.security.user.User;
import java.io.IOException;
@@ -79,9 +79,9 @@ protected Authentication createAuthentication() {
final String nodeName = randomAlphaOfLengthBetween(1, 10);
final Authentication.AuthenticationType authenticationType = randomFrom(Authentication.AuthenticationType.values());
if (Authentication.AuthenticationType.API_KEY.equals(authenticationType)) {
- metadata.put(ApiKeyServiceField.API_KEY_ID_KEY, randomAlphaOfLengthBetween(1, 10));
+ metadata.put(AuthenticationField.API_KEY_ID_KEY, randomAlphaOfLengthBetween(1, 10));
if (randomBoolean()) {
- metadata.put(ApiKeyServiceField.API_KEY_NAME_KEY, randomAlphaOfLengthBetween(1, 10));
+ metadata.put(AuthenticationField.API_KEY_NAME_KEY, randomAlphaOfLengthBetween(1, 10));
}
}
return new Authentication(
@@ -102,8 +102,8 @@ AuthenticateResponse createServerAuthenticationResponse(Authentication authentic
authentication.getAuthenticatedBy().getType(): authentication.getLookedUpBy().getType());
final AuthenticateResponse.ApiKeyInfo apiKeyInfo;
if (Authentication.AuthenticationType.API_KEY.equals(authentication.getAuthenticationType())) {
- final String apiKeyId = (String) authentication.getMetadata().get(ApiKeyServiceField.API_KEY_ID_KEY); // mandatory
- final String apiKeyName = (String) authentication.getMetadata().get(ApiKeyServiceField.API_KEY_NAME_KEY); // optional
+ final String apiKeyId = (String) authentication.getMetadata().get(AuthenticationField.API_KEY_ID_KEY); // mandatory
+ final String apiKeyName = (String) authentication.getMetadata().get(AuthenticationField.API_KEY_NAME_KEY); // optional
apiKeyInfo = new AuthenticateResponse.ApiKeyInfo(apiKeyId, apiKeyName);
} else {
apiKeyInfo = null;
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/SecurityContext.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/SecurityContext.java
index bf08b26f76356..5838d11dd64e5 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/SecurityContext.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/SecurityContext.java
@@ -19,7 +19,6 @@
import org.elasticsearch.common.xcontent.XContentHelper;
import org.elasticsearch.xcontent.XContentType;
import org.elasticsearch.node.Node;
-import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.Authentication.AuthenticationType;
import org.elasticsearch.xpack.core.security.authc.AuthenticationField;
@@ -181,21 +180,21 @@ private Map rewriteMetadataForApiKeyRoleDescriptors(Version stre
if (authentication.getVersion().onOrAfter(VERSION_API_KEY_ROLES_AS_BYTES)
&& streamVersion.before(VERSION_API_KEY_ROLES_AS_BYTES)) {
metadata = new HashMap<>(metadata);
- metadata.put(ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY,
+ metadata.put(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY,
convertRoleDescriptorsBytesToMap(
- (BytesReference) metadata.get(ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY)));
- metadata.put(ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
+ (BytesReference) metadata.get(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY)));
+ metadata.put(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
convertRoleDescriptorsBytesToMap(
- (BytesReference) metadata.get(ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY)));
+ (BytesReference) metadata.get(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY)));
} else if (authentication.getVersion().before(VERSION_API_KEY_ROLES_AS_BYTES)
&& streamVersion.onOrAfter(VERSION_API_KEY_ROLES_AS_BYTES)) {
metadata = new HashMap<>(metadata);
- metadata.put(ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY,
+ metadata.put(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY,
convertRoleDescriptorsMapToBytes(
- (Map) metadata.get(ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY)));
- metadata.put(ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
+ (Map) metadata.get(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY)));
+ metadata.put(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
convertRoleDescriptorsMapToBytes(
- (Map) metadata.get(ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY)));
+ (Map) metadata.get(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY)));
}
}
return metadata;
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/ApiKeyServiceField.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/ApiKeyServiceField.java
deleted file mode 100644
index 594d2ec1cc77e..0000000000000
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/ApiKeyServiceField.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
- * or more contributor license agreements. Licensed under the Elastic License
- * 2.0; you may not use this file except in compliance with the Elastic License
- * 2.0.
- */
-
-package org.elasticsearch.xpack.core.security.authc;
-
-public class ApiKeyServiceField {
- public static final String API_KEY_REALM_NAME = "_es_api_key";
- public static final String API_KEY_REALM_TYPE = "_es_api_key";
-
- public static final String API_KEY_ID_KEY = "_security_api_key_id";
- public static final String API_KEY_NAME_KEY = "_security_api_key_name";
- public static final String API_KEY_METADATA_KEY = "_security_api_key_metadata";
- public static final String API_KEY_ROLE_DESCRIPTORS_KEY = "_security_api_key_role_descriptors";
- public static final String API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY = "_security_api_key_limited_by_role_descriptors";
- public static final String API_KEY_CREATOR_REALM_NAME = "_security_api_key_creator_realm_name";
- public static final String API_KEY_CREATOR_REALM_TYPE = "_security_api_key_creator_realm_type";
-
- private ApiKeyServiceField() {
- }
-}
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java
index 718fb4fd76fca..05ddc9a70a51c 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java
@@ -161,8 +161,8 @@ public void writeTo(StreamOutput out) throws IOException {
*/
public boolean canAccessResourcesOf(Authentication other) {
if (AuthenticationType.API_KEY == getAuthenticationType() && AuthenticationType.API_KEY == other.getAuthenticationType()) {
- final boolean sameKeyId = getMetadata().get(ApiKeyServiceField.API_KEY_ID_KEY)
- .equals(other.getMetadata().get(ApiKeyServiceField.API_KEY_ID_KEY));
+ final boolean sameKeyId = getMetadata().get(AuthenticationField.API_KEY_ID_KEY)
+ .equals(other.getMetadata().get(AuthenticationField.API_KEY_ID_KEY));
if (sameKeyId) {
assert getUser().principal().equals(other.getUser().principal()) :
"The same API key ID cannot be attributed to two different usernames";
@@ -266,12 +266,12 @@ public void toXContentFragment(XContentBuilder builder) throws IOException {
*/
private Map verifyApiKeyInfoAndCreateApiKeyInfoMap() throws IllegalArgumentException {
if (isApiKey()) {
- final String apiKeyId = (String) this.metadata.get(ApiKeyServiceField.API_KEY_ID_KEY);
+ final String apiKeyId = (String) this.metadata.get(AuthenticationField.API_KEY_ID_KEY);
if (apiKeyId == null) { // checks for both errors: 1) metadata.containsKey==false, 2) metadata.get==null
throw new IllegalArgumentException("If AuthenticationType=API_KEY, User metadata must contain non-null API KEY id");
}
- if (this.metadata.containsKey(ApiKeyServiceField.API_KEY_NAME_KEY)) { // handle older API KEYs where name was not mandatory
- final String apiKeyName = (String) this.metadata.get(ApiKeyServiceField.API_KEY_NAME_KEY);
+ if (this.metadata.containsKey(AuthenticationField.API_KEY_NAME_KEY)) { // handle older API KEYs where name was not mandatory
+ final String apiKeyName = (String) this.metadata.get(AuthenticationField.API_KEY_NAME_KEY);
if (apiKeyName == null) {
throw new IllegalArgumentException("If AuthenticationType=API_KEY, User metadata with API KEY name must be non-null");
}
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/AuthenticationField.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/AuthenticationField.java
index cf5a1c78ba96a..7a8ab3b5df237 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/AuthenticationField.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/AuthenticationField.java
@@ -13,5 +13,16 @@ public final class AuthenticationField {
public static final String PRIVILEGE_CATEGORY_VALUE_OPERATOR = "operator";
public static final String PRIVILEGE_CATEGORY_VALUE_EMPTY = "__empty";
+ public static final String API_KEY_REALM_NAME = "_es_api_key";
+ public static final String API_KEY_REALM_TYPE = "_es_api_key";
+
+ public static final String API_KEY_CREATOR_REALM_NAME = "_security_api_key_creator_realm_name";
+ public static final String API_KEY_CREATOR_REALM_TYPE = "_security_api_key_creator_realm_type";
+ public static final String API_KEY_ID_KEY = "_security_api_key_id";
+ public static final String API_KEY_NAME_KEY = "_security_api_key_name";
+ public static final String API_KEY_METADATA_KEY = "_security_api_key_metadata";
+ public static final String API_KEY_ROLE_DESCRIPTORS_KEY = "_security_api_key_role_descriptors";
+ public static final String API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY = "_security_api_key_limited_by_role_descriptors";
+
private AuthenticationField() {}
}
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ManageOwnApiKeyClusterPrivilege.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ManageOwnApiKeyClusterPrivilege.java
index ec05af02a8706..74848fa3670be 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ManageOwnApiKeyClusterPrivilege.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ManageOwnApiKeyClusterPrivilege.java
@@ -13,9 +13,9 @@
import org.elasticsearch.xpack.core.security.action.GetApiKeyRequest;
import org.elasticsearch.xpack.core.security.action.InvalidateApiKeyRequest;
import org.elasticsearch.xpack.core.security.action.apikey.QueryApiKeyRequest;
-import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.Authentication.AuthenticationType;
+import org.elasticsearch.xpack.core.security.authc.AuthenticationField;
import org.elasticsearch.xpack.core.security.authz.permission.ClusterPermission;
import org.elasticsearch.xpack.core.security.support.Automatons;
@@ -115,7 +115,7 @@ private boolean checkIfUserIsOwnerOfApiKeys(Authentication authentication, Strin
private boolean isCurrentAuthenticationUsingSameApiKeyIdFromRequest(Authentication authentication, String apiKeyId) {
if (AuthenticationType.API_KEY == authentication.getAuthenticationType()) {
// API key id from authentication must match the id from request
- final String authenticatedApiKeyId = (String) authentication.getMetadata().get(ApiKeyServiceField.API_KEY_ID_KEY);
+ final String authenticatedApiKeyId = (String) authentication.getMetadata().get(AuthenticationField.API_KEY_ID_KEY);
if (Strings.hasText(apiKeyId)) {
return apiKeyId.equals(authenticatedApiKeyId);
}
diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/action/DelegatePkiAuthenticationResponseTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/action/DelegatePkiAuthenticationResponseTests.java
index f3cc916c65f9a..8530a8e837d33 100644
--- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/action/DelegatePkiAuthenticationResponseTests.java
+++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/action/DelegatePkiAuthenticationResponseTests.java
@@ -16,8 +16,8 @@
import org.elasticsearch.xcontent.XContentParser;
import org.elasticsearch.test.AbstractXContentTestCase;
import org.elasticsearch.xpack.core.security.action.DelegatePkiAuthenticationResponse;
-import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
import org.elasticsearch.xpack.core.security.authc.Authentication;
+import org.elasticsearch.xpack.core.security.authc.AuthenticationField;
import org.elasticsearch.xpack.core.security.user.User;
import java.io.IOException;
@@ -138,9 +138,9 @@ public static Authentication createAuthentication() {
final String nodeName = "node_name";
final Authentication.AuthenticationType authenticationType = randomFrom(Authentication.AuthenticationType.values());
if (Authentication.AuthenticationType.API_KEY.equals(authenticationType)) {
- metadata.put(ApiKeyServiceField.API_KEY_ID_KEY, randomAlphaOfLengthBetween(1, 10));
+ metadata.put(AuthenticationField.API_KEY_ID_KEY, randomAlphaOfLengthBetween(1, 10));
if (randomBoolean()) {
- metadata.put(ApiKeyServiceField.API_KEY_NAME_KEY, randomAlphaOfLengthBetween(1, 10));
+ metadata.put(AuthenticationField.API_KEY_NAME_KEY, randomAlphaOfLengthBetween(1, 10));
}
}
return new Authentication(
diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authc/AuthenticationTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authc/AuthenticationTests.java
index 6b73356e7e8b7..e84efb8c3cce7 100644
--- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authc/AuthenticationTests.java
+++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authc/AuthenticationTests.java
@@ -186,7 +186,7 @@ public static Authentication randomApiKeyAuthentication(User user, String apiKey
null,
VersionUtils.randomVersionBetween(random(), Version.V_7_0_0, Version.CURRENT),
AuthenticationType.API_KEY,
- Map.of(ApiKeyServiceField.API_KEY_ID_KEY, apiKeyId));
+ Map.of(AuthenticationField.API_KEY_ID_KEY, apiKeyId));
}
private boolean realmIsSingleton(RealmRef realmRef) {
diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/ManageOwnApiKeyClusterPrivilegeTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/ManageOwnApiKeyClusterPrivilegeTests.java
index 3dbd61d22f789..ad6494338571a 100644
--- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/ManageOwnApiKeyClusterPrivilegeTests.java
+++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/ManageOwnApiKeyClusterPrivilegeTests.java
@@ -15,9 +15,9 @@
import org.elasticsearch.xpack.core.security.action.InvalidateApiKeyRequest;
import org.elasticsearch.xpack.core.security.action.apikey.QueryApiKeyAction;
import org.elasticsearch.xpack.core.security.action.apikey.QueryApiKeyRequest;
-import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.Authentication.AuthenticationType;
+import org.elasticsearch.xpack.core.security.authc.AuthenticationField;
import org.elasticsearch.xpack.core.security.authz.permission.ClusterPermission;
import org.elasticsearch.xpack.core.security.user.User;
@@ -35,7 +35,7 @@ public void testAuthenticationWithApiKeyAllowsAccessToApiKeyActionsWhenItIsOwner
final String apiKeyId = randomAlphaOfLengthBetween(4, 7);
final Authentication authentication = createMockAuthentication("joe", "_es_api_key",
- AuthenticationType.API_KEY, Map.of(ApiKeyServiceField.API_KEY_ID_KEY, apiKeyId));
+ AuthenticationType.API_KEY, Map.of(AuthenticationField.API_KEY_ID_KEY, apiKeyId));
final TransportRequest getApiKeyRequest = GetApiKeyRequest.usingApiKeyId(apiKeyId, randomBoolean());
final TransportRequest invalidateApiKeyRequest = InvalidateApiKeyRequest.usingApiKeyId(apiKeyId, randomBoolean());
@@ -50,7 +50,7 @@ public void testAuthenticationWithApiKeyDeniesAccessToApiKeyActionsWhenItIsNotOw
final String apiKeyId = randomAlphaOfLengthBetween(4, 7);
final Authentication authentication = createMockAuthentication("joe", "_es_api_key",
- AuthenticationType.API_KEY, Map.of(ApiKeyServiceField.API_KEY_ID_KEY, randomAlphaOfLength(7)));
+ AuthenticationType.API_KEY, Map.of(AuthenticationField.API_KEY_ID_KEY, randomAlphaOfLength(7)));
final TransportRequest getApiKeyRequest = GetApiKeyRequest.usingApiKeyId(apiKeyId, randomBoolean());
final TransportRequest invalidateApiKeyRequest = InvalidateApiKeyRequest.usingApiKeyId(apiKeyId, randomBoolean());
diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrail.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrail.java
index 239a9eeedf197..a0b24fa5cfd70 100644
--- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrail.java
+++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrail.java
@@ -71,8 +71,8 @@
import org.elasticsearch.xpack.core.security.action.user.PutUserRequest;
import org.elasticsearch.xpack.core.security.action.user.SetEnabledAction;
import org.elasticsearch.xpack.core.security.action.user.SetEnabledRequest;
-import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
import org.elasticsearch.xpack.core.security.authc.Authentication;
+import org.elasticsearch.xpack.core.security.authc.AuthenticationField;
import org.elasticsearch.xpack.core.security.authc.AuthenticationToken;
import org.elasticsearch.xpack.core.security.authc.service.ServiceAccountSettings;
import org.elasticsearch.xpack.core.security.authz.AuthorizationEngine.AuthorizationInfo;
@@ -1298,12 +1298,12 @@ LogEntryBuilder withAuthentication(Authentication authentication) {
logEntry.with(PRINCIPAL_FIELD_NAME, authentication.getUser().principal());
logEntry.with(AUTHENTICATION_TYPE_FIELD_NAME, authentication.getAuthenticationType().toString());
if (Authentication.AuthenticationType.API_KEY == authentication.getAuthenticationType()) {
- logEntry.with(API_KEY_ID_FIELD_NAME, (String) authentication.getMetadata().get(ApiKeyServiceField.API_KEY_ID_KEY));
- String apiKeyName = (String) authentication.getMetadata().get(ApiKeyServiceField.API_KEY_NAME_KEY);
+ logEntry.with(API_KEY_ID_FIELD_NAME, (String) authentication.getMetadata().get(AuthenticationField.API_KEY_ID_KEY));
+ String apiKeyName = (String) authentication.getMetadata().get(AuthenticationField.API_KEY_NAME_KEY);
if (apiKeyName != null) {
logEntry.with(API_KEY_NAME_FIELD_NAME, apiKeyName);
}
- String creatorRealmName = (String) authentication.getMetadata().get(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME);
+ String creatorRealmName = (String) authentication.getMetadata().get(AuthenticationField.API_KEY_CREATOR_REALM_NAME);
if (creatorRealmName != null) {
// can be null for API keys created before version 7.7
logEntry.with(PRINCIPAL_REALM_FIELD_NAME, creatorRealmName);
diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/ApiKeyService.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/ApiKeyService.java
index 4fb7c1239f941..7ec1269873770 100644
--- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/ApiKeyService.java
+++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/ApiKeyService.java
@@ -85,11 +85,8 @@
import org.elasticsearch.xpack.core.security.action.GetApiKeyResponse;
import org.elasticsearch.xpack.core.security.action.InvalidateApiKeyResponse;
import org.elasticsearch.xpack.core.security.action.apikey.QueryApiKeyResponse;
-import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
-import org.elasticsearch.xpack.core.security.authc.Authentication;
+import org.elasticsearch.xpack.core.security.authc.*;
import org.elasticsearch.xpack.core.security.authc.Authentication.RealmRef;
-import org.elasticsearch.xpack.core.security.authc.AuthenticationResult;
-import org.elasticsearch.xpack.core.security.authc.AuthenticationToken;
import org.elasticsearch.xpack.core.security.authc.service.ServiceAccountSettings;
import org.elasticsearch.xpack.core.security.authc.support.Hasher;
import org.elasticsearch.xpack.core.security.authz.RoleDescriptor;
@@ -391,7 +388,7 @@ public Authentication createApiKeyAuthentication(AuthenticationResult authResult
throw new IllegalArgumentException("API Key authn result must be successful");
}
final User user = authResult.getUser();
- final RealmRef authenticatedBy = new RealmRef(ApiKeyServiceField.API_KEY_REALM_NAME, ApiKeyServiceField.API_KEY_REALM_TYPE,
+ final RealmRef authenticatedBy = new RealmRef(AuthenticationField.API_KEY_REALM_NAME, AuthenticationField.API_KEY_REALM_TYPE,
nodeName);
return new Authentication(user, authenticatedBy, null, Version.CURRENT, Authentication.AuthenticationType.API_KEY,
authResult.getMetadata());
@@ -473,11 +470,11 @@ public void getRoleForApiKey(Authentication authentication, ActionListener metadata = authentication.getMetadata();
- final String apiKeyId = (String) metadata.get(ApiKeyServiceField.API_KEY_ID_KEY);
+ final String apiKeyId = (String) metadata.get(AuthenticationField.API_KEY_ID_KEY);
@SuppressWarnings("unchecked") final Map roleDescriptors =
- (Map) metadata.get(ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY);
+ (Map) metadata.get(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY);
@SuppressWarnings("unchecked") final Map authnRoleDescriptors =
- (Map) metadata.get(ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY);
+ (Map) metadata.get(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY);
if (roleDescriptors == null && authnRoleDescriptors == null) {
listener.onFailure(new ElasticsearchSecurityException("no role descriptors found for API key"));
@@ -500,14 +497,14 @@ public Tuple getApiKeyIdAndRoleBytes(Authentication auth
final Map metadata = authentication.getMetadata();
final BytesReference bytesReference = (BytesReference) metadata.get(limitedBy
- ? ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY : ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY);
+ ? AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY : AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY);
if (limitedBy && bytesReference.length() == 2 && "{}".equals(bytesReference.utf8ToString())) {
- if (ServiceAccountSettings.REALM_NAME.equals(metadata.get(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME))
+ if (ServiceAccountSettings.REALM_NAME.equals(metadata.get(AuthenticationField.API_KEY_CREATOR_REALM_NAME))
&& "elastic/fleet-server".equals(authentication.getUser().principal())) {
- return new Tuple<>((String) metadata.get(ApiKeyServiceField.API_KEY_ID_KEY), FLEET_SERVER_ROLE_DESCRIPTOR_BYTES_V_7_14);
+ return new Tuple<>((String) metadata.get(AuthenticationField.API_KEY_ID_KEY), FLEET_SERVER_ROLE_DESCRIPTOR_BYTES_V_7_14);
}
}
- return new Tuple<>((String) metadata.get(ApiKeyServiceField.API_KEY_ID_KEY), bytesReference);
+ return new Tuple<>((String) metadata.get(AuthenticationField.API_KEY_ID_KEY), bytesReference);
}
public static class ApiKeyRoleDescriptors {
@@ -696,14 +693,14 @@ void validateApiKeyExpiration(ApiKeyDoc apiKeyDoc, ApiKeyCredentials credentials
Map metadata = (Map) apiKeyDoc.creator.get("metadata");
final User apiKeyUser = new User(principal, Strings.EMPTY_ARRAY, fullName, email, metadata, true);
final Map authResultMetadata = new HashMap<>();
- authResultMetadata.put(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME, apiKeyDoc.creator.get("realm"));
- authResultMetadata.put(ApiKeyServiceField.API_KEY_CREATOR_REALM_TYPE, apiKeyDoc.creator.get("realm_type"));
- authResultMetadata.put(ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY, apiKeyDoc.roleDescriptorsBytes);
- authResultMetadata.put(ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, apiKeyDoc.limitedByRoleDescriptorsBytes);
- authResultMetadata.put(ApiKeyServiceField.API_KEY_ID_KEY, credentials.getId());
- authResultMetadata.put(ApiKeyServiceField.API_KEY_NAME_KEY, apiKeyDoc.name);
+ authResultMetadata.put(AuthenticationField.API_KEY_CREATOR_REALM_NAME, apiKeyDoc.creator.get("realm"));
+ authResultMetadata.put(AuthenticationField.API_KEY_CREATOR_REALM_TYPE, apiKeyDoc.creator.get("realm_type"));
+ authResultMetadata.put(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY, apiKeyDoc.roleDescriptorsBytes);
+ authResultMetadata.put(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, apiKeyDoc.limitedByRoleDescriptorsBytes);
+ authResultMetadata.put(AuthenticationField.API_KEY_ID_KEY, credentials.getId());
+ authResultMetadata.put(AuthenticationField.API_KEY_NAME_KEY, apiKeyDoc.name);
if (apiKeyDoc.metadataFlattened != null) {
- authResultMetadata.put(ApiKeyServiceField.API_KEY_METADATA_KEY, apiKeyDoc.metadataFlattened);
+ authResultMetadata.put(AuthenticationField.API_KEY_METADATA_KEY, apiKeyDoc.metadataFlattened);
}
listener.onResponse(AuthenticationResult.success(apiKeyUser, authResultMetadata));
} else {
@@ -750,7 +747,7 @@ ApiKeyCredentials getCredentialsFromHeader(ThreadContext threadContext) {
public static boolean isApiKeyAuthentication(Authentication authentication) {
final Authentication.AuthenticationType authType = authentication.getAuthenticationType();
if (Authentication.AuthenticationType.API_KEY == authType) {
- assert ApiKeyServiceField.API_KEY_REALM_TYPE.equals(authentication.getAuthenticatedBy().getType())
+ assert AuthenticationField.API_KEY_REALM_TYPE.equals(authentication.getAuthenticatedBy().getType())
: "API key authentication must have API key realm type";
return true;
} else {
@@ -1216,7 +1213,7 @@ AtomicLong getLastEvictionCheckedAt() {
/**
* Returns realm name for the authenticated user.
- * If the user is authenticated by realm type {@value ApiKeyServiceField#API_KEY_REALM_TYPE}
+ * If the user is authenticated by realm type {@value AuthenticationField#API_KEY_REALM_TYPE}
* then it will return the realm name of user who created this API key.
*
* @param authentication {@link Authentication}
@@ -1224,7 +1221,7 @@ AtomicLong getLastEvictionCheckedAt() {
*/
public static String getCreatorRealmName(final Authentication authentication) {
if (AuthenticationType.API_KEY == authentication.getAuthenticationType()) {
- return (String) authentication.getMetadata().get(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME);
+ return (String) authentication.getMetadata().get(AuthenticationField.API_KEY_CREATOR_REALM_NAME);
} else {
return authentication.getSourceRealm().getName();
}
@@ -1232,7 +1229,7 @@ public static String getCreatorRealmName(final Authentication authentication) {
/**
* Returns realm type for the authenticated user.
- * If the user is authenticated by realm type {@value ApiKeyServiceField#API_KEY_REALM_TYPE}
+ * If the user is authenticated by realm type {@value AuthenticationField#API_KEY_REALM_TYPE}
* then it will return the realm name of user who created this API key.
*
* @param authentication {@link Authentication}
@@ -1240,7 +1237,7 @@ public static String getCreatorRealmName(final Authentication authentication) {
*/
public static String getCreatorRealmType(final Authentication authentication) {
if (AuthenticationType.API_KEY == authentication.getAuthenticationType()) {
- return (String) authentication.getMetadata().get(ApiKeyServiceField.API_KEY_CREATOR_REALM_TYPE);
+ return (String) authentication.getMetadata().get(AuthenticationField.API_KEY_CREATOR_REALM_TYPE);
} else {
return authentication.getSourceRealm().getType();
}
@@ -1257,7 +1254,7 @@ public static Map getApiKeyMetadata(Authentication authenticatio
throw new IllegalArgumentException("authentication type must be [api_key], got ["
+ authentication.getAuthenticationType().name().toLowerCase(Locale.ROOT) + "]");
}
- final Object apiKeyMetadata = authentication.getMetadata().get(ApiKeyServiceField.API_KEY_METADATA_KEY);
+ final Object apiKeyMetadata = authentication.getMetadata().get(AuthenticationField.API_KEY_METADATA_KEY);
if (apiKeyMetadata != null) {
final Tuple> tuple =
XContentHelper.convertToMap((BytesReference) apiKeyMetadata, false, XContentType.JSON);
diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/AuthorizationService.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/AuthorizationService.java
index 6a85b0a58735f..a26f223d4bc8b 100644
--- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/AuthorizationService.java
+++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/AuthorizationService.java
@@ -49,10 +49,10 @@
import org.elasticsearch.xpack.core.security.action.user.GetUserPrivilegesResponse;
import org.elasticsearch.xpack.core.security.action.user.HasPrivilegesRequest;
import org.elasticsearch.xpack.core.security.action.user.HasPrivilegesResponse;
-import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.Authentication.AuthenticationType;
import org.elasticsearch.xpack.core.security.authc.AuthenticationFailureHandler;
+import org.elasticsearch.xpack.core.security.authc.AuthenticationField;
import org.elasticsearch.xpack.core.security.authc.esnative.ClientReservedRealm;
import org.elasticsearch.xpack.core.security.authz.AuthorizationEngine;
import org.elasticsearch.xpack.core.security.authz.AuthorizationEngine.AsyncSupplier;
@@ -721,7 +721,7 @@ private ElasticsearchSecurityException denialException(Authentication authentica
}
// check for authentication by API key
if (AuthenticationType.API_KEY == authentication.getAuthenticationType()) {
- final String apiKeyId = (String) authentication.getMetadata().get(ApiKeyServiceField.API_KEY_ID_KEY);
+ final String apiKeyId = (String) authentication.getMetadata().get(AuthenticationField.API_KEY_ID_KEY);
assert apiKeyId != null : "api key id must be present in the metadata";
userText = "API key id [" + apiKeyId + "] of " + userText;
} else if (false == authentication.isServiceAccount()) {
diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/RBACEngine.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/RBACEngine.java
index 36bde69cef326..fb11dc5badb8b 100644
--- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/RBACEngine.java
+++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/RBACEngine.java
@@ -52,9 +52,9 @@
import org.elasticsearch.xpack.core.security.action.user.HasPrivilegesRequest;
import org.elasticsearch.xpack.core.security.action.user.HasPrivilegesResponse;
import org.elasticsearch.xpack.core.security.action.user.UserRequest;
-import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.Authentication.AuthenticationType;
+import org.elasticsearch.xpack.core.security.authc.AuthenticationField;
import org.elasticsearch.xpack.core.security.authc.esnative.NativeRealmSettings;
import org.elasticsearch.xpack.core.security.authz.AuthorizationEngine;
import org.elasticsearch.xpack.core.security.authz.ResolvedIndices;
@@ -190,7 +190,7 @@ boolean checkSameUserPermissions(String action, TransportRequest request, Authen
if (AuthenticationType.API_KEY == authentication.getAuthenticationType()) {
assert authentication.getLookedUpBy() == null : "runAs not supported for api key authentication";
// if authenticated by API key then the request must also contain same API key id
- String authenticatedApiKeyId = (String) authentication.getMetadata().get(ApiKeyServiceField.API_KEY_ID_KEY);
+ String authenticatedApiKeyId = (String) authentication.getMetadata().get(AuthenticationField.API_KEY_ID_KEY);
if (Strings.hasText(getApiKeyRequest.getApiKeyId())) {
return getApiKeyRequest.getApiKeyId().equals(authenticatedApiKeyId);
} else {
diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessor.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessor.java
index dccc58cc5e690..d0e997399351c 100644
--- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessor.java
+++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessor.java
@@ -14,8 +14,8 @@
import org.elasticsearch.ingest.Processor;
import org.elasticsearch.xpack.core.XPackSettings;
import org.elasticsearch.xpack.core.security.SecurityContext;
-import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
import org.elasticsearch.xpack.core.security.authc.Authentication;
+import org.elasticsearch.xpack.core.security.authc.AuthenticationField;
import org.elasticsearch.xpack.core.security.user.User;
import org.elasticsearch.xpack.security.authc.ApiKeyService;
@@ -125,11 +125,11 @@ public IngestDocument execute(IngestDocument ingestDocument) throws Exception {
final Object existingApiKeyField = userObject.get(apiKey);
@SuppressWarnings("unchecked") final Map apiKeyField =
existingApiKeyField instanceof Map ? (Map) existingApiKeyField : new HashMap<>();
- Object apiKeyName = authentication.getMetadata().get(ApiKeyServiceField.API_KEY_NAME_KEY);
+ Object apiKeyName = authentication.getMetadata().get(AuthenticationField.API_KEY_NAME_KEY);
if (apiKeyName != null) {
apiKeyField.put("name", apiKeyName);
}
- Object apiKeyId = authentication.getMetadata().get(ApiKeyServiceField.API_KEY_ID_KEY);
+ Object apiKeyId = authentication.getMetadata().get(AuthenticationField.API_KEY_ID_KEY);
if (apiKeyId != null) {
apiKeyField.put("id", apiKeyId);
}
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityContextTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityContextTests.java
index d9d80b13933f0..b2105c2624efa 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityContextTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityContextTests.java
@@ -15,7 +15,6 @@
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.VersionUtils;
import org.elasticsearch.xpack.core.security.SecurityContext;
-import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.Authentication.AuthenticationType;
import org.elasticsearch.xpack.core.security.authc.Authentication.RealmRef;
@@ -32,8 +31,6 @@
import java.util.concurrent.atomic.AtomicReference;
import static org.elasticsearch.xpack.core.security.authc.Authentication.VERSION_API_KEY_ROLES_AS_BYTES;
-import static org.elasticsearch.xpack.core.security.authc.AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY;
-import static org.elasticsearch.xpack.core.security.authc.AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
@@ -152,10 +149,10 @@ public void testExecuteAfterRewritingAuthenticationWillConditionallyRewriteNewAp
User user = new User("test", null, new User("authUser"));
RealmRef authBy = new RealmRef("_es_api_key", "_es_api_key", "node1");
final Map metadata = Map.of(
- ApiKeyServiceField.API_KEY_ID_KEY, randomAlphaOfLengthBetween(1, 10),
- ApiKeyServiceField.API_KEY_NAME_KEY, randomAlphaOfLengthBetween(1, 10),
- ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY, new BytesArray("{\"a role\": {\"cluster\": [\"all\"]}}"),
- ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, new BytesArray("{\"limitedBy role\": {\"cluster\": [\"all\"]}}")
+ AuthenticationField.API_KEY_ID_KEY, randomAlphaOfLengthBetween(1, 10),
+ AuthenticationField.API_KEY_NAME_KEY, randomAlphaOfLengthBetween(1, 10),
+ AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY, new BytesArray("{\"a role\": {\"cluster\": [\"all\"]}}"),
+ AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, new BytesArray("{\"limitedBy role\": {\"cluster\": [\"all\"]}}")
);
final Authentication original = new Authentication(user, authBy, authBy, Version.V_8_0_0,
AuthenticationType.API_KEY, metadata);
@@ -165,9 +162,9 @@ ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, new BytesArray("{\"limi
securityContext.executeAfterRewritingAuthentication(originalCtx -> {
Authentication authentication = securityContext.getAuthentication();
assertEquals(Map.of("a role", Map.of("cluster", List.of("all"))),
- authentication.getMetadata().get(ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY));
+ authentication.getMetadata().get(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY));
assertEquals(Map.of("limitedBy role", Map.of("cluster", List.of("all"))),
- authentication.getMetadata().get(ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY));
+ authentication.getMetadata().get(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY));
}, Version.V_7_8_0);
// If target is new node, no need to rewrite the new style API key metadata
@@ -181,10 +178,10 @@ public void testExecuteAfterRewritingAuthenticationWillConditionallyRewriteOldAp
User user = new User("test", null, new User("authUser"));
RealmRef authBy = new RealmRef("_es_api_key", "_es_api_key", "node1");
final Map metadata = Map.of(
- ApiKeyServiceField.API_KEY_ID_KEY, randomAlphaOfLengthBetween(1, 10),
- ApiKeyServiceField.API_KEY_NAME_KEY, randomAlphaOfLengthBetween(1, 10),
- ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY, Map.of("a role", Map.of("cluster", List.of("all"))),
- ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, Map.of("limitedBy role", Map.of("cluster", List.of("all")))
+ AuthenticationField.API_KEY_ID_KEY, randomAlphaOfLengthBetween(1, 10),
+ AuthenticationField.API_KEY_NAME_KEY, randomAlphaOfLengthBetween(1, 10),
+ AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY, Map.of("a role", Map.of("cluster", List.of("all"))),
+ AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, Map.of("limitedBy role", Map.of("cluster", List.of("all")))
);
final Authentication original = new Authentication(user, authBy, authBy, Version.V_7_8_0, AuthenticationType.API_KEY, metadata);
original.writeToContext(threadContext);
@@ -200,10 +197,10 @@ ApiKeyServiceField.API_KEY_NAME_KEY, randomAlphaOfLengthBetween(1, 10),
Authentication authentication = securityContext.getAuthentication();
assertEquals("{\"a role\":{\"cluster\":[\"all\"]}}",
((BytesReference) authentication.getMetadata()
- .get(ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY)).utf8ToString());
+ .get(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY)).utf8ToString());
assertEquals("{\"limitedBy role\":{\"cluster\":[\"all\"]}}",
((BytesReference) authentication.getMetadata()
- .get(ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY)).utf8ToString());
+ .get(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY)).utf8ToString());
}, VersionUtils.randomVersionBetween(random(), VERSION_API_KEY_ROLES_AS_BYTES, Version.CURRENT));
}
}
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailFilterTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailFilterTests.java
index 3ea712c3e7f84..674a081e5f788 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailFilterTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailFilterTests.java
@@ -27,9 +27,9 @@
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.TransportRequest;
import org.elasticsearch.xpack.core.security.audit.logfile.CapturingLogger;
-import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.Authentication.RealmRef;
+import org.elasticsearch.xpack.core.security.authc.AuthenticationField;
import org.elasticsearch.xpack.core.security.authc.AuthenticationToken;
import org.elasticsearch.xpack.core.security.authz.AuthorizationEngine.AuthorizationInfo;
import org.elasticsearch.xpack.core.security.user.SystemUser;
@@ -933,7 +933,7 @@ public void testRealmsFilter() throws Exception {
createApiKeyAuthentication(apiKeyService, createAuthentication(user, filteredRealm));
auditTrail.accessGranted(randomAlphaOfLength(8), authentication, "_action", request, authzInfo(new String[]{"role1"}));
if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY &&
- false == authentication.getMetadata().containsKey(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME)) {
+ false == authentication.getMetadata().containsKey(AuthenticationField.API_KEY_CREATOR_REALM_NAME)) {
if (filterMissingRealm) {
assertThat("AccessGranted message: not filtered out by the missing realm filter", logOutput.size(), is(0));
} else {
@@ -949,7 +949,7 @@ public void testRealmsFilter() throws Exception {
createApiKeyAuthentication(apiKeyService, createAuthentication(user, unfilteredRealm));
auditTrail.accessGranted(randomAlphaOfLength(8), authentication, "_action", request, authzInfo(new String[]{"role1"}));
if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY &&
- false == authentication.getMetadata().containsKey(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME)) {
+ false == authentication.getMetadata().containsKey(AuthenticationField.API_KEY_CREATOR_REALM_NAME)) {
if (filterMissingRealm) {
assertThat("AccessGranted message: not filtered out by the missing realm filter", logOutput.size(), is(0));
} else {
@@ -977,7 +977,7 @@ public void testRealmsFilter() throws Exception {
createApiKeyAuthentication(apiKeyService, createAuthentication(user, filteredRealm));
auditTrail.accessGranted(randomAlphaOfLength(8), authentication, "internal:_action", request, authzInfo(new String[]{"role1"}));
if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY &&
- false == authentication.getMetadata().containsKey(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME)) {
+ false == authentication.getMetadata().containsKey(AuthenticationField.API_KEY_CREATOR_REALM_NAME)) {
if (filterMissingRealm) {
assertThat("AccessGranted internal message: not filtered out by the missing realm filter", logOutput.size(), is(0));
} else {
@@ -993,7 +993,7 @@ public void testRealmsFilter() throws Exception {
createApiKeyAuthentication(apiKeyService, createAuthentication(user, unfilteredRealm));
auditTrail.accessGranted(randomAlphaOfLength(8), authentication, "internal:_action", request, authzInfo(new String[] { "role1" }));
if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY &&
- false == authentication.getMetadata().containsKey(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME)) {
+ false == authentication.getMetadata().containsKey(AuthenticationField.API_KEY_CREATOR_REALM_NAME)) {
if (filterMissingRealm) {
assertThat("AccessGranted internal message: not filtered out by the missing realm filter", logOutput.size(), is(0));
} else {
@@ -1010,7 +1010,7 @@ public void testRealmsFilter() throws Exception {
createApiKeyAuthentication(apiKeyService, createAuthentication(user, filteredRealm));
auditTrail.accessDenied(randomAlphaOfLength(8), authentication, "_action", request, authzInfo(new String[]{"role1"}));
if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY &&
- false == authentication.getMetadata().containsKey(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME)) {
+ false == authentication.getMetadata().containsKey(AuthenticationField.API_KEY_CREATOR_REALM_NAME)) {
if (filterMissingRealm) {
assertThat("AccessDenied message: not filtered out by the missing realm filter", logOutput.size(), is(0));
} else {
@@ -1026,7 +1026,7 @@ public void testRealmsFilter() throws Exception {
createApiKeyAuthentication(apiKeyService, createAuthentication(user, unfilteredRealm));
auditTrail.accessDenied(randomAlphaOfLength(8), authentication, "_action", request, authzInfo(new String[]{"role1"}));
if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY &&
- false == authentication.getMetadata().containsKey(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME)) {
+ false == authentication.getMetadata().containsKey(AuthenticationField.API_KEY_CREATOR_REALM_NAME)) {
if (filterMissingRealm) {
assertThat("AccessDenied message: not filtered out by the missing realm filter", logOutput.size(), is(0));
} else {
@@ -1054,7 +1054,7 @@ public void testRealmsFilter() throws Exception {
createApiKeyAuthentication(apiKeyService, createAuthentication(user, filteredRealm));
auditTrail.accessDenied(randomAlphaOfLength(8), authentication, "internal:_action", request, authzInfo(new String[]{"role1"}));
if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY &&
- false == authentication.getMetadata().containsKey(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME)) {
+ false == authentication.getMetadata().containsKey(AuthenticationField.API_KEY_CREATOR_REALM_NAME)) {
if (filterMissingRealm) {
assertThat("AccessDenied internal message: not filtered out by the missing realm filter", logOutput.size(), is(0));
} else {
@@ -1071,7 +1071,7 @@ public void testRealmsFilter() throws Exception {
auditTrail.accessDenied(randomAlphaOfLength(8), authentication, "internal:_action",
request, authzInfo(new String[]{"role1"}));
if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY &&
- false == authentication.getMetadata().containsKey(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME)) {
+ false == authentication.getMetadata().containsKey(AuthenticationField.API_KEY_CREATOR_REALM_NAME)) {
if (filterMissingRealm) {
assertThat("AccessDenied internal message: not filtered out by the missing realm filter", logOutput.size(), is(0));
} else {
@@ -1106,7 +1106,7 @@ public void testRealmsFilter() throws Exception {
createApiKeyAuthentication(apiKeyService, createAuthentication(user, filteredRealm));
auditTrail.tamperedRequest(randomAlphaOfLength(8), authentication, "_action", request);
if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY &&
- false == authentication.getMetadata().containsKey(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME)) {
+ false == authentication.getMetadata().containsKey(AuthenticationField.API_KEY_CREATOR_REALM_NAME)) {
if (filterMissingRealm) {
assertThat("Tampered message: not filtered out by the missing realm filter", logOutput.size(), is(0));
} else {
@@ -1122,7 +1122,7 @@ public void testRealmsFilter() throws Exception {
createApiKeyAuthentication(apiKeyService, createAuthentication(user, unfilteredRealm));
auditTrail.tamperedRequest(randomAlphaOfLength(8), authentication, "_action", request);
if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY &&
- false == authentication.getMetadata().containsKey(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME)) {
+ false == authentication.getMetadata().containsKey(AuthenticationField.API_KEY_CREATOR_REALM_NAME)) {
if (filterMissingRealm) {
assertThat("Tampered message: not filtered out by the missing realm filter", logOutput.size(), is(0));
} else {
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailTests.java
index 80f341399c6c2..68c2cf752f165 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailTests.java
@@ -76,10 +76,10 @@
import org.elasticsearch.xpack.core.security.action.user.SetEnabledAction;
import org.elasticsearch.xpack.core.security.action.user.SetEnabledRequest;
import org.elasticsearch.xpack.core.security.audit.logfile.CapturingLogger;
-import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.Authentication.AuthenticationType;
import org.elasticsearch.xpack.core.security.authc.Authentication.RealmRef;
+import org.elasticsearch.xpack.core.security.authc.AuthenticationField;
import org.elasticsearch.xpack.core.security.authc.AuthenticationToken;
import org.elasticsearch.xpack.core.security.authc.service.ServiceAccountSettings;
import org.elasticsearch.xpack.core.security.authc.support.mapper.TemplateRoleName;
@@ -2416,12 +2416,12 @@ private static void authentication(Authentication authentication, MapBuilder();
@@ -464,10 +464,10 @@ public void testValidateApiKey() throws Exception {
assertThat(result.getUser().email(), is("test@user.com"));
assertThat(result.getUser().roles(), is(emptyArray()));
assertThat(result.getUser().metadata(), is(Collections.emptyMap()));
- assertThat(result.getMetadata().get(ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY), equalTo(apiKeyDoc.roleDescriptorsBytes));
- assertThat(result.getMetadata().get(ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY),
+ assertThat(result.getMetadata().get(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY), equalTo(apiKeyDoc.roleDescriptorsBytes));
+ assertThat(result.getMetadata().get(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY),
equalTo(apiKeyDoc.limitedByRoleDescriptorsBytes));
- assertThat(result.getMetadata().get(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME), is("realm1"));
+ assertThat(result.getMetadata().get(AuthenticationField.API_KEY_CREATOR_REALM_NAME), is("realm1"));
apiKeyDoc = buildApiKeyDoc(hash, Clock.systemUTC().instant().minus(1L, ChronoUnit.HOURS).toEpochMilli(), false);
future = new PlainActionFuture<>();
@@ -502,10 +502,10 @@ public void testGetRolesForApiKeyNotInContext() throws Exception {
false);
}
Map authMetadata = new HashMap<>();
- authMetadata.put(ApiKeyServiceField.API_KEY_ID_KEY, randomAlphaOfLength(12));
- authMetadata.put(ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY,
+ authMetadata.put(AuthenticationField.API_KEY_ID_KEY, randomAlphaOfLength(12));
+ authMetadata.put(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY,
Collections.singletonMap(SUPERUSER_ROLE_DESCRIPTOR.getName(), superUserRdMap));
- authMetadata.put(ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
+ authMetadata.put(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
Collections.singletonMap(SUPERUSER_ROLE_DESCRIPTOR.getName(), superUserRdMap));
final Authentication authentication = new Authentication(new User("joe"), new RealmRef("apikey", "apikey", "node"), null,
@@ -523,7 +523,7 @@ public void testGetRolesForApiKeyNotInContext() throws Exception {
@SuppressWarnings("unchecked")
public void testGetRolesForApiKey() throws Exception {
Map authMetadata = new HashMap<>();
- authMetadata.put(ApiKeyServiceField.API_KEY_ID_KEY, randomAlphaOfLength(12));
+ authMetadata.put(AuthenticationField.API_KEY_ID_KEY, randomAlphaOfLength(12));
boolean emptyApiKeyRoleDescriptor = randomBoolean();
final RoleDescriptor roleARoleDescriptor = new RoleDescriptor("a role", new String[] { "monitor" },
new RoleDescriptor.IndicesPrivileges[] {
@@ -534,7 +534,7 @@ public void testGetRolesForApiKey() throws Exception {
roleARDMap = XContentHelper.convertToMap(XContentType.JSON.xContent(),
BytesReference.bytes(roleARoleDescriptor.toXContent(builder, ToXContent.EMPTY_PARAMS, true)).streamInput(), false);
}
- authMetadata.put(ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY,
+ authMetadata.put(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY,
(emptyApiKeyRoleDescriptor) ? randomFrom(Arrays.asList(null, Collections.emptyMap()))
: Collections.singletonMap("a role", roleARDMap));
@@ -550,7 +550,7 @@ public void testGetRolesForApiKey() throws Exception {
.streamInput(),
false);
}
- authMetadata.put(ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, Collections.singletonMap("limited role", limitedRdMap));
+ authMetadata.put(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, Collections.singletonMap("limited role", limitedRdMap));
final Authentication authentication = new Authentication(new User("joe"), new RealmRef("apikey", "apikey", "node"), null,
VersionUtils.randomVersionBetween(random(), Version.V_7_0_0, Version.V_7_8_1),
@@ -586,11 +586,11 @@ public void testGetRolesForApiKey() throws Exception {
public void testGetApiKeyIdAndRoleBytes() {
Map authMetadata = new HashMap<>();
final String apiKeyId = randomAlphaOfLength(12);
- authMetadata.put(ApiKeyServiceField.API_KEY_ID_KEY, apiKeyId);
+ authMetadata.put(AuthenticationField.API_KEY_ID_KEY, apiKeyId);
final BytesReference roleBytes = new BytesArray("{\"a role\": {\"cluster\": [\"all\"]}}");
final BytesReference limitedByRoleBytes = new BytesArray("{\"limitedBy role\": {\"cluster\": [\"all\"]}}");
- authMetadata.put(ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY, roleBytes);
- authMetadata.put(ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, limitedByRoleBytes);
+ authMetadata.put(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY, roleBytes);
+ authMetadata.put(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, limitedByRoleBytes);
final Authentication authentication = new Authentication(new User("joe"), new RealmRef("apikey", "apikey", "node"), null,
Version.CURRENT, AuthenticationType.API_KEY, authMetadata);
@@ -1292,14 +1292,14 @@ public static Authentication createApiKeyAuthentication(ApiKeyService apiKeyServ
// maybe remove realm name to simulate old API Key authentication
assert authenticationResult.getStatus() == AuthenticationResult.Status.SUCCESS;
Map authenticationResultMetadata = new HashMap<>(authenticationResult.getMetadata());
- authenticationResultMetadata.remove(ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME);
+ authenticationResultMetadata.remove(AuthenticationField.API_KEY_CREATOR_REALM_NAME);
authenticationResult = AuthenticationResult.success(authenticationResult.getUser(), authenticationResultMetadata);
}
if (randomBoolean()) {
// simulate authentication with nameless API Key, see https://github.com/elastic/elasticsearch/issues/59484
assert authenticationResult.getStatus() == AuthenticationResult.Status.SUCCESS;
Map authenticationResultMetadata = new HashMap<>(authenticationResult.getMetadata());
- authenticationResultMetadata.remove(ApiKeyServiceField.API_KEY_NAME_KEY);
+ authenticationResultMetadata.remove(AuthenticationField.API_KEY_NAME_KEY);
authenticationResult = AuthenticationResult.success(authenticationResult.getUser(), authenticationResultMetadata);
}
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/RBACEngineTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/RBACEngineTests.java
index b1c3fd4a2ce06..5d8259c5d5c3e 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/RBACEngineTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/RBACEngineTests.java
@@ -46,9 +46,9 @@
import org.elasticsearch.xpack.core.security.action.user.HasPrivilegesResponse;
import org.elasticsearch.xpack.core.security.action.user.PutUserAction;
import org.elasticsearch.xpack.core.security.action.user.UserRequest;
-import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.Authentication.AuthenticationType;
+import org.elasticsearch.xpack.core.security.authc.AuthenticationField;
import org.elasticsearch.xpack.core.security.authc.esnative.NativeRealmSettings;
import org.elasticsearch.xpack.core.security.authc.file.FileRealmSettings;
import org.elasticsearch.xpack.core.security.authc.ldap.LdapRealmSettings;
@@ -246,7 +246,7 @@ public void testSameUserPermissionDoesNotAllowChangePasswordForApiKey() {
when(authentication.getUser()).thenReturn(user);
when(authentication.getAuthenticatedBy()).thenReturn(authenticatedBy);
when(authentication.getAuthenticationType()).thenReturn(Authentication.AuthenticationType.API_KEY);
- when(authenticatedBy.getType()).thenReturn(ApiKeyServiceField.API_KEY_REALM_TYPE);
+ when(authenticatedBy.getType()).thenReturn(AuthenticationField.API_KEY_REALM_TYPE);
assertThat(request, instanceOf(UserRequest.class));
assertFalse(engine.checkSameUserPermissions(action, request, authentication));
@@ -311,7 +311,7 @@ public void testSameUserPermissionAllowsSelfApiKeyInfoRetrievalWhenAuthenticated
when(authentication.getUser()).thenReturn(user);
when(authentication.getAuthenticatedBy()).thenReturn(authenticatedBy);
when(authentication.getAuthenticationType()).thenReturn(AuthenticationType.API_KEY);
- when(authentication.getMetadata()).thenReturn(Map.of(ApiKeyServiceField.API_KEY_ID_KEY, apiKeyId));
+ when(authentication.getMetadata()).thenReturn(Map.of(AuthenticationField.API_KEY_ID_KEY, apiKeyId));
assertTrue(engine.checkSameUserPermissions(GetApiKeyAction.NAME, request, authentication));
}
@@ -324,8 +324,8 @@ public void testSameUserPermissionDeniesApiKeyInfoRetrievalWhenAuthenticatedByAD
final Authentication.RealmRef authenticatedBy = mock(Authentication.RealmRef.class);
when(authentication.getUser()).thenReturn(user);
when(authentication.getAuthenticatedBy()).thenReturn(authenticatedBy);
- when(authenticatedBy.getType()).thenReturn(ApiKeyServiceField.API_KEY_REALM_TYPE);
- when(authentication.getMetadata()).thenReturn(Map.of(ApiKeyServiceField.API_KEY_ID_KEY, randomAlphaOfLengthBetween(4, 7)));
+ when(authenticatedBy.getType()).thenReturn(AuthenticationField.API_KEY_REALM_TYPE);
+ when(authentication.getMetadata()).thenReturn(Map.of(AuthenticationField.API_KEY_ID_KEY, randomAlphaOfLengthBetween(4, 7)));
assertFalse(engine.checkSameUserPermissions(GetApiKeyAction.NAME, request, authentication));
}
@@ -341,7 +341,7 @@ public void testSameUserPermissionDeniesApiKeyInfoRetrievalWhenLookedupByIsPrese
when(authentication.getAuthenticatedBy()).thenReturn(authenticatedBy);
when(authentication.getLookedUpBy()).thenReturn(lookedupBy);
when(authentication.getAuthenticationType()).thenReturn(AuthenticationType.API_KEY);
- when(authentication.getMetadata()).thenReturn(Map.of(ApiKeyServiceField.API_KEY_ID_KEY, randomAlphaOfLengthBetween(4, 7)));
+ when(authentication.getMetadata()).thenReturn(Map.of(AuthenticationField.API_KEY_ID_KEY, randomAlphaOfLengthBetween(4, 7)));
final AssertionError assertionError = expectThrows(AssertionError.class, () -> engine.checkSameUserPermissions(GetApiKeyAction.NAME,
request, authentication));
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java
index 042e8bb419806..830fa0c9b929c 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java
@@ -49,10 +49,10 @@
import org.elasticsearch.xpack.core.XPackSettings;
import org.elasticsearch.xpack.core.security.action.saml.SamlAuthenticateAction;
import org.elasticsearch.xpack.core.security.action.user.PutUserAction;
-import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.Authentication.AuthenticationType;
import org.elasticsearch.xpack.core.security.authc.Authentication.RealmRef;
+import org.elasticsearch.xpack.core.security.authc.AuthenticationField;
import org.elasticsearch.xpack.core.security.authz.RoleDescriptor;
import org.elasticsearch.xpack.core.security.authz.RoleDescriptor.IndicesPrivileges;
import org.elasticsearch.xpack.core.security.authz.accesscontrol.DocumentSubsetBitsetCache;
@@ -1374,11 +1374,11 @@ public void testCacheEntryIsReusedForIdenticalApiKeyRoles() {
null,
Version.CURRENT,
AuthenticationType.API_KEY,
- Map.of(ApiKeyServiceField.API_KEY_ID_KEY,
+ Map.of(AuthenticationField.API_KEY_ID_KEY,
"key-id-1",
- ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY,
+ AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY,
roleBytes,
- ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
+ AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
limitedByRoleBytes));
doCallRealMethod().when(apiKeyService).getApiKeyIdAndRoleBytes(eq(authentication), anyBoolean());
@@ -1396,11 +1396,11 @@ public void testCacheEntryIsReusedForIdenticalApiKeyRoles() {
null,
Version.CURRENT,
AuthenticationType.API_KEY,
- Map.of(ApiKeyServiceField.API_KEY_ID_KEY,
+ Map.of(AuthenticationField.API_KEY_ID_KEY,
"key-id-2",
- ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY,
+ AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY,
roleBytes,
- ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
+ AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
limitedByRoleBytes));
doCallRealMethod().when(apiKeyService).getApiKeyIdAndRoleBytes(eq(authentication), anyBoolean());
roleFuture = new PlainActionFuture<>();
@@ -1417,11 +1417,11 @@ public void testCacheEntryIsReusedForIdenticalApiKeyRoles() {
null,
Version.CURRENT,
AuthenticationType.API_KEY,
- Map.of(ApiKeyServiceField.API_KEY_ID_KEY,
+ Map.of(AuthenticationField.API_KEY_ID_KEY,
"key-id-3",
- ApiKeyServiceField.API_KEY_ROLE_DESCRIPTORS_KEY,
+ AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY,
anotherRoleBytes,
- ApiKeyServiceField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
+ AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
limitedByRoleBytes));
doCallRealMethod().when(apiKeyService).getApiKeyIdAndRoleBytes(eq(authentication), anyBoolean());
roleFuture = new PlainActionFuture<>();
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessorTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessorTests.java
index 1564a8f0b344c..671e5a3aed6b6 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessorTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessorTests.java
@@ -18,9 +18,9 @@
import org.elasticsearch.xpack.core.security.SecurityContext;
import org.elasticsearch.xpack.core.security.action.ApiKeyTests;
import org.elasticsearch.xpack.core.security.action.service.TokenInfo;
-import org.elasticsearch.xpack.core.security.authc.ApiKeyServiceField;
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.Authentication.AuthenticationType;
+import org.elasticsearch.xpack.core.security.authc.AuthenticationField;
import org.elasticsearch.xpack.core.security.authc.support.AuthenticationContextSerializer;
import org.elasticsearch.xpack.core.security.support.ValidationTests;
import org.elasticsearch.xpack.core.security.user.User;
@@ -249,17 +249,17 @@ public void testOverwriteExistingField() throws Exception {
public void testApiKeyPopulation() throws Exception {
User user = new User(randomAlphaOfLengthBetween(4, 12), null, null);
Authentication.RealmRef realmRef = new Authentication.RealmRef(
- ApiKeyServiceField.API_KEY_REALM_NAME, ApiKeyServiceField.API_KEY_REALM_TYPE, "_node_name");
+ AuthenticationField.API_KEY_REALM_NAME, AuthenticationField.API_KEY_REALM_TYPE, "_node_name");
final Map authMetadata = new HashMap<>(Map.of(
- ApiKeyServiceField.API_KEY_ID_KEY, "api_key_id",
- ApiKeyServiceField.API_KEY_NAME_KEY, "api_key_name",
- ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME, "creator_realm_name",
- ApiKeyServiceField.API_KEY_CREATOR_REALM_TYPE, "creator_realm_type"
+ AuthenticationField.API_KEY_ID_KEY, "api_key_id",
+ AuthenticationField.API_KEY_NAME_KEY, "api_key_name",
+ AuthenticationField.API_KEY_CREATOR_REALM_NAME, "creator_realm_name",
+ AuthenticationField.API_KEY_CREATOR_REALM_TYPE, "creator_realm_type"
));
final Map apiKeyMetadata = ApiKeyTests.randomMetadata();
if (apiKeyMetadata != null) {
- authMetadata.put(ApiKeyServiceField.API_KEY_METADATA_KEY,
+ authMetadata.put(AuthenticationField.API_KEY_METADATA_KEY,
XContentTestUtils.convertToXContent(apiKeyMetadata, XContentType.JSON));
}
@@ -291,17 +291,17 @@ public void testApiKeyPopulation() throws Exception {
public void testWillNotOverwriteExistingApiKeyAndRealm() throws Exception {
User user = new User(randomAlphaOfLengthBetween(4, 12), null, null);
Authentication.RealmRef realmRef = new Authentication.RealmRef(
- ApiKeyServiceField.API_KEY_REALM_NAME, ApiKeyServiceField.API_KEY_REALM_TYPE, "_node_name");
+ AuthenticationField.API_KEY_REALM_NAME, AuthenticationField.API_KEY_REALM_TYPE, "_node_name");
final Map authMetadata = new HashMap<>(Map.of(
- ApiKeyServiceField.API_KEY_ID_KEY, "api_key_id",
- ApiKeyServiceField.API_KEY_NAME_KEY, "api_key_name",
- ApiKeyServiceField.API_KEY_CREATOR_REALM_NAME, "creator_realm_name",
- ApiKeyServiceField.API_KEY_CREATOR_REALM_TYPE, "creator_realm_type"
+ AuthenticationField.API_KEY_ID_KEY, "api_key_id",
+ AuthenticationField.API_KEY_NAME_KEY, "api_key_name",
+ AuthenticationField.API_KEY_CREATOR_REALM_NAME, "creator_realm_name",
+ AuthenticationField.API_KEY_CREATOR_REALM_TYPE, "creator_realm_type"
));
final Map apiKeyMetadata = ApiKeyTests.randomMetadata();
if (apiKeyMetadata != null) {
- authMetadata.put(ApiKeyServiceField.API_KEY_METADATA_KEY,
+ authMetadata.put(AuthenticationField.API_KEY_METADATA_KEY,
XContentTestUtils.convertToXContent(apiKeyMetadata, XContentType.JSON));
}
From 82d3f8fdf567169d8b74f3313b845a3f76c5f080 Mon Sep 17 00:00:00 2001
From: Justin Cranford
Date: Wed, 20 Oct 2021 12:17:30 -0400
Subject: [PATCH 12/25] Fix refactoring. It mixed single+wildcard imports.
---
.../elasticsearch/xpack/security/authc/ApiKeyService.java | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/ApiKeyService.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/ApiKeyService.java
index 7ec1269873770..b6c1430e63994 100644
--- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/ApiKeyService.java
+++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/ApiKeyService.java
@@ -85,8 +85,11 @@
import org.elasticsearch.xpack.core.security.action.GetApiKeyResponse;
import org.elasticsearch.xpack.core.security.action.InvalidateApiKeyResponse;
import org.elasticsearch.xpack.core.security.action.apikey.QueryApiKeyResponse;
-import org.elasticsearch.xpack.core.security.authc.*;
+import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.Authentication.RealmRef;
+import org.elasticsearch.xpack.core.security.authc.AuthenticationField;
+import org.elasticsearch.xpack.core.security.authc.AuthenticationResult;
+import org.elasticsearch.xpack.core.security.authc.AuthenticationToken;
import org.elasticsearch.xpack.core.security.authc.service.ServiceAccountSettings;
import org.elasticsearch.xpack.core.security.authc.support.Hasher;
import org.elasticsearch.xpack.core.security.authz.RoleDescriptor;
From 3f98ccd602d3614e7db67fa672b5ddce10757f47 Mon Sep 17 00:00:00 2001
From: Justin Cranford
Date: Wed, 20 Oct 2021 17:30:35 -0400
Subject: [PATCH 13/25] Resolve PR comments.
---
.../core/security/authc/Authentication.java | 34 +++++++++++--------
1 file changed, 19 insertions(+), 15 deletions(-)
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java
index 05ddc9a70a51c..eee98ebb5bdb4 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java
@@ -58,7 +58,8 @@ public Authentication(User user, RealmRef authenticatedBy, RealmRef lookedUpBy,
this.version = version;
this.type = type;
this.metadata = metadata;
- this.verifyApiKeyInfoAndCreateApiKeyInfoMap(); // authentication.api_key={"id":"ab12", "name":"my-key"}
+ assert this.metadata.get(AuthenticationField.API_KEY_ID_KEY) != null; // always present, never null
+ assert this.metadata.containsKey(AuthenticationField.API_KEY_ID_KEY); // always present, null for old keys
}
public Authentication(StreamInput in) throws IOException {
@@ -72,7 +73,8 @@ public Authentication(StreamInput in) throws IOException {
this.version = in.getVersion();
type = AuthenticationType.values()[in.readVInt()];
metadata = in.readMap();
- this.verifyApiKeyInfoAndCreateApiKeyInfoMap(); // authentication.api_key={"id":"ab12", "name":"my-key"}
+ assert this.metadata.get(AuthenticationField.API_KEY_ID_KEY) != null; // always present, never null
+ assert this.metadata.containsKey(AuthenticationField.API_KEY_ID_KEY); // always present, null for old keys
}
public User getUser() {
@@ -254,7 +256,21 @@ public void toXContentFragment(XContentBuilder builder) throws IOException {
builder.endObject();
builder.field(User.Fields.AUTHENTICATION_TYPE.getPreferredName(), getAuthenticationType().name().toLowerCase(Locale.ROOT));
if (isApiKey()) {
- builder.field("api_key", verifyApiKeyInfoAndCreateApiKeyInfoMap()); // authentication.api_key={"id":"ab12", "name":"my-key"}
+ final String apiKeyId = (String) this.metadata.get(AuthenticationField.API_KEY_ID_KEY);
+ final String apiKeyName = (String) this.metadata.get(AuthenticationField.API_KEY_NAME_KEY);
+ if (apiKeyId == null) {
+ if (apiKeyName == null) {
+ builder.field("api_key", Collections.emptyMap());
+ } else {
+ builder.field("api_key", Map.of("name", apiKeyName));
+ }
+ } else {
+ if (apiKeyName == null) {
+ builder.field("api_key", Map.of("id", apiKeyId));
+ } else {
+ builder.field("api_key", Map.of("id", apiKeyId, "name", apiKeyName));
+ }
+ }
}
}
@@ -266,18 +282,6 @@ public void toXContentFragment(XContentBuilder builder) throws IOException {
*/
private Map verifyApiKeyInfoAndCreateApiKeyInfoMap() throws IllegalArgumentException {
if (isApiKey()) {
- final String apiKeyId = (String) this.metadata.get(AuthenticationField.API_KEY_ID_KEY);
- if (apiKeyId == null) { // checks for both errors: 1) metadata.containsKey==false, 2) metadata.get==null
- throw new IllegalArgumentException("If AuthenticationType=API_KEY, User metadata must contain non-null API KEY id");
- }
- if (this.metadata.containsKey(AuthenticationField.API_KEY_NAME_KEY)) { // handle older API KEYs where name was not mandatory
- final String apiKeyName = (String) this.metadata.get(AuthenticationField.API_KEY_NAME_KEY);
- if (apiKeyName == null) {
- throw new IllegalArgumentException("If AuthenticationType=API_KEY, User metadata with API KEY name must be non-null");
- }
- return Map.of("id", apiKeyId, "name", apiKeyName); // newer API KEYs include name
- }
- return Map.of("id", apiKeyId); // older API KEYs lack name
}
return null;
}
From 2f0bee86af3e25bc095d32b432153d6b4d0504df Mon Sep 17 00:00:00 2001
From: Justin Cranford
Date: Thu, 21 Oct 2021 11:31:06 -0400
Subject: [PATCH 14/25] Re-add public constructors.
---
.../client/security/AuthenticateResponse.java | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/AuthenticateResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/AuthenticateResponse.java
index f5f17922371f4..3c3abc8666d94 100644
--- a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/AuthenticateResponse.java
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/AuthenticateResponse.java
@@ -87,7 +87,17 @@ public final class AuthenticateResponse implements ToXContentObject {
@Nullable
private final Map token;
@Nullable
- private final ApiKeyInfo apikeyinfo; // authentication.api_key={"id":"abc123","name":"my-api-key"}
+ private final ApiKeyInfo apikeyinfo;
+
+ public AuthenticateResponse(User user, boolean enabled, RealmInfo authenticationRealm,
+ RealmInfo lookupRealm, String authenticationType) {
+ this(user, enabled, authenticationRealm, lookupRealm, authenticationType, null);
+ }
+
+ public AuthenticateResponse(User user, boolean enabled, RealmInfo authenticationRealm,
+ RealmInfo lookupRealm, String authenticationType, @Nullable Map token) {
+ this(user, enabled, authenticationRealm, lookupRealm, authenticationType, null, null);
+ }
public AuthenticateResponse(User user, boolean enabled, RealmInfo authenticationRealm,
RealmInfo lookupRealm, String authenticationType, @Nullable Map token,
From 036a753607574a2d919ae4acd44e6a60ac6dfc77 Mon Sep 17 00:00:00 2001
From: Justin Cranford
Date: Thu, 21 Oct 2021 11:32:56 -0400
Subject: [PATCH 15/25] Guard assertions with authentication type check.
Add a brief message to show when the assertions trip.
Change second assertion from ID to NAME.
---
.../xpack/core/security/authc/Authentication.java | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java
index eee98ebb5bdb4..eb2e7c74b2461 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java
@@ -58,8 +58,7 @@ public Authentication(User user, RealmRef authenticatedBy, RealmRef lookedUpBy,
this.version = version;
this.type = type;
this.metadata = metadata;
- assert this.metadata.get(AuthenticationField.API_KEY_ID_KEY) != null; // always present, never null
- assert this.metadata.containsKey(AuthenticationField.API_KEY_ID_KEY); // always present, null for old keys
+ this.assertApiKeyMetadata();
}
public Authentication(StreamInput in) throws IOException {
@@ -73,8 +72,14 @@ public Authentication(StreamInput in) throws IOException {
this.version = in.getVersion();
type = AuthenticationType.values()[in.readVInt()];
metadata = in.readMap();
- assert this.metadata.get(AuthenticationField.API_KEY_ID_KEY) != null; // always present, never null
- assert this.metadata.containsKey(AuthenticationField.API_KEY_ID_KEY); // always present, null for old keys
+ this.assertApiKeyMetadata();
+ }
+
+ private void assertApiKeyMetadata() {
+ assert (AuthenticationType.API_KEY.equals(this.type)) && (this.metadata.get(AuthenticationField.API_KEY_ID_KEY) != null)
+ : "API KEY authentication requires metadata to contain API KEY id, and the value must be non-null.";
+ assert (AuthenticationType.API_KEY.equals(this.type)) && (this.metadata.containsKey(AuthenticationField.API_KEY_NAME_KEY))
+ : "API KEY authentication requires metadata to contain API KEY name; the value may be null for older keys.";
}
public User getUser() {
From 2c7d898e05757feaace2b70dbc93798fa82da31e Mon Sep 17 00:00:00 2001
From: Justin Cranford
Date: Thu, 21 Oct 2021 11:48:53 -0400
Subject: [PATCH 16/25] Re-add asserts to simplify production null checks.
---
.../core/security/authc/Authentication.java | 39 +++++--------------
1 file changed, 10 insertions(+), 29 deletions(-)
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java
index eb2e7c74b2461..a0515a145d1c8 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java
@@ -75,13 +75,6 @@ public Authentication(StreamInput in) throws IOException {
this.assertApiKeyMetadata();
}
- private void assertApiKeyMetadata() {
- assert (AuthenticationType.API_KEY.equals(this.type)) && (this.metadata.get(AuthenticationField.API_KEY_ID_KEY) != null)
- : "API KEY authentication requires metadata to contain API KEY id, and the value must be non-null.";
- assert (AuthenticationType.API_KEY.equals(this.type)) && (this.metadata.containsKey(AuthenticationField.API_KEY_NAME_KEY))
- : "API KEY authentication requires metadata to contain API KEY name; the value may be null for older keys.";
- }
-
public User getUser() {
return user;
}
@@ -261,34 +254,22 @@ public void toXContentFragment(XContentBuilder builder) throws IOException {
builder.endObject();
builder.field(User.Fields.AUTHENTICATION_TYPE.getPreferredName(), getAuthenticationType().name().toLowerCase(Locale.ROOT));
if (isApiKey()) {
- final String apiKeyId = (String) this.metadata.get(AuthenticationField.API_KEY_ID_KEY);
+ this.assertApiKeyMetadata();
+ final String apiKeyId = (String) this.metadata.get(AuthenticationField.API_KEY_ID_KEY);
final String apiKeyName = (String) this.metadata.get(AuthenticationField.API_KEY_NAME_KEY);
- if (apiKeyId == null) {
- if (apiKeyName == null) {
- builder.field("api_key", Collections.emptyMap());
- } else {
- builder.field("api_key", Map.of("name", apiKeyName));
- }
+ if (apiKeyName == null) {
+ builder.field("api_key", Map.of("id", apiKeyId));
} else {
- if (apiKeyName == null) {
- builder.field("api_key", Map.of("id", apiKeyId));
- } else {
- builder.field("api_key", Map.of("id", apiKeyId, "name", apiKeyName));
- }
+ builder.field("api_key", Map.of("id", apiKeyId, "name", apiKeyName));
}
}
}
- /**
- * If authenticationType=API_KEY then validate and return API KEY info map, otherwise return null map.
- *
- * @return Map of API KEY info, or null for other authentication types.
- * @throws IllegalArgumentException Error if API KEY id is missing or null, or if API KEY name present but null.
- */
- private Map verifyApiKeyInfoAndCreateApiKeyInfoMap() throws IllegalArgumentException {
- if (isApiKey()) {
- }
- return null;
+ private void assertApiKeyMetadata() {
+ assert (AuthenticationType.API_KEY.equals(this.type)) && (this.metadata.get(AuthenticationField.API_KEY_ID_KEY) != null)
+ : "API KEY authentication requires metadata to contain API KEY id, and the value must be non-null.";
+ assert (AuthenticationType.API_KEY.equals(this.type)) && (this.metadata.containsKey(AuthenticationField.API_KEY_NAME_KEY))
+ : "API KEY authentication requires metadata to contain API KEY name; the value may be null for older keys.";
}
@Override
From 015822ed46b388ccffddf0b5c46364b96ab78b7b Mon Sep 17 00:00:00 2001
From: Justin Cranford
Date: Thu, 21 Oct 2021 15:24:46 -0400
Subject: [PATCH 17/25] Fix assertions.
---
.../xpack/core/security/authc/Authentication.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java
index a0515a145d1c8..4c0eb96c39932 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/Authentication.java
@@ -266,9 +266,9 @@ public void toXContentFragment(XContentBuilder builder) throws IOException {
}
private void assertApiKeyMetadata() {
- assert (AuthenticationType.API_KEY.equals(this.type)) && (this.metadata.get(AuthenticationField.API_KEY_ID_KEY) != null)
+ assert (AuthenticationType.API_KEY.equals(this.type) == false) || (this.metadata.get(AuthenticationField.API_KEY_ID_KEY) != null)
: "API KEY authentication requires metadata to contain API KEY id, and the value must be non-null.";
- assert (AuthenticationType.API_KEY.equals(this.type)) && (this.metadata.containsKey(AuthenticationField.API_KEY_NAME_KEY))
+ assert (AuthenticationType.API_KEY.equals(this.type) == false) || (this.metadata.containsKey(AuthenticationField.API_KEY_NAME_KEY))
: "API KEY authentication requires metadata to contain API KEY name; the value may be null for older keys.";
}
From a4fd65413e77783f244161ff7839b52b9d118237 Mon Sep 17 00:00:00 2001
From: Justin Cranford
Date: Thu, 21 Oct 2021 16:02:25 -0400
Subject: [PATCH 18/25] API KEY name must be present, null or non-null.
---
.../client/security/DelegatePkiAuthenticationResponseTests.java | 2 ++
.../core/action/DelegatePkiAuthenticationResponseTests.java | 2 ++
2 files changed, 4 insertions(+)
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/DelegatePkiAuthenticationResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/DelegatePkiAuthenticationResponseTests.java
index 32ed46f0b9014..db85935d3fcd5 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/DelegatePkiAuthenticationResponseTests.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/DelegatePkiAuthenticationResponseTests.java
@@ -82,6 +82,8 @@ protected Authentication createAuthentication() {
metadata.put(AuthenticationField.API_KEY_ID_KEY, randomAlphaOfLengthBetween(1, 10));
if (randomBoolean()) {
metadata.put(AuthenticationField.API_KEY_NAME_KEY, randomAlphaOfLengthBetween(1, 10));
+ } else {
+ metadata.put(AuthenticationField.API_KEY_NAME_KEY, null);
}
}
return new Authentication(
diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/action/DelegatePkiAuthenticationResponseTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/action/DelegatePkiAuthenticationResponseTests.java
index 8530a8e837d33..8086a17a072b2 100644
--- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/action/DelegatePkiAuthenticationResponseTests.java
+++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/action/DelegatePkiAuthenticationResponseTests.java
@@ -141,6 +141,8 @@ public static Authentication createAuthentication() {
metadata.put(AuthenticationField.API_KEY_ID_KEY, randomAlphaOfLengthBetween(1, 10));
if (randomBoolean()) {
metadata.put(AuthenticationField.API_KEY_NAME_KEY, randomAlphaOfLengthBetween(1, 10));
+ } else {
+ metadata.put(AuthenticationField.API_KEY_NAME_KEY, null);
}
}
return new Authentication(
From 0e0f30c5313019cfb8bc901ab5a9403bef9a4bb6 Mon Sep 17 00:00:00 2001
From: Justin Cranford
Date: Thu, 21 Oct 2021 16:29:59 -0400
Subject: [PATCH 19/25] Fix test to include API KEY name, random or null.
---
.../core/security/authc/AuthenticationTests.java | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authc/AuthenticationTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authc/AuthenticationTests.java
index e84efb8c3cce7..cc41e659855da 100644
--- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authc/AuthenticationTests.java
+++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authc/AuthenticationTests.java
@@ -19,6 +19,7 @@
import java.util.Arrays;
import java.util.EnumSet;
+import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
@@ -181,12 +182,20 @@ public static Authentication randomAuthentication(User user, RealmRef realmRef)
public static Authentication randomApiKeyAuthentication(User user, String apiKeyId) {
final RealmRef apiKeyRealm = new RealmRef("_es_api_key", "_es_api_key", randomAlphaOfLengthBetween(3, 8));
+ final HashMap apiKeyInfo = new HashMap<>();
+ apiKeyInfo.put(AuthenticationField.API_KEY_ID_KEY, apiKeyId);
+ if (randomBoolean()) {
+ apiKeyInfo.put(AuthenticationField.API_KEY_NAME_KEY, randomAlphaOfLengthBetween(1, 16));
+ } else {
+ apiKeyInfo.put(AuthenticationField.API_KEY_NAME_KEY, null); // HashMap supports null values
+ }
return new Authentication(user,
apiKeyRealm,
null,
VersionUtils.randomVersionBetween(random(), Version.V_7_0_0, Version.CURRENT),
AuthenticationType.API_KEY,
- Map.of(AuthenticationField.API_KEY_ID_KEY, apiKeyId));
+ apiKeyInfo
+ );
}
private boolean realmIsSingleton(RealmRef realmRef) {
From ac3655782c6e38f53098fe1b2f17debd66593c1f Mon Sep 17 00:00:00 2001
From: Justin Cranford
Date: Thu, 21 Oct 2021 21:23:21 -0400
Subject: [PATCH 20/25] Fix tests.
---
...elegatePkiAuthenticationResponseTests.java | 6 +---
...elegatePkiAuthenticationResponseTests.java | 6 +---
.../security/authc/AuthenticationTests.java | 12 +++----
.../ManageOwnApiKeyClusterPrivilegeTests.java | 11 ++++--
.../xpack/security/SecurityContextTests.java | 25 ++++++-------
.../security/authc/ApiKeyServiceTests.java | 3 ++
.../authz/store/CompositeRolesStoreTests.java | 36 +++++++++----------
.../ingest/SetSecurityUserProcessorTests.java | 27 +++++++-------
8 files changed, 62 insertions(+), 64 deletions(-)
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/DelegatePkiAuthenticationResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/DelegatePkiAuthenticationResponseTests.java
index db85935d3fcd5..2897e3c42af13 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/DelegatePkiAuthenticationResponseTests.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/DelegatePkiAuthenticationResponseTests.java
@@ -80,11 +80,7 @@ protected Authentication createAuthentication() {
final Authentication.AuthenticationType authenticationType = randomFrom(Authentication.AuthenticationType.values());
if (Authentication.AuthenticationType.API_KEY.equals(authenticationType)) {
metadata.put(AuthenticationField.API_KEY_ID_KEY, randomAlphaOfLengthBetween(1, 10));
- if (randomBoolean()) {
- metadata.put(AuthenticationField.API_KEY_NAME_KEY, randomAlphaOfLengthBetween(1, 10));
- } else {
- metadata.put(AuthenticationField.API_KEY_NAME_KEY, null);
- }
+ metadata.put(AuthenticationField.API_KEY_NAME_KEY, randomBoolean() ? null : randomAlphaOfLengthBetween(1, 10));
}
return new Authentication(
new User(username, roles, fullName, email, metadata, true),
diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/action/DelegatePkiAuthenticationResponseTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/action/DelegatePkiAuthenticationResponseTests.java
index 8086a17a072b2..7f3caa4c89bf1 100644
--- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/action/DelegatePkiAuthenticationResponseTests.java
+++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/action/DelegatePkiAuthenticationResponseTests.java
@@ -139,11 +139,7 @@ public static Authentication createAuthentication() {
final Authentication.AuthenticationType authenticationType = randomFrom(Authentication.AuthenticationType.values());
if (Authentication.AuthenticationType.API_KEY.equals(authenticationType)) {
metadata.put(AuthenticationField.API_KEY_ID_KEY, randomAlphaOfLengthBetween(1, 10));
- if (randomBoolean()) {
- metadata.put(AuthenticationField.API_KEY_NAME_KEY, randomAlphaOfLengthBetween(1, 10));
- } else {
- metadata.put(AuthenticationField.API_KEY_NAME_KEY, null);
- }
+ metadata.put(AuthenticationField.API_KEY_NAME_KEY, randomBoolean() ? null : randomAlphaOfLengthBetween(1, 10));
}
return new Authentication(
new User(username, roles, fullName, email, metadata, true),
diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authc/AuthenticationTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authc/AuthenticationTests.java
index cc41e659855da..5ee4bc428793d 100644
--- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authc/AuthenticationTests.java
+++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authc/AuthenticationTests.java
@@ -182,19 +182,15 @@ public static Authentication randomAuthentication(User user, RealmRef realmRef)
public static Authentication randomApiKeyAuthentication(User user, String apiKeyId) {
final RealmRef apiKeyRealm = new RealmRef("_es_api_key", "_es_api_key", randomAlphaOfLengthBetween(3, 8));
- final HashMap apiKeyInfo = new HashMap<>();
- apiKeyInfo.put(AuthenticationField.API_KEY_ID_KEY, apiKeyId);
- if (randomBoolean()) {
- apiKeyInfo.put(AuthenticationField.API_KEY_NAME_KEY, randomAlphaOfLengthBetween(1, 16));
- } else {
- apiKeyInfo.put(AuthenticationField.API_KEY_NAME_KEY, null); // HashMap supports null values
- }
+ final HashMap metadata = new HashMap<>();
+ metadata.put(AuthenticationField.API_KEY_ID_KEY, apiKeyId);
+ metadata.put(AuthenticationField.API_KEY_NAME_KEY, randomBoolean() ? null : randomAlphaOfLengthBetween(1, 16));
return new Authentication(user,
apiKeyRealm,
null,
VersionUtils.randomVersionBetween(random(), Version.V_7_0_0, Version.CURRENT),
AuthenticationType.API_KEY,
- apiKeyInfo
+ metadata
);
}
diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/ManageOwnApiKeyClusterPrivilegeTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/ManageOwnApiKeyClusterPrivilegeTests.java
index ad6494338571a..21aac9a114e88 100644
--- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/ManageOwnApiKeyClusterPrivilegeTests.java
+++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/ManageOwnApiKeyClusterPrivilegeTests.java
@@ -21,6 +21,7 @@
import org.elasticsearch.xpack.core.security.authz.permission.ClusterPermission;
import org.elasticsearch.xpack.core.security.user.User;
+import java.util.HashMap;
import java.util.Map;
import static org.hamcrest.Matchers.is;
@@ -34,8 +35,11 @@ public void testAuthenticationWithApiKeyAllowsAccessToApiKeyActionsWhenItIsOwner
ManageOwnApiKeyClusterPrivilege.INSTANCE.buildPermission(ClusterPermission.builder()).build();
final String apiKeyId = randomAlphaOfLengthBetween(4, 7);
+ final HashMap metadata = new HashMap<>();
+ metadata.put(AuthenticationField.API_KEY_ID_KEY, randomAlphaOfLength(7));
+ metadata.put(AuthenticationField.API_KEY_NAME_KEY, randomBoolean() ? null : randomAlphaOfLengthBetween(1, 16));
final Authentication authentication = createMockAuthentication("joe", "_es_api_key",
- AuthenticationType.API_KEY, Map.of(AuthenticationField.API_KEY_ID_KEY, apiKeyId));
+ AuthenticationType.API_KEY, metadata);
final TransportRequest getApiKeyRequest = GetApiKeyRequest.usingApiKeyId(apiKeyId, randomBoolean());
final TransportRequest invalidateApiKeyRequest = InvalidateApiKeyRequest.usingApiKeyId(apiKeyId, randomBoolean());
@@ -49,8 +53,11 @@ public void testAuthenticationWithApiKeyDeniesAccessToApiKeyActionsWhenItIsNotOw
ManageOwnApiKeyClusterPrivilege.INSTANCE.buildPermission(ClusterPermission.builder()).build();
final String apiKeyId = randomAlphaOfLengthBetween(4, 7);
+ final HashMap metadata = new HashMap<>();
+ metadata.put(AuthenticationField.API_KEY_ID_KEY, randomAlphaOfLength(7));
+ metadata.put(AuthenticationField.API_KEY_NAME_KEY, randomBoolean() ? null : randomAlphaOfLengthBetween(1, 16));
final Authentication authentication = createMockAuthentication("joe", "_es_api_key",
- AuthenticationType.API_KEY, Map.of(AuthenticationField.API_KEY_ID_KEY, randomAlphaOfLength(7)));
+ AuthenticationType.API_KEY, metadata);
final TransportRequest getApiKeyRequest = GetApiKeyRequest.usingApiKeyId(apiKeyId, randomBoolean());
final TransportRequest invalidateApiKeyRequest = InvalidateApiKeyRequest.usingApiKeyId(apiKeyId, randomBoolean());
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityContextTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityContextTests.java
index b2105c2624efa..97edd3a2ce589 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityContextTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityContextTests.java
@@ -26,6 +26,7 @@
import java.io.EOFException;
import java.io.IOException;
import java.io.UncheckedIOException;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
@@ -148,12 +149,12 @@ AuthenticationField.PRIVILEGE_CATEGORY_KEY, randomAlphaOfLengthBetween(3, 10),
public void testExecuteAfterRewritingAuthenticationWillConditionallyRewriteNewApiKeyMetadata() throws IOException {
User user = new User("test", null, new User("authUser"));
RealmRef authBy = new RealmRef("_es_api_key", "_es_api_key", "node1");
- final Map metadata = Map.of(
- AuthenticationField.API_KEY_ID_KEY, randomAlphaOfLengthBetween(1, 10),
- AuthenticationField.API_KEY_NAME_KEY, randomAlphaOfLengthBetween(1, 10),
- AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY, new BytesArray("{\"a role\": {\"cluster\": [\"all\"]}}"),
- AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, new BytesArray("{\"limitedBy role\": {\"cluster\": [\"all\"]}}")
- );
+ final Map metadata = new HashMap<>();
+ metadata.put(AuthenticationField.API_KEY_ID_KEY, randomAlphaOfLengthBetween(1, 10));
+ metadata.put(AuthenticationField.API_KEY_NAME_KEY, randomBoolean() ? null : randomAlphaOfLengthBetween(1, 10));
+ metadata.put(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY, new BytesArray("{\"a role\": {\"cluster\": [\"all\"]}}"));
+ metadata.put(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
+ new BytesArray("{\"limitedBy role\": {\"cluster\": [\"all\"]}}"));
final Authentication original = new Authentication(user, authBy, authBy, Version.V_8_0_0,
AuthenticationType.API_KEY, metadata);
original.writeToContext(threadContext);
@@ -177,12 +178,12 @@ AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, new BytesArray("{\"lim
public void testExecuteAfterRewritingAuthenticationWillConditionallyRewriteOldApiKeyMetadata() throws IOException {
User user = new User("test", null, new User("authUser"));
RealmRef authBy = new RealmRef("_es_api_key", "_es_api_key", "node1");
- final Map metadata = Map.of(
- AuthenticationField.API_KEY_ID_KEY, randomAlphaOfLengthBetween(1, 10),
- AuthenticationField.API_KEY_NAME_KEY, randomAlphaOfLengthBetween(1, 10),
- AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY, Map.of("a role", Map.of("cluster", List.of("all"))),
- AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, Map.of("limitedBy role", Map.of("cluster", List.of("all")))
- );
+ final Map metadata = new HashMap<>();
+ metadata.put(AuthenticationField.API_KEY_ID_KEY, randomAlphaOfLengthBetween(1, 10));
+ metadata.put(AuthenticationField.API_KEY_NAME_KEY, randomBoolean() ? null : randomAlphaOfLengthBetween(1, 10));
+ metadata.put(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY, Map.of("a role", Map.of("cluster", List.of("all"))));
+ metadata.put(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
+ Map.of("limitedBy role", Map.of("cluster", List.of("all"))));
final Authentication original = new Authentication(user, authBy, authBy, Version.V_7_8_0, AuthenticationType.API_KEY, metadata);
original.writeToContext(threadContext);
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/ApiKeyServiceTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/ApiKeyServiceTests.java
index 56ed5321f58df..318ee89fa32ed 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/ApiKeyServiceTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/ApiKeyServiceTests.java
@@ -503,6 +503,7 @@ public void testGetRolesForApiKeyNotInContext() throws Exception {
}
Map authMetadata = new HashMap<>();
authMetadata.put(AuthenticationField.API_KEY_ID_KEY, randomAlphaOfLength(12));
+ authMetadata.put(AuthenticationField.API_KEY_NAME_KEY, randomBoolean() ? null : randomAlphaOfLength(12));
authMetadata.put(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY,
Collections.singletonMap(SUPERUSER_ROLE_DESCRIPTOR.getName(), superUserRdMap));
authMetadata.put(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
@@ -524,6 +525,7 @@ public void testGetRolesForApiKeyNotInContext() throws Exception {
public void testGetRolesForApiKey() throws Exception {
Map authMetadata = new HashMap<>();
authMetadata.put(AuthenticationField.API_KEY_ID_KEY, randomAlphaOfLength(12));
+ authMetadata.put(AuthenticationField.API_KEY_NAME_KEY, randomBoolean() ? null : randomAlphaOfLength(12));
boolean emptyApiKeyRoleDescriptor = randomBoolean();
final RoleDescriptor roleARoleDescriptor = new RoleDescriptor("a role", new String[] { "monitor" },
new RoleDescriptor.IndicesPrivileges[] {
@@ -587,6 +589,7 @@ public void testGetApiKeyIdAndRoleBytes() {
Map authMetadata = new HashMap<>();
final String apiKeyId = randomAlphaOfLength(12);
authMetadata.put(AuthenticationField.API_KEY_ID_KEY, apiKeyId);
+ authMetadata.put(AuthenticationField.API_KEY_NAME_KEY, randomBoolean() ? null : randomAlphaOfLength(12));
final BytesReference roleBytes = new BytesArray("{\"a role\": {\"cluster\": [\"all\"]}}");
final BytesReference limitedByRoleBytes = new BytesArray("{\"limitedBy role\": {\"cluster\": [\"all\"]}}");
authMetadata.put(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY, roleBytes);
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java
index 830fa0c9b929c..17e62f2e6a330 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java
@@ -1369,17 +1369,17 @@ public void testCacheEntryIsReusedForIdenticalApiKeyRoles() {
AuditUtil.getOrGenerateRequestId(threadContext);
final BytesArray roleBytes = new BytesArray("{\"a role\": {\"cluster\": [\"all\"]}}");
final BytesArray limitedByRoleBytes = new BytesArray("{\"limitedBy role\": {\"cluster\": [\"all\"]}}");
+ final Map metadata = new HashMap<>();
+ metadata.put(AuthenticationField.API_KEY_ID_KEY, "key-id-1");
+ metadata.put(AuthenticationField.API_KEY_NAME_KEY, randomBoolean() ? null : randomAlphaOfLengthBetween(1, 16));
+ metadata.put(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY, roleBytes);
+ metadata.put(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, limitedByRoleBytes);
Authentication authentication = new Authentication(new User("test api key user", "superuser"),
new RealmRef("_es_api_key", "_es_api_key", "node"),
null,
Version.CURRENT,
AuthenticationType.API_KEY,
- Map.of(AuthenticationField.API_KEY_ID_KEY,
- "key-id-1",
- AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY,
- roleBytes,
- AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
- limitedByRoleBytes));
+ metadata);
doCallRealMethod().when(apiKeyService).getApiKeyIdAndRoleBytes(eq(authentication), anyBoolean());
PlainActionFuture roleFuture = new PlainActionFuture<>();
@@ -1391,17 +1391,17 @@ public void testCacheEntryIsReusedForIdenticalApiKeyRoles() {
verify(apiKeyService).parseRoleDescriptors("key-id-1", limitedByRoleBytes);
// Different API key with the same roles should read from cache
+ final Map metadata2 = new HashMap<>();
+ metadata2.put(AuthenticationField.API_KEY_ID_KEY, "key-id-2");
+ metadata2.put(AuthenticationField.API_KEY_NAME_KEY, randomBoolean() ? null : randomAlphaOfLengthBetween(1, 16));
+ metadata2.put(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY, roleBytes);
+ metadata2.put(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, limitedByRoleBytes);
authentication = new Authentication(new User("test api key user 2", "superuser"),
new RealmRef("_es_api_key", "_es_api_key", "node"),
null,
Version.CURRENT,
AuthenticationType.API_KEY,
- Map.of(AuthenticationField.API_KEY_ID_KEY,
- "key-id-2",
- AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY,
- roleBytes,
- AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
- limitedByRoleBytes));
+ metadata2);
doCallRealMethod().when(apiKeyService).getApiKeyIdAndRoleBytes(eq(authentication), anyBoolean());
roleFuture = new PlainActionFuture<>();
compositeRolesStore.getRoles(authentication.getUser(), authentication, roleFuture);
@@ -1412,17 +1412,17 @@ public void testCacheEntryIsReusedForIdenticalApiKeyRoles() {
// Different API key with the same limitedBy role should read from cache, new role should be built
final BytesArray anotherRoleBytes = new BytesArray("{\"b role\": {\"cluster\": [\"manage_security\"]}}");
+ final Map metadata3 = new HashMap<>();
+ metadata3.put(AuthenticationField.API_KEY_ID_KEY, "key-id-3");
+ metadata3.put(AuthenticationField.API_KEY_NAME_KEY, randomBoolean() ? null : randomAlphaOfLengthBetween(1, 16));
+ metadata3.put(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY, anotherRoleBytes);
+ metadata3.put(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, limitedByRoleBytes);
authentication = new Authentication(new User("test api key user 2", "superuser"),
new RealmRef("_es_api_key", "_es_api_key", "node"),
null,
Version.CURRENT,
AuthenticationType.API_KEY,
- Map.of(AuthenticationField.API_KEY_ID_KEY,
- "key-id-3",
- AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY,
- anotherRoleBytes,
- AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
- limitedByRoleBytes));
+ metadata3);
doCallRealMethod().when(apiKeyService).getApiKeyIdAndRoleBytes(eq(authentication), anyBoolean());
roleFuture = new PlainActionFuture<>();
compositeRolesStore.getRoles(authentication.getUser(), authentication, roleFuture);
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessorTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessorTests.java
index 671e5a3aed6b6..bf77fdc9fae82 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessorTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessorTests.java
@@ -251,12 +251,11 @@ public void testApiKeyPopulation() throws Exception {
Authentication.RealmRef realmRef = new Authentication.RealmRef(
AuthenticationField.API_KEY_REALM_NAME, AuthenticationField.API_KEY_REALM_TYPE, "_node_name");
- final Map authMetadata = new HashMap<>(Map.of(
- AuthenticationField.API_KEY_ID_KEY, "api_key_id",
- AuthenticationField.API_KEY_NAME_KEY, "api_key_name",
- AuthenticationField.API_KEY_CREATOR_REALM_NAME, "creator_realm_name",
- AuthenticationField.API_KEY_CREATOR_REALM_TYPE, "creator_realm_type"
- ));
+ final Map authMetadata = new HashMap<>();
+ authMetadata.put(AuthenticationField.API_KEY_ID_KEY, "api_key_id");
+ authMetadata.put(AuthenticationField.API_KEY_NAME_KEY, randomBoolean() ? null : "api_key_name");
+ authMetadata.put(AuthenticationField.API_KEY_CREATOR_REALM_NAME, "creator_realm_name");
+ authMetadata.put(AuthenticationField.API_KEY_CREATOR_REALM_TYPE, "creator_realm_type");
final Map apiKeyMetadata = ApiKeyTests.randomMetadata();
if (apiKeyMetadata != null) {
authMetadata.put(AuthenticationField.API_KEY_METADATA_KEY,
@@ -275,8 +274,9 @@ public void testApiKeyPopulation() throws Exception {
Map result = ingestDocument.getFieldValue("_field", Map.class);
assertThat(result, aMapWithSize(4));
final Map apiKeyMap = (Map) result.get("api_key");
- assertThat(apiKeyMap.get("name"), equalTo("api_key_name"));
- assertThat(apiKeyMap.get("id"), equalTo("api_key_id"));
+ assertThat(apiKeyMap.get("id"), equalTo(authMetadata.get(AuthenticationField.API_KEY_ID_KEY)));
+ assertThat(apiKeyMap, hasKey("name")); // must be present, even if null or non-null
+ assertThat(apiKeyMap.get("name"), equalTo(authMetadata.get(AuthenticationField.API_KEY_NAME_KEY))); // null or non-null
if (apiKeyMetadata == null || apiKeyMetadata.isEmpty()) {
assertNull(apiKeyMap.get("metadata"));
} else {
@@ -293,12 +293,11 @@ public void testWillNotOverwriteExistingApiKeyAndRealm() throws Exception {
Authentication.RealmRef realmRef = new Authentication.RealmRef(
AuthenticationField.API_KEY_REALM_NAME, AuthenticationField.API_KEY_REALM_TYPE, "_node_name");
- final Map authMetadata = new HashMap<>(Map.of(
- AuthenticationField.API_KEY_ID_KEY, "api_key_id",
- AuthenticationField.API_KEY_NAME_KEY, "api_key_name",
- AuthenticationField.API_KEY_CREATOR_REALM_NAME, "creator_realm_name",
- AuthenticationField.API_KEY_CREATOR_REALM_TYPE, "creator_realm_type"
- ));
+ final Map authMetadata = new HashMap<>();
+ authMetadata.put(AuthenticationField.API_KEY_ID_KEY, "api_key_id");
+ authMetadata.put(AuthenticationField.API_KEY_NAME_KEY, randomBoolean() ? null : "api_key_name");
+ authMetadata.put(AuthenticationField.API_KEY_CREATOR_REALM_NAME, "creator_realm_name");
+ authMetadata.put(AuthenticationField.API_KEY_CREATOR_REALM_TYPE, "creator_realm_type");
final Map apiKeyMetadata = ApiKeyTests.randomMetadata();
if (apiKeyMetadata != null) {
authMetadata.put(AuthenticationField.API_KEY_METADATA_KEY,
From 15e140ab7293821f95facd4bb032dd26888a4236 Mon Sep 17 00:00:00 2001
From: Justin Cranford
Date: Mon, 25 Oct 2021 00:43:52 -0400
Subject: [PATCH 21/25] Fix test.
---
.../authz/privilege/ManageOwnApiKeyClusterPrivilegeTests.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/ManageOwnApiKeyClusterPrivilegeTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/ManageOwnApiKeyClusterPrivilegeTests.java
index 21aac9a114e88..9d469c76fb02a 100644
--- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/ManageOwnApiKeyClusterPrivilegeTests.java
+++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/ManageOwnApiKeyClusterPrivilegeTests.java
@@ -36,8 +36,8 @@ public void testAuthenticationWithApiKeyAllowsAccessToApiKeyActionsWhenItIsOwner
final String apiKeyId = randomAlphaOfLengthBetween(4, 7);
final HashMap metadata = new HashMap<>();
- metadata.put(AuthenticationField.API_KEY_ID_KEY, randomAlphaOfLength(7));
- metadata.put(AuthenticationField.API_KEY_NAME_KEY, randomBoolean() ? null : randomAlphaOfLengthBetween(1, 16));
+ metadata.put(AuthenticationField.API_KEY_ID_KEY, apiKeyId);
+ metadata.put(AuthenticationField.API_KEY_NAME_KEY, randomAlphaOfLengthBetween(1, 16));
final Authentication authentication = createMockAuthentication("joe", "_es_api_key",
AuthenticationType.API_KEY, metadata);
final TransportRequest getApiKeyRequest = GetApiKeyRequest.usingApiKeyId(apiKeyId, randomBoolean());
From 96884c14d4a533edb188f132b6506e5639dc713f Mon Sep 17 00:00:00 2001
From: Justin Cranford
Date: Thu, 28 Oct 2021 14:40:54 -0400
Subject: [PATCH 22/25] Fix issues with auto-merge.
---
.../xpack/core/security/SecurityContext.java | 1 +
.../xpack/security/authc/ApiKeyService.java | 2 +-
.../security/authc/ApiKeyServiceTests.java | 32 +++++++++----------
.../authz/store/CompositeRolesStoreTests.java | 8 ++---
4 files changed, 22 insertions(+), 21 deletions(-)
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/SecurityContext.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/SecurityContext.java
index 738c6eba24563..255f4954a065f 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/SecurityContext.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/SecurityContext.java
@@ -21,6 +21,7 @@
import org.elasticsearch.xcontent.XContentType;
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.Authentication.AuthenticationType;
+import org.elasticsearch.xpack.core.security.authc.AuthenticationField;
import org.elasticsearch.xpack.core.security.authc.support.AuthenticationContextSerializer;
import org.elasticsearch.xpack.core.security.authc.support.SecondaryAuthentication;
import org.elasticsearch.xpack.core.security.user.User;
diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/ApiKeyService.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/ApiKeyService.java
index 3bf6dc8876857..0d5f1531ae825 100644
--- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/ApiKeyService.java
+++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/ApiKeyService.java
@@ -448,7 +448,7 @@ public Authentication createApiKeyAuthentication(AuthenticationResult auth
if (false == authResult.isAuthenticated()) {
throw new IllegalArgumentException("API Key authn result must be successful");
}
- final User user = authResult.getUser();
+ final User user = authResult.getValue();
final RealmRef authenticatedBy = new RealmRef(AuthenticationField.API_KEY_REALM_NAME, AuthenticationField.API_KEY_REALM_TYPE,
nodeName);
return new Authentication(user, authenticatedBy, null, Version.CURRENT, Authentication.AuthenticationType.API_KEY,
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/ApiKeyServiceTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/ApiKeyServiceTests.java
index 3e7dce5e940f1..a5e9ae0870efa 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/ApiKeyServiceTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/ApiKeyServiceTests.java
@@ -300,10 +300,10 @@ public void testAuthenticateWithApiKey() throws Exception {
final AuthenticationResult auth = tryAuthenticate(service, id, key);
assertThat(auth.getStatus(), is(AuthenticationResult.Status.SUCCESS));
- assertThat(auth.getUser(), notNullValue());
- assertThat(auth.getUser().principal(), is("hulk"));
- assertThat(auth.getUser().fullName(), is("Bruce Banner"));
- assertThat(auth.getUser().email(), is("hulk@test.com"));
+ assertThat(auth.getValue(), notNullValue());
+ assertThat(auth.getValue().principal(), is("hulk"));
+ assertThat(auth.getValue().fullName(), is("Bruce Banner"));
+ assertThat(auth.getValue().email(), is("hulk@test.com"));
assertThat(auth.getMetadata().get(AuthenticationField.API_KEY_CREATOR_REALM_NAME), is("realm1"));
assertThat(auth.getMetadata().get(AuthenticationField.API_KEY_CREATOR_REALM_TYPE), is("native"));
assertThat(auth.getMetadata().get(AuthenticationField.API_KEY_ID_KEY), is(id));
@@ -497,11 +497,11 @@ public void testValidateApiKey() throws Exception {
AuthenticationResult result = future.get();
assertNotNull(result);
assertTrue(result.isAuthenticated());
- assertThat(result.getUser().principal(), is("test_user"));
- assertThat(result.getUser().fullName(), is("test user"));
- assertThat(result.getUser().email(), is("test@user.com"));
- assertThat(result.getUser().roles(), is(emptyArray()));
- assertThat(result.getUser().metadata(), is(Collections.emptyMap()));
+ assertThat(result.getValue().principal(), is("test_user"));
+ assertThat(result.getValue().fullName(), is("test user"));
+ assertThat(result.getValue().email(), is("test@user.com"));
+ assertThat(result.getValue().roles(), is(emptyArray()));
+ assertThat(result.getValue().metadata(), is(Collections.emptyMap()));
assertThat(result.getMetadata().get(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY), equalTo(apiKeyDoc.roleDescriptorsBytes));
assertThat(result.getMetadata().get(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY),
equalTo(apiKeyDoc.limitedByRoleDescriptorsBytes));
@@ -519,11 +519,11 @@ public void testValidateApiKey() throws Exception {
result = future.get();
assertNotNull(result);
assertTrue(result.isAuthenticated());
- assertThat(result.getUser().principal(), is("test_user"));
- assertThat(result.getUser().fullName(), is("test user"));
- assertThat(result.getUser().email(), is("test@user.com"));
- assertThat(result.getUser().roles(), is(emptyArray()));
- assertThat(result.getUser().metadata(), is(Collections.emptyMap()));
+ assertThat(result.getValue().principal(), is("test_user"));
+ assertThat(result.getValue().fullName(), is("test user"));
+ assertThat(result.getValue().email(), is("test@user.com"));
+ assertThat(result.getValue().roles(), is(emptyArray()));
+ assertThat(result.getValue().metadata(), is(Collections.emptyMap()));
assertThat(result.getMetadata().get(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY), equalTo(apiKeyDoc.roleDescriptorsBytes));
assertThat(result.getMetadata().get(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY),
equalTo(apiKeyDoc.limitedByRoleDescriptorsBytes));
@@ -1511,14 +1511,14 @@ public static Authentication createApiKeyAuthentication(
assert authenticationResult.getStatus() == AuthenticationResult.Status.SUCCESS;
Map authenticationResultMetadata = new HashMap<>(authenticationResult.getMetadata());
authenticationResultMetadata.remove(AuthenticationField.API_KEY_CREATOR_REALM_NAME);
- authenticationResult = AuthenticationResult.success(authenticationResult.getUser(), authenticationResultMetadata);
+ authenticationResult = AuthenticationResult.success(authenticationResult.getValue(), authenticationResultMetadata);
}
if (randomBoolean()) {
// simulate authentication with nameless API Key, see https://github.com/elastic/elasticsearch/issues/59484
assert authenticationResult.getStatus() == AuthenticationResult.Status.SUCCESS;
Map authenticationResultMetadata = new HashMap<>(authenticationResult.getMetadata());
authenticationResultMetadata.remove(AuthenticationField.API_KEY_NAME_KEY);
- authenticationResult = AuthenticationResult.success(authenticationResult.getUser(), authenticationResultMetadata);
+ authenticationResult = AuthenticationResult.success(authenticationResult.getValue(), authenticationResultMetadata);
}
final ThreadContext threadContext = new ThreadContext(Settings.EMPTY);
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java
index 85517043bd8d4..c6c5c77d46603 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java
@@ -648,7 +648,7 @@ public void testMergingRolesWithFls() {
Sets.newHashSet(flsRole, addsL1Fields),
cache,
null,
- RESTRICTED_INDICES_AUTOMATON,
+ TestRestrictedIndices.RESTRICTED_INDICES_AUTOMATON,
future
);
Role role = future.actionGet();
@@ -756,7 +756,7 @@ public ClusterPermission.Builder buildPermission(ClusterPermission.Builder build
Sets.newHashSet(role1, role2),
cache,
privilegeStore,
- RESTRICTED_INDICES_AUTOMATON,
+ TestRestrictedIndices.RESTRICTED_INDICES_AUTOMATON,
future
);
Role role = future.actionGet();
@@ -1617,7 +1617,7 @@ private Authentication createAuthentication() {
}
public void testXPackUserCanAccessNonRestrictedIndices() {
- CharacterRunAutomaton restrictedAutomaton = new CharacterRunAutomaton(RESTRICTED_INDICES_AUTOMATON);
+ CharacterRunAutomaton restrictedAutomaton = new CharacterRunAutomaton(TestRestrictedIndices.RESTRICTED_INDICES_AUTOMATON);
for (String action : Arrays.asList(GetAction.NAME, DeleteAction.NAME, SearchAction.NAME, IndexAction.NAME)) {
Predicate predicate = getXPackUserRole().indices().allowedIndicesMatcher(action);
IndexAbstraction index = mockIndexAbstraction(randomAlphaOfLengthBetween(3, 12));
@@ -1657,7 +1657,7 @@ public void testXPackUserCannotWriteToAuditTrail() {
}
public void testAsyncSearchUserCannotAccessNonRestrictedIndices() {
- CharacterRunAutomaton restrictedAutomaton = new CharacterRunAutomaton(RESTRICTED_INDICES_AUTOMATON);
+ CharacterRunAutomaton restrictedAutomaton = new CharacterRunAutomaton(TestRestrictedIndices.RESTRICTED_INDICES_AUTOMATON);
for (String action : Arrays.asList(GetAction.NAME, DeleteAction.NAME, SearchAction.NAME, IndexAction.NAME)) {
Predicate predicate = getAsyncSearchUserRole().indices().allowedIndicesMatcher(action);
IndexAbstraction index = mockIndexAbstraction(randomAlphaOfLengthBetween(3, 12));
From cf344e85a8e0db4bc79cc63a14b0529d3e7c5ac5 Mon Sep 17 00:00:00 2001
From: Justin Cranford
Date: Thu, 28 Oct 2021 15:15:44 -0400
Subject: [PATCH 23/25] Apply new whitesource formatting rules.
---
.../client/security/AuthenticateResponse.java | 61 +++--
.../security/AuthenticateResponseTests.java | 226 ++++++++++++++----
.../security/CreateTokenResponseTests.java | 10 +-
...elegatePkiAuthenticationResponseTests.java | 40 +++-
.../xpack/core/security/SecurityContext.java | 36 ++-
.../security/authc/AuthenticationTests.java | 5 +-
.../ManageOwnApiKeyClusterPrivilegeTests.java | 10 +-
.../xpack/security/apikey/ApiKeyRestIT.java | 11 +-
.../xpack/security/authc/FileRealmAuthIT.java | 2 -
.../xpack/security/authc/PkiRealmAuthIT.java | 2 -
.../security/authc/ReservedRealmAuthIT.java | 2 -
.../authc/SecurityRealmSmokeTestCase.java | 2 +-
.../xpack/security/authc/ApiKeyService.java | 32 ++-
.../ingest/SetSecurityUserProcessor.java | 6 +-
.../xpack/security/SecurityContextTests.java | 38 +--
.../logfile/LoggingAuditTrailFilterTests.java | 90 +++----
.../audit/logfile/LoggingAuditTrailTests.java | 6 +-
.../security/authc/ApiKeyServiceTests.java | 45 ++--
.../authz/store/CompositeRolesStoreTests.java | 18 +-
.../ingest/SetSecurityUserProcessorTests.java | 22 +-
20 files changed, 447 insertions(+), 217 deletions(-)
diff --git a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/AuthenticateResponse.java b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/AuthenticateResponse.java
index 2228fb2a59c9b..2aed21588aa7c 100644
--- a/client/rest-high-level/src/main/java/org/elasticsearch/client/security/AuthenticateResponse.java
+++ b/client/rest-high-level/src/main/java/org/elasticsearch/client/security/AuthenticateResponse.java
@@ -50,11 +50,18 @@ public final class AuthenticateResponse implements ToXContentObject {
@SuppressWarnings("unchecked")
private static final ConstructingObjectParser PARSER = new ConstructingObjectParser<>(
- "client_security_authenticate_response", true,
+ "client_security_authenticate_response",
+ true,
a -> new AuthenticateResponse(
- new User((String) a[0], ((List) a[1]), (Map) a[2],
- (String) a[3], (String) a[4]), (Boolean) a[5], (RealmInfo) a[6], (RealmInfo) a[7], (String) a[8],
- (Map) a[9], (ApiKeyInfo) a[10]));
+ new User((String) a[0], ((List) a[1]), (Map) a[2], (String) a[3], (String) a[4]),
+ (Boolean) a[5],
+ (RealmInfo) a[6],
+ (RealmInfo) a[7],
+ (String) a[8],
+ (Map) a[9],
+ (ApiKeyInfo) a[10]
+ )
+ );
static {
final ConstructingObjectParser realmInfoParser = new ConstructingObjectParser<>(
"realm_info",
@@ -64,8 +71,11 @@ public final class AuthenticateResponse implements ToXContentObject {
realmInfoParser.declareString(constructorArg(), REALM_NAME);
realmInfoParser.declareString(constructorArg(), REALM_TYPE);
- final ConstructingObjectParser apiKeyInfoParser = new ConstructingObjectParser<>("api_key", true,
- a -> new ApiKeyInfo((String) a[0], (String) a[1]));
+ final ConstructingObjectParser apiKeyInfoParser = new ConstructingObjectParser<>(
+ "api_key",
+ true,
+ a -> new ApiKeyInfo((String) a[0], (String) a[1])
+ );
apiKeyInfoParser.declareString(constructorArg(), API_KEY_INFO_ID);
apiKeyInfoParser.declareString(optionalConstructorArg(), API_KEY_INFO_NAME);
@@ -102,14 +112,26 @@ public AuthenticateResponse(
this(user, enabled, authenticationRealm, lookupRealm, authenticationType, null);
}
- public AuthenticateResponse(User user, boolean enabled, RealmInfo authenticationRealm,
- RealmInfo lookupRealm, String authenticationType, @Nullable Map token) {
+ public AuthenticateResponse(
+ User user,
+ boolean enabled,
+ RealmInfo authenticationRealm,
+ RealmInfo lookupRealm,
+ String authenticationType,
+ @Nullable Map token
+ ) {
this(user, enabled, authenticationRealm, lookupRealm, authenticationType, null, null);
}
- public AuthenticateResponse(User user, boolean enabled, RealmInfo authenticationRealm,
- RealmInfo lookupRealm, String authenticationType, @Nullable Map token,
- @Nullable ApiKeyInfo apikeyinfo) {
+ public AuthenticateResponse(
+ User user,
+ boolean enabled,
+ RealmInfo authenticationRealm,
+ RealmInfo lookupRealm,
+ String authenticationType,
+ @Nullable Map token,
+ @Nullable ApiKeyInfo apikeyinfo
+ ) {
this.user = user;
this.enabled = enabled;
this.authenticationRealm = authenticationRealm;
@@ -202,13 +224,13 @@ public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AuthenticateResponse that = (AuthenticateResponse) o;
- return enabled == that.enabled &&
- Objects.equals(user, that.user) &&
- Objects.equals(authenticationRealm, that.authenticationRealm) &&
- Objects.equals(lookupRealm, that.lookupRealm) &&
- Objects.equals(authenticationType, that.authenticationType) &&
- Objects.equals(token, that.token) &&
- Objects.equals(apikeyinfo, that.apikeyinfo);
+ return enabled == that.enabled
+ && Objects.equals(user, that.user)
+ && Objects.equals(authenticationRealm, that.authenticationRealm)
+ && Objects.equals(lookupRealm, that.lookupRealm)
+ && Objects.equals(authenticationType, that.authenticationType)
+ && Objects.equals(token, that.token)
+ && Objects.equals(apikeyinfo, that.apikeyinfo);
}
@Override
@@ -273,8 +295,7 @@ public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final ApiKeyInfo that = (ApiKeyInfo) o;
- return Objects.equals(this.id, that.id) &&
- Objects.equals(this.name, that.name);
+ return Objects.equals(this.id, that.id) && Objects.equals(this.name, that.name);
}
@Override
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/AuthenticateResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/AuthenticateResponseTests.java
index 43943875348aa..0766dcb55a98f 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/AuthenticateResponseTests.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/AuthenticateResponseTests.java
@@ -87,8 +87,14 @@ protected AuthenticateResponse createTestInstance() {
}
return new AuthenticateResponse(
- new User(username, roles, metadata, fullName, email), enabled, authenticationRealm,
- lookupRealm, authenticationType, tokenInfo, apiKeyInfo);
+ new User(username, roles, metadata, fullName, email),
+ enabled,
+ authenticationRealm,
+ lookupRealm,
+ authenticationType,
+ tokenInfo,
+ apiKeyInfo
+ );
}
private void toXContent(AuthenticateResponse response, XContentBuilder builder) throws IOException {
@@ -97,10 +103,22 @@ private void toXContent(AuthenticateResponse response, XContentBuilder builder)
private AuthenticateResponse copy(AuthenticateResponse response) {
final User originalUser = response.getUser();
- final User copyUser = new User(originalUser.getUsername(), originalUser.getRoles(), originalUser.getMetadata(),
- originalUser.getFullName(), originalUser.getEmail());
- return new AuthenticateResponse(copyUser, response.enabled(), response.getAuthenticationRealm(),
- response.getLookupRealm(), response.getAuthenticationType(), Map.copyOf(response.getToken()), response.getApiKeyInfo());
+ final User copyUser = new User(
+ originalUser.getUsername(),
+ originalUser.getRoles(),
+ originalUser.getMetadata(),
+ originalUser.getFullName(),
+ originalUser.getEmail()
+ );
+ return new AuthenticateResponse(
+ copyUser,
+ response.enabled(),
+ response.getAuthenticationRealm(),
+ response.getLookupRealm(),
+ response.getAuthenticationType(),
+ Map.copyOf(response.getToken()),
+ response.getApiKeyInfo()
+ );
}
private AuthenticateResponse mutate(AuthenticateResponse response) {
@@ -108,36 +126,105 @@ private AuthenticateResponse mutate(AuthenticateResponse response) {
int randomSwitchCase = randomIntBetween(1, 11); // range is inclusive
switch (randomSwitchCase) {
case 1:
- return new AuthenticateResponse(new User(originalUser.getUsername() + "wrong", originalUser.getRoles(),
- originalUser.getMetadata(), originalUser.getFullName(), originalUser.getEmail()), response.enabled(),
- response.getAuthenticationRealm(), response.getLookupRealm(), response.getAuthenticationType(), response.getToken(),
- response.getApiKeyInfo());
+ return new AuthenticateResponse(
+ new User(
+ originalUser.getUsername() + "wrong",
+ originalUser.getRoles(),
+ originalUser.getMetadata(),
+ originalUser.getFullName(),
+ originalUser.getEmail()
+ ),
+ response.enabled(),
+ response.getAuthenticationRealm(),
+ response.getLookupRealm(),
+ response.getAuthenticationType(),
+ response.getToken(),
+ response.getApiKeyInfo()
+ );
case 2:
final List wrongRoles = new ArrayList<>(originalUser.getRoles());
wrongRoles.add(randomAlphaOfLengthBetween(1, 4));
- return new AuthenticateResponse(new User(originalUser.getUsername(), wrongRoles, originalUser.getMetadata(),
- originalUser.getFullName(), originalUser.getEmail()), response.enabled(), response.getAuthenticationRealm(),
- response.getLookupRealm(), response.getAuthenticationType(), response.getToken(), response.getApiKeyInfo());
+ return new AuthenticateResponse(
+ new User(
+ originalUser.getUsername(),
+ wrongRoles,
+ originalUser.getMetadata(),
+ originalUser.getFullName(),
+ originalUser.getEmail()
+ ),
+ response.enabled(),
+ response.getAuthenticationRealm(),
+ response.getLookupRealm(),
+ response.getAuthenticationType(),
+ response.getToken(),
+ response.getApiKeyInfo()
+ );
case 3:
final Map wrongMetadata = new HashMap<>(originalUser.getMetadata());
wrongMetadata.put("wrong_string", randomAlphaOfLengthBetween(0, 4));
- return new AuthenticateResponse(new User(originalUser.getUsername(), originalUser.getRoles(), wrongMetadata,
- originalUser.getFullName(), originalUser.getEmail()), response.enabled(), response.getAuthenticationRealm(),
- response.getLookupRealm(), response.getAuthenticationType(), response.getToken(), response.getApiKeyInfo());
+ return new AuthenticateResponse(
+ new User(
+ originalUser.getUsername(),
+ originalUser.getRoles(),
+ wrongMetadata,
+ originalUser.getFullName(),
+ originalUser.getEmail()
+ ),
+ response.enabled(),
+ response.getAuthenticationRealm(),
+ response.getLookupRealm(),
+ response.getAuthenticationType(),
+ response.getToken(),
+ response.getApiKeyInfo()
+ );
case 4:
- return new AuthenticateResponse(new User(originalUser.getUsername(), originalUser.getRoles(), originalUser.getMetadata(),
- originalUser.getFullName() + "wrong", originalUser.getEmail()), response.enabled(),
- response.getAuthenticationRealm(), response.getLookupRealm(), response.getAuthenticationType(), response.getToken(),
- response.getApiKeyInfo());
+ return new AuthenticateResponse(
+ new User(
+ originalUser.getUsername(),
+ originalUser.getRoles(),
+ originalUser.getMetadata(),
+ originalUser.getFullName() + "wrong",
+ originalUser.getEmail()
+ ),
+ response.enabled(),
+ response.getAuthenticationRealm(),
+ response.getLookupRealm(),
+ response.getAuthenticationType(),
+ response.getToken(),
+ response.getApiKeyInfo()
+ );
case 5:
- return new AuthenticateResponse(new User(originalUser.getUsername(), originalUser.getRoles(), originalUser.getMetadata(),
- originalUser.getFullName(), originalUser.getEmail() + "wrong"), response.enabled(),
- response.getAuthenticationRealm(), response.getLookupRealm(), response.getAuthenticationType(), response.getToken(),
- response.getApiKeyInfo());
+ return new AuthenticateResponse(
+ new User(
+ originalUser.getUsername(),
+ originalUser.getRoles(),
+ originalUser.getMetadata(),
+ originalUser.getFullName(),
+ originalUser.getEmail() + "wrong"
+ ),
+ response.enabled(),
+ response.getAuthenticationRealm(),
+ response.getLookupRealm(),
+ response.getAuthenticationType(),
+ response.getToken(),
+ response.getApiKeyInfo()
+ );
case 6:
- return new AuthenticateResponse(new User(originalUser.getUsername(), originalUser.getRoles(), originalUser.getMetadata(),
- originalUser.getFullName(), originalUser.getEmail()), response.enabled() == false, response.getAuthenticationRealm(),
- response.getLookupRealm(), response.getAuthenticationType(), response.getToken(), response.getApiKeyInfo());
+ return new AuthenticateResponse(
+ new User(
+ originalUser.getUsername(),
+ originalUser.getRoles(),
+ originalUser.getMetadata(),
+ originalUser.getFullName(),
+ originalUser.getEmail()
+ ),
+ response.enabled() == false,
+ response.getAuthenticationRealm(),
+ response.getLookupRealm(),
+ response.getAuthenticationType(),
+ response.getToken(),
+ response.getApiKeyInfo()
+ );
case 7:
return new AuthenticateResponse(
new User(
@@ -150,12 +237,26 @@ private AuthenticateResponse mutate(AuthenticateResponse response) {
response.enabled(),
response.getAuthenticationRealm(),
new AuthenticateResponse.RealmInfo(randomAlphaOfLength(5), randomAlphaOfLength(5)),
- response.getAuthenticationType(), response.getToken(), response.getApiKeyInfo());
+ response.getAuthenticationType(),
+ response.getToken(),
+ response.getApiKeyInfo()
+ );
case 8:
- return new AuthenticateResponse(new User(originalUser.getUsername(), originalUser.getRoles(), originalUser.getMetadata(),
- originalUser.getFullName(), originalUser.getEmail()), response.enabled(),
- new AuthenticateResponse.RealmInfo(randomAlphaOfLength(5), randomAlphaOfLength(5)), response.getLookupRealm(),
- response.getAuthenticationType(), response.getToken(), response.getApiKeyInfo());
+ return new AuthenticateResponse(
+ new User(
+ originalUser.getUsername(),
+ originalUser.getRoles(),
+ originalUser.getMetadata(),
+ originalUser.getFullName(),
+ originalUser.getEmail()
+ ),
+ response.enabled(),
+ new AuthenticateResponse.RealmInfo(randomAlphaOfLength(5), randomAlphaOfLength(5)),
+ response.getLookupRealm(),
+ response.getAuthenticationType(),
+ response.getToken(),
+ response.getApiKeyInfo()
+ );
case 9:
return new AuthenticateResponse(
new User(
@@ -168,30 +269,59 @@ private AuthenticateResponse mutate(AuthenticateResponse response) {
response.enabled(),
response.getAuthenticationRealm(),
response.getLookupRealm(),
- randomValueOtherThan(response.getAuthenticationType(),
- () -> randomFrom("realm", "api_key", "token", "anonymous", "internal")), response.getToken(),
- response.getApiKeyInfo());
+ randomValueOtherThan(
+ response.getAuthenticationType(),
+ () -> randomFrom("realm", "api_key", "token", "anonymous", "internal")
+ ),
+ response.getToken(),
+ response.getApiKeyInfo()
+ );
case 10:
- return new AuthenticateResponse(new User(originalUser.getUsername(), originalUser.getRoles(), originalUser.getMetadata(),
- originalUser.getFullName(), originalUser.getEmail()), response.enabled(), response.getAuthenticationRealm(),
+ return new AuthenticateResponse(
+ new User(
+ originalUser.getUsername(),
+ originalUser.getRoles(),
+ originalUser.getMetadata(),
+ originalUser.getFullName(),
+ originalUser.getEmail()
+ ),
+ response.enabled(),
+ response.getAuthenticationRealm(),
response.getLookupRealm(),
response.getAuthenticationType(),
- response.getToken() == null ?
- Map.of("foo", "bar") :
- randomFrom(Map.of(
- "name", randomValueOtherThan(response.getToken().get("name"), () -> randomAlphaOfLengthBetween(3, 8)),
- "type", randomValueOtherThan(response.getToken().get("type"), () -> randomAlphaOfLengthBetween(3, 8))
- ), null),
- response.getApiKeyInfo());
+ response.getToken() == null
+ ? Map.of("foo", "bar")
+ : randomFrom(
+ Map.of(
+ "name",
+ randomValueOtherThan(response.getToken().get("name"), () -> randomAlphaOfLengthBetween(3, 8)),
+ "type",
+ randomValueOtherThan(response.getToken().get("type"), () -> randomAlphaOfLengthBetween(3, 8))
+ ),
+ null
+ ),
+ response.getApiKeyInfo()
+ );
case 11:
- return new AuthenticateResponse(new User(originalUser.getUsername(), originalUser.getRoles(), originalUser.getMetadata(),
- originalUser.getFullName(), originalUser.getEmail()), response.enabled(), response.getAuthenticationRealm(),
- response.getLookupRealm(), response.getAuthenticationType(), response.getToken(),
+ return new AuthenticateResponse(
+ new User(
+ originalUser.getUsername(),
+ originalUser.getRoles(),
+ originalUser.getMetadata(),
+ originalUser.getFullName(),
+ originalUser.getEmail()
+ ),
+ response.enabled(),
+ response.getAuthenticationRealm(),
+ response.getLookupRealm(),
+ response.getAuthenticationType(),
+ response.getToken(),
response.getApiKeyInfo() == null
? new AuthenticateResponse.ApiKeyInfo(
randomAlphaOfLength(16), // mandatory
randomBoolean() ? randomAlphaOfLength(20) : null // optional
- ) : null
+ )
+ : null
);
default:
fail("Random number " + randomSwitchCase + " did not match any switch cases");
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/CreateTokenResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/CreateTokenResponseTests.java
index f75105b07e43e..1024bf9f24b24 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/CreateTokenResponseTests.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/CreateTokenResponseTests.java
@@ -29,10 +29,12 @@ public void testFromXContent() throws IOException {
final String scope = randomBoolean() ? null : randomAlphaOfLength(4);
final String type = randomAlphaOfLength(6);
final String kerberosAuthenticationResponseToken = randomBoolean() ? null : randomAlphaOfLength(7);
- final AuthenticateResponse authentication = new AuthenticateResponse(new User(randomAlphaOfLength(7),
- Arrays.asList(randomAlphaOfLength(9))),
- true, new AuthenticateResponse.RealmInfo(randomAlphaOfLength(5), randomAlphaOfLength(7)),
- new AuthenticateResponse.RealmInfo(randomAlphaOfLength(5), randomAlphaOfLength(5)), "realm",
+ final AuthenticateResponse authentication = new AuthenticateResponse(
+ new User(randomAlphaOfLength(7), Arrays.asList(randomAlphaOfLength(9))),
+ true,
+ new AuthenticateResponse.RealmInfo(randomAlphaOfLength(5), randomAlphaOfLength(7)),
+ new AuthenticateResponse.RealmInfo(randomAlphaOfLength(5), randomAlphaOfLength(5)),
+ "realm",
null,
new AuthenticateResponse.ApiKeyInfo(
randomAlphaOfLength(16), // mandatory
diff --git a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/DelegatePkiAuthenticationResponseTests.java b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/DelegatePkiAuthenticationResponseTests.java
index 86437d98cf4cb..cee3657d403a3 100644
--- a/client/rest-high-level/src/test/java/org/elasticsearch/client/security/DelegatePkiAuthenticationResponseTests.java
+++ b/client/rest-high-level/src/test/java/org/elasticsearch/client/security/DelegatePkiAuthenticationResponseTests.java
@@ -99,23 +99,41 @@ protected Authentication createAuthentication() {
AuthenticateResponse createServerAuthenticationResponse(Authentication authentication) {
User user = authentication.getUser();
- org.elasticsearch.client.security.user.User cUser = new org.elasticsearch.client.security.user.User(user.principal(),
- Arrays.asList(user.roles()), user.metadata(), user.fullName(), user.email());
- AuthenticateResponse.RealmInfo authenticatedBy = new AuthenticateResponse.RealmInfo(authentication.getAuthenticatedBy().getName(),
- authentication.getAuthenticatedBy().getType());
- AuthenticateResponse.RealmInfo lookedUpBy = new AuthenticateResponse.RealmInfo(authentication.getLookedUpBy() == null?
- authentication.getAuthenticatedBy().getName(): authentication.getLookedUpBy().getName(),
- authentication.getLookedUpBy() == null?
- authentication.getAuthenticatedBy().getType(): authentication.getLookedUpBy().getType());
+ org.elasticsearch.client.security.user.User cUser = new org.elasticsearch.client.security.user.User(
+ user.principal(),
+ Arrays.asList(user.roles()),
+ user.metadata(),
+ user.fullName(),
+ user.email()
+ );
+ AuthenticateResponse.RealmInfo authenticatedBy = new AuthenticateResponse.RealmInfo(
+ authentication.getAuthenticatedBy().getName(),
+ authentication.getAuthenticatedBy().getType()
+ );
+ AuthenticateResponse.RealmInfo lookedUpBy = new AuthenticateResponse.RealmInfo(
+ authentication.getLookedUpBy() == null
+ ? authentication.getAuthenticatedBy().getName()
+ : authentication.getLookedUpBy().getName(),
+ authentication.getLookedUpBy() == null
+ ? authentication.getAuthenticatedBy().getType()
+ : authentication.getLookedUpBy().getType()
+ );
final AuthenticateResponse.ApiKeyInfo apiKeyInfo;
if (Authentication.AuthenticationType.API_KEY.equals(authentication.getAuthenticationType())) {
- final String apiKeyId = (String) authentication.getMetadata().get(AuthenticationField.API_KEY_ID_KEY); // mandatory
+ final String apiKeyId = (String) authentication.getMetadata().get(AuthenticationField.API_KEY_ID_KEY); // mandatory
final String apiKeyName = (String) authentication.getMetadata().get(AuthenticationField.API_KEY_NAME_KEY); // optional
apiKeyInfo = new AuthenticateResponse.ApiKeyInfo(apiKeyId, apiKeyName);
} else {
apiKeyInfo = null;
}
- return new AuthenticateResponse(cUser, user.enabled(), authenticatedBy, lookedUpBy,
- authentication.getAuthenticationType().toString().toLowerCase(Locale.ROOT), null, apiKeyInfo);
+ return new AuthenticateResponse(
+ cUser,
+ user.enabled(),
+ authenticatedBy,
+ lookedUpBy,
+ authentication.getAuthenticationType().toString().toLowerCase(Locale.ROOT),
+ null,
+ apiKeyInfo
+ );
}
}
diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/SecurityContext.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/SecurityContext.java
index 255f4954a065f..4c1b992af7c4b 100644
--- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/SecurityContext.java
+++ b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/SecurityContext.java
@@ -188,22 +188,32 @@ private Map rewriteMetadataForApiKeyRoleDescriptors(Version stre
if (authentication.getVersion().onOrAfter(VERSION_API_KEY_ROLES_AS_BYTES)
&& streamVersion.before(VERSION_API_KEY_ROLES_AS_BYTES)) {
metadata = new HashMap<>(metadata);
- metadata.put(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY,
+ metadata.put(
+ AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY,
+ convertRoleDescriptorsBytesToMap((BytesReference) metadata.get(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY))
+ );
+ metadata.put(
+ AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
convertRoleDescriptorsBytesToMap(
- (BytesReference) metadata.get(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY)));
- metadata.put(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
- convertRoleDescriptorsBytesToMap(
- (BytesReference) metadata.get(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY)));
+ (BytesReference) metadata.get(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY)
+ )
+ );
} else if (authentication.getVersion().before(VERSION_API_KEY_ROLES_AS_BYTES)
&& streamVersion.onOrAfter(VERSION_API_KEY_ROLES_AS_BYTES)) {
- metadata = new HashMap<>(metadata);
- metadata.put(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY,
- convertRoleDescriptorsMapToBytes(
- (Map) metadata.get(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY)));
- metadata.put(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
- convertRoleDescriptorsMapToBytes(
- (Map) metadata.get(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY)));
- }
+ metadata = new HashMap<>(metadata);
+ metadata.put(
+ AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY,
+ convertRoleDescriptorsMapToBytes(
+ (Map) metadata.get(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY)
+ )
+ );
+ metadata.put(
+ AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
+ convertRoleDescriptorsMapToBytes(
+ (Map) metadata.get(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY)
+ )
+ );
+ }
}
return metadata;
}
diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authc/AuthenticationTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authc/AuthenticationTests.java
index 26a8f51411670..bdc5d2656b58f 100644
--- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authc/AuthenticationTests.java
+++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authc/AuthenticationTests.java
@@ -205,10 +205,11 @@ public static Authentication randomAuthentication(User user, RealmRef realmRef)
public static Authentication randomApiKeyAuthentication(User user, String apiKeyId) {
final RealmRef apiKeyRealm = new RealmRef("_es_api_key", "_es_api_key", randomAlphaOfLengthBetween(3, 8));
- final HashMap metadata = new HashMap<>();
+ final HashMap metadata = new HashMap<>();
metadata.put(AuthenticationField.API_KEY_ID_KEY, apiKeyId);
metadata.put(AuthenticationField.API_KEY_NAME_KEY, randomBoolean() ? null : randomAlphaOfLengthBetween(1, 16));
- return new Authentication(user,
+ return new Authentication(
+ user,
apiKeyRealm,
null,
VersionUtils.randomVersionBetween(random(), Version.V_7_0_0, Version.CURRENT),
diff --git a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/ManageOwnApiKeyClusterPrivilegeTests.java b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/ManageOwnApiKeyClusterPrivilegeTests.java
index d92050d67cec3..8fda71fc22c6f 100644
--- a/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/ManageOwnApiKeyClusterPrivilegeTests.java
+++ b/x-pack/plugin/core/src/test/java/org/elasticsearch/xpack/core/security/authz/privilege/ManageOwnApiKeyClusterPrivilegeTests.java
@@ -35,11 +35,10 @@ public void testAuthenticationWithApiKeyAllowsAccessToApiKeyActionsWhenItIsOwner
.build();
final String apiKeyId = randomAlphaOfLengthBetween(4, 7);
- final HashMap metadata = new HashMap<>();
+ final HashMap metadata = new HashMap<>();
metadata.put(AuthenticationField.API_KEY_ID_KEY, apiKeyId);
metadata.put(AuthenticationField.API_KEY_NAME_KEY, randomAlphaOfLengthBetween(1, 16));
- final Authentication authentication = createMockAuthentication("joe", "_es_api_key",
- AuthenticationType.API_KEY, metadata);
+ final Authentication authentication = createMockAuthentication("joe", "_es_api_key", AuthenticationType.API_KEY, metadata);
final TransportRequest getApiKeyRequest = GetApiKeyRequest.usingApiKeyId(apiKeyId, randomBoolean());
final TransportRequest invalidateApiKeyRequest = InvalidateApiKeyRequest.usingApiKeyId(apiKeyId, randomBoolean());
@@ -53,11 +52,10 @@ public void testAuthenticationWithApiKeyDeniesAccessToApiKeyActionsWhenItIsNotOw
.build();
final String apiKeyId = randomAlphaOfLengthBetween(4, 7);
- final HashMap metadata = new HashMap<>();
+ final HashMap metadata = new HashMap<>();
metadata.put(AuthenticationField.API_KEY_ID_KEY, randomAlphaOfLength(7));
metadata.put(AuthenticationField.API_KEY_NAME_KEY, randomBoolean() ? null : randomAlphaOfLengthBetween(1, 16));
- final Authentication authentication = createMockAuthentication("joe", "_es_api_key",
- AuthenticationType.API_KEY, metadata);
+ final Authentication authentication = createMockAuthentication("joe", "_es_api_key", AuthenticationType.API_KEY, metadata);
final TransportRequest getApiKeyRequest = GetApiKeyRequest.usingApiKeyId(apiKeyId, randomBoolean());
final TransportRequest invalidateApiKeyRequest = InvalidateApiKeyRequest.usingApiKeyId(apiKeyId, randomBoolean());
diff --git a/x-pack/plugin/security/qa/security-trial/src/javaRestTest/java/org/elasticsearch/xpack/security/apikey/ApiKeyRestIT.java b/x-pack/plugin/security/qa/security-trial/src/javaRestTest/java/org/elasticsearch/xpack/security/apikey/ApiKeyRestIT.java
index ceb65e7c7abb8..c68a269f4bcd2 100644
--- a/x-pack/plugin/security/qa/security-trial/src/javaRestTest/java/org/elasticsearch/xpack/security/apikey/ApiKeyRestIT.java
+++ b/x-pack/plugin/security/qa/security-trial/src/javaRestTest/java/org/elasticsearch/xpack/security/apikey/ApiKeyRestIT.java
@@ -29,8 +29,8 @@
import java.util.Set;
import static org.hamcrest.Matchers.containsString;
-import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.emptyString;
+import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.hasEntry;
import static org.hamcrest.Matchers.instanceOf;
@@ -66,7 +66,7 @@ public void cleanUp() throws IOException {
invalidateApiKeysForUser(END_USER);
}
- @SuppressWarnings({"unchecked"})
+ @SuppressWarnings({ "unchecked" })
public void testAuthenticateResponseApiKey() throws IOException {
final String expectedApiKeyName = "my-api-key-name";
final Map expectedApiKeyMetadata = Map.of("not", "returned");
@@ -85,15 +85,16 @@ public void testAuthenticateResponseApiKey() throws IOException {
assertThat(actualApiKeyEncoded, not(emptyString()));
final Request authenticateRequest = new Request("GET", "_security/_authenticate");
- authenticateRequest.setOptions(authenticateRequest.getOptions().toBuilder().addHeader(
- "Authorization", "ApiKey " + actualApiKeyEncoded));
+ authenticateRequest.setOptions(
+ authenticateRequest.getOptions().toBuilder().addHeader("Authorization", "ApiKey " + actualApiKeyEncoded)
+ );
final Response authenticateResponse = client().performRequest(authenticateRequest);
assertOK(authenticateResponse);
final Map authenticate = responseAsMap(authenticateResponse); // keys: username, roles, full_name, etc
// If authentication type is API_KEY, authentication.api_key={"id":"abc123","name":"my-api-key"}. No encoded, api_key, or metadata.
- // If authentication type is other, authentication.api_key not present.
+ // If authentication type is other, authentication.api_key not present.
assertThat(authenticate, hasEntry("api_key", Map.of("id", actualApiKeyId, "name", expectedApiKeyName)));
}
diff --git a/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/FileRealmAuthIT.java b/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/FileRealmAuthIT.java
index d36df810542df..1703a6e6fa083 100644
--- a/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/FileRealmAuthIT.java
+++ b/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/FileRealmAuthIT.java
@@ -15,8 +15,6 @@
import java.io.IOException;
import java.util.Map;
-import static org.hamcrest.Matchers.is;
-
/**
* Integration Rest Test for testing authentication when all possible realms are configured
*/
diff --git a/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/PkiRealmAuthIT.java b/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/PkiRealmAuthIT.java
index aa3d60ca3af8a..69391ff14e73c 100644
--- a/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/PkiRealmAuthIT.java
+++ b/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/PkiRealmAuthIT.java
@@ -15,8 +15,6 @@
import java.io.IOException;
import java.util.Map;
-import static org.hamcrest.Matchers.is;
-
/**
* Integration Rest Test for testing authentication when all possible realms are configured
*/
diff --git a/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/ReservedRealmAuthIT.java b/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/ReservedRealmAuthIT.java
index 9167d0500ccac..bb096dad8f151 100644
--- a/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/ReservedRealmAuthIT.java
+++ b/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/ReservedRealmAuthIT.java
@@ -16,8 +16,6 @@
import java.io.IOException;
import java.util.Map;
-import static org.hamcrest.Matchers.is;
-
/**
* Integration Rest Test for testing authentication when all possible realms are configured
*/
diff --git a/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/SecurityRealmSmokeTestCase.java b/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/SecurityRealmSmokeTestCase.java
index d557945723936..bdccd10db561c 100644
--- a/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/SecurityRealmSmokeTestCase.java
+++ b/x-pack/plugin/security/qa/smoke-test-all-realms/src/javaRestTest/java/org/elasticsearch/xpack/security/authc/SecurityRealmSmokeTestCase.java
@@ -106,7 +106,7 @@ protected void assertRoles(Map authenticateResponse, String... r
protected void assertNoApiKeyInfo(Map authenticateResponse, AuthenticationType type) {
// If authentication type is API_KEY, authentication.api_key={"id":"abc123","name":"my-api-key"}. No encoded, api_key, or metadata.
- // If authentication type is other, authentication.api_key not present.
+ // If authentication type is other, authentication.api_key not present.
assertThat(authenticateResponse, not(hasKey("api_key")));
}
diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/ApiKeyService.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/ApiKeyService.java
index 0d5f1531ae825..4efbb10db1601 100644
--- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/ApiKeyService.java
+++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/ApiKeyService.java
@@ -449,10 +449,19 @@ public Authentication createApiKeyAuthentication(AuthenticationResult auth
throw new IllegalArgumentException("API Key authn result must be successful");
}
final User user = authResult.getValue();
- final RealmRef authenticatedBy = new RealmRef(AuthenticationField.API_KEY_REALM_NAME, AuthenticationField.API_KEY_REALM_TYPE,
- nodeName);
- return new Authentication(user, authenticatedBy, null, Version.CURRENT, Authentication.AuthenticationType.API_KEY,
- authResult.getMetadata());
+ final RealmRef authenticatedBy = new RealmRef(
+ AuthenticationField.API_KEY_REALM_NAME,
+ AuthenticationField.API_KEY_REALM_TYPE,
+ nodeName
+ );
+ return new Authentication(
+ user,
+ authenticatedBy,
+ null,
+ Version.CURRENT,
+ Authentication.AuthenticationType.API_KEY,
+ authResult.getMetadata()
+ );
}
void loadApiKeyAndValidateCredentials(
@@ -540,10 +549,12 @@ public void getRoleForApiKey(Authentication authentication, ActionListener metadata = authentication.getMetadata();
final String apiKeyId = (String) metadata.get(AuthenticationField.API_KEY_ID_KEY);
- @SuppressWarnings("unchecked") final Map roleDescriptors =
- (Map) metadata.get(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY);
- @SuppressWarnings("unchecked") final Map authnRoleDescriptors =
- (Map) metadata.get(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY);
+ @SuppressWarnings("unchecked")
+ final Map roleDescriptors = (Map) metadata.get(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY);
+ @SuppressWarnings("unchecked")
+ final Map authnRoleDescriptors = (Map) metadata.get(
+ AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY
+ );
if (roleDescriptors == null && authnRoleDescriptors == null) {
listener.onFailure(new ElasticsearchSecurityException("no role descriptors found for API key"));
@@ -565,8 +576,9 @@ public Tuple getApiKeyIdAndRoleBytes(Authentication auth
: "This method only applies to authentication objects created on or after v7.9.0";
final Map metadata = authentication.getMetadata();
- final BytesReference bytesReference = (BytesReference) metadata.get(limitedBy
- ? AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY : AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY);
+ final BytesReference bytesReference = (BytesReference) metadata.get(
+ limitedBy ? AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY : AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY
+ );
if (limitedBy && bytesReference.length() == 2 && "{}".equals(bytesReference.utf8ToString())) {
if (ServiceAccountSettings.REALM_NAME.equals(metadata.get(AuthenticationField.API_KEY_CREATOR_REALM_NAME))
&& "elastic/fleet-server".equals(authentication.getUser().principal())) {
diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessor.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessor.java
index f45872a0e4b85..216c3bca32124 100644
--- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessor.java
+++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessor.java
@@ -143,8 +143,10 @@ public IngestDocument execute(IngestDocument ingestDocument) throws Exception {
if (Authentication.AuthenticationType.API_KEY == authentication.getAuthenticationType()) {
final String apiKey = "api_key";
final Object existingApiKeyField = userObject.get(apiKey);
- @SuppressWarnings("unchecked") final Map apiKeyField =
- existingApiKeyField instanceof Map ? (Map) existingApiKeyField : new HashMap<>();
+ @SuppressWarnings("unchecked")
+ final Map apiKeyField = existingApiKeyField instanceof Map
+ ? (Map) existingApiKeyField
+ : new HashMap<>();
Object apiKeyName = authentication.getMetadata().get(AuthenticationField.API_KEY_NAME_KEY);
if (apiKeyName != null) {
apiKeyField.put("name", apiKeyName);
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityContextTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityContextTests.java
index a940159a301a5..c718c80d43443 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityContextTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityContextTests.java
@@ -160,19 +160,24 @@ public void testExecuteAfterRewritingAuthenticationWillConditionallyRewriteNewAp
metadata.put(AuthenticationField.API_KEY_ID_KEY, randomAlphaOfLengthBetween(1, 10));
metadata.put(AuthenticationField.API_KEY_NAME_KEY, randomBoolean() ? null : randomAlphaOfLengthBetween(1, 10));
metadata.put(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY, new BytesArray("{\"a role\": {\"cluster\": [\"all\"]}}"));
- metadata.put(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
- new BytesArray("{\"limitedBy role\": {\"cluster\": [\"all\"]}}"));
- final Authentication original = new Authentication(user, authBy, authBy, Version.V_8_0_0,
- AuthenticationType.API_KEY, metadata);
+ metadata.put(
+ AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
+ new BytesArray("{\"limitedBy role\": {\"cluster\": [\"all\"]}}")
+ );
+ final Authentication original = new Authentication(user, authBy, authBy, Version.V_8_0_0, AuthenticationType.API_KEY, metadata);
original.writeToContext(threadContext);
// If target is old node, rewrite new style API key metadata to old format
securityContext.executeAfterRewritingAuthentication(originalCtx -> {
Authentication authentication = securityContext.getAuthentication();
- assertEquals(Map.of("a role", Map.of("cluster", List.of("all"))),
- authentication.getMetadata().get(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY));
- assertEquals(Map.of("limitedBy role", Map.of("cluster", List.of("all"))),
- authentication.getMetadata().get(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY));
+ assertEquals(
+ Map.of("a role", Map.of("cluster", List.of("all"))),
+ authentication.getMetadata().get(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY)
+ );
+ assertEquals(
+ Map.of("limitedBy role", Map.of("cluster", List.of("all"))),
+ authentication.getMetadata().get(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY)
+ );
}, Version.V_7_8_0);
// If target is new node, no need to rewrite the new style API key metadata
@@ -189,8 +194,7 @@ public void testExecuteAfterRewritingAuthenticationWillConditionallyRewriteOldAp
metadata.put(AuthenticationField.API_KEY_ID_KEY, randomAlphaOfLengthBetween(1, 10));
metadata.put(AuthenticationField.API_KEY_NAME_KEY, randomBoolean() ? null : randomAlphaOfLengthBetween(1, 10));
metadata.put(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY, Map.of("a role", Map.of("cluster", List.of("all"))));
- metadata.put(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
- Map.of("limitedBy role", Map.of("cluster", List.of("all"))));
+ metadata.put(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, Map.of("limitedBy role", Map.of("cluster", List.of("all"))));
final Authentication original = new Authentication(user, authBy, authBy, Version.V_7_8_0, AuthenticationType.API_KEY, metadata);
original.writeToContext(threadContext);
@@ -203,12 +207,14 @@ public void testExecuteAfterRewritingAuthenticationWillConditionallyRewriteOldAp
// If target is new old, ensure old map style API key metadata is rewritten to bytesreference
securityContext.executeAfterRewritingAuthentication(originalCtx -> {
Authentication authentication = securityContext.getAuthentication();
- assertEquals("{\"a role\":{\"cluster\":[\"all\"]}}",
- ((BytesReference) authentication.getMetadata()
- .get(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY)).utf8ToString());
- assertEquals("{\"limitedBy role\":{\"cluster\":[\"all\"]}}",
- ((BytesReference) authentication.getMetadata()
- .get(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY)).utf8ToString());
+ assertEquals(
+ "{\"a role\":{\"cluster\":[\"all\"]}}",
+ ((BytesReference) authentication.getMetadata().get(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY)).utf8ToString()
+ );
+ assertEquals(
+ "{\"limitedBy role\":{\"cluster\":[\"all\"]}}",
+ ((BytesReference) authentication.getMetadata().get(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY)).utf8ToString()
+ );
}, VersionUtils.randomVersionBetween(random(), VERSION_API_KEY_ROLES_AS_BYTES, Version.CURRENT));
}
}
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailFilterTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailFilterTests.java
index 1919f9f147244..46c999138365c 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailFilterTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailFilterTests.java
@@ -1311,11 +1311,12 @@ public void testRealmsFilter() throws Exception {
threadContext.stashContext();
// accessGranted
- Authentication authentication = randomBoolean() ? createAuthentication(user, filteredRealm) :
- createApiKeyAuthentication(apiKeyService, createAuthentication(user, filteredRealm));
- auditTrail.accessGranted(randomAlphaOfLength(8), authentication, "_action", request, authzInfo(new String[]{"role1"}));
- if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY &&
- false == authentication.getMetadata().containsKey(AuthenticationField.API_KEY_CREATOR_REALM_NAME)) {
+ Authentication authentication = randomBoolean()
+ ? createAuthentication(user, filteredRealm)
+ : createApiKeyAuthentication(apiKeyService, createAuthentication(user, filteredRealm));
+ auditTrail.accessGranted(randomAlphaOfLength(8), authentication, "_action", request, authzInfo(new String[] { "role1" }));
+ if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY
+ && false == authentication.getMetadata().containsKey(AuthenticationField.API_KEY_CREATOR_REALM_NAME)) {
if (filterMissingRealm) {
assertThat("AccessGranted message: not filtered out by the missing realm filter", logOutput.size(), is(0));
} else {
@@ -1327,11 +1328,12 @@ public void testRealmsFilter() throws Exception {
logOutput.clear();
threadContext.stashContext();
- authentication = randomBoolean() ? createAuthentication(user, unfilteredRealm) :
- createApiKeyAuthentication(apiKeyService, createAuthentication(user, unfilteredRealm));
- auditTrail.accessGranted(randomAlphaOfLength(8), authentication, "_action", request, authzInfo(new String[]{"role1"}));
- if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY &&
- false == authentication.getMetadata().containsKey(AuthenticationField.API_KEY_CREATOR_REALM_NAME)) {
+ authentication = randomBoolean()
+ ? createAuthentication(user, unfilteredRealm)
+ : createApiKeyAuthentication(apiKeyService, createAuthentication(user, unfilteredRealm));
+ auditTrail.accessGranted(randomAlphaOfLength(8), authentication, "_action", request, authzInfo(new String[] { "role1" }));
+ if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY
+ && false == authentication.getMetadata().containsKey(AuthenticationField.API_KEY_CREATOR_REALM_NAME)) {
if (filterMissingRealm) {
assertThat("AccessGranted message: not filtered out by the missing realm filter", logOutput.size(), is(0));
} else {
@@ -1365,11 +1367,12 @@ public void testRealmsFilter() throws Exception {
logOutput.clear();
threadContext.stashContext();
- authentication = randomBoolean() ? createAuthentication(user, filteredRealm) :
- createApiKeyAuthentication(apiKeyService, createAuthentication(user, filteredRealm));
- auditTrail.accessGranted(randomAlphaOfLength(8), authentication, "internal:_action", request, authzInfo(new String[]{"role1"}));
- if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY &&
- false == authentication.getMetadata().containsKey(AuthenticationField.API_KEY_CREATOR_REALM_NAME)) {
+ authentication = randomBoolean()
+ ? createAuthentication(user, filteredRealm)
+ : createApiKeyAuthentication(apiKeyService, createAuthentication(user, filteredRealm));
+ auditTrail.accessGranted(randomAlphaOfLength(8), authentication, "internal:_action", request, authzInfo(new String[] { "role1" }));
+ if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY
+ && false == authentication.getMetadata().containsKey(AuthenticationField.API_KEY_CREATOR_REALM_NAME)) {
if (filterMissingRealm) {
assertThat("AccessGranted internal message: not filtered out by the missing realm filter", logOutput.size(), is(0));
} else {
@@ -1385,8 +1388,8 @@ public void testRealmsFilter() throws Exception {
? createAuthentication(user, unfilteredRealm)
: createApiKeyAuthentication(apiKeyService, createAuthentication(user, unfilteredRealm));
auditTrail.accessGranted(randomAlphaOfLength(8), authentication, "internal:_action", request, authzInfo(new String[] { "role1" }));
- if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY &&
- false == authentication.getMetadata().containsKey(AuthenticationField.API_KEY_CREATOR_REALM_NAME)) {
+ if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY
+ && false == authentication.getMetadata().containsKey(AuthenticationField.API_KEY_CREATOR_REALM_NAME)) {
if (filterMissingRealm) {
assertThat("AccessGranted internal message: not filtered out by the missing realm filter", logOutput.size(), is(0));
} else {
@@ -1399,11 +1402,12 @@ public void testRealmsFilter() throws Exception {
threadContext.stashContext();
// accessDenied
- authentication = randomBoolean() ? createAuthentication(user, filteredRealm) :
- createApiKeyAuthentication(apiKeyService, createAuthentication(user, filteredRealm));
- auditTrail.accessDenied(randomAlphaOfLength(8), authentication, "_action", request, authzInfo(new String[]{"role1"}));
- if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY &&
- false == authentication.getMetadata().containsKey(AuthenticationField.API_KEY_CREATOR_REALM_NAME)) {
+ authentication = randomBoolean()
+ ? createAuthentication(user, filteredRealm)
+ : createApiKeyAuthentication(apiKeyService, createAuthentication(user, filteredRealm));
+ auditTrail.accessDenied(randomAlphaOfLength(8), authentication, "_action", request, authzInfo(new String[] { "role1" }));
+ if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY
+ && false == authentication.getMetadata().containsKey(AuthenticationField.API_KEY_CREATOR_REALM_NAME)) {
if (filterMissingRealm) {
assertThat("AccessDenied message: not filtered out by the missing realm filter", logOutput.size(), is(0));
} else {
@@ -1415,11 +1419,12 @@ public void testRealmsFilter() throws Exception {
logOutput.clear();
threadContext.stashContext();
- authentication = randomBoolean() ? createAuthentication(user, unfilteredRealm) :
- createApiKeyAuthentication(apiKeyService, createAuthentication(user, unfilteredRealm));
- auditTrail.accessDenied(randomAlphaOfLength(8), authentication, "_action", request, authzInfo(new String[]{"role1"}));
- if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY &&
- false == authentication.getMetadata().containsKey(AuthenticationField.API_KEY_CREATOR_REALM_NAME)) {
+ authentication = randomBoolean()
+ ? createAuthentication(user, unfilteredRealm)
+ : createApiKeyAuthentication(apiKeyService, createAuthentication(user, unfilteredRealm));
+ auditTrail.accessDenied(randomAlphaOfLength(8), authentication, "_action", request, authzInfo(new String[] { "role1" }));
+ if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY
+ && false == authentication.getMetadata().containsKey(AuthenticationField.API_KEY_CREATOR_REALM_NAME)) {
if (filterMissingRealm) {
assertThat("AccessDenied message: not filtered out by the missing realm filter", logOutput.size(), is(0));
} else {
@@ -1453,11 +1458,12 @@ public void testRealmsFilter() throws Exception {
logOutput.clear();
threadContext.stashContext();
- authentication = randomBoolean() ? createAuthentication(user, filteredRealm) :
- createApiKeyAuthentication(apiKeyService, createAuthentication(user, filteredRealm));
- auditTrail.accessDenied(randomAlphaOfLength(8), authentication, "internal:_action", request, authzInfo(new String[]{"role1"}));
- if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY &&
- false == authentication.getMetadata().containsKey(AuthenticationField.API_KEY_CREATOR_REALM_NAME)) {
+ authentication = randomBoolean()
+ ? createAuthentication(user, filteredRealm)
+ : createApiKeyAuthentication(apiKeyService, createAuthentication(user, filteredRealm));
+ auditTrail.accessDenied(randomAlphaOfLength(8), authentication, "internal:_action", request, authzInfo(new String[] { "role1" }));
+ if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY
+ && false == authentication.getMetadata().containsKey(AuthenticationField.API_KEY_CREATOR_REALM_NAME)) {
if (filterMissingRealm) {
assertThat("AccessDenied internal message: not filtered out by the missing realm filter", logOutput.size(), is(0));
} else {
@@ -1469,12 +1475,12 @@ public void testRealmsFilter() throws Exception {
logOutput.clear();
threadContext.stashContext();
- authentication = randomBoolean() ? createAuthentication(user, unfilteredRealm) :
- createApiKeyAuthentication(apiKeyService, createAuthentication(user, unfilteredRealm));
- auditTrail.accessDenied(randomAlphaOfLength(8), authentication, "internal:_action",
- request, authzInfo(new String[]{"role1"}));
- if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY &&
- false == authentication.getMetadata().containsKey(AuthenticationField.API_KEY_CREATOR_REALM_NAME)) {
+ authentication = randomBoolean()
+ ? createAuthentication(user, unfilteredRealm)
+ : createApiKeyAuthentication(apiKeyService, createAuthentication(user, unfilteredRealm));
+ auditTrail.accessDenied(randomAlphaOfLength(8), authentication, "internal:_action", request, authzInfo(new String[] { "role1" }));
+ if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY
+ && false == authentication.getMetadata().containsKey(AuthenticationField.API_KEY_CREATOR_REALM_NAME)) {
if (filterMissingRealm) {
assertThat("AccessDenied internal message: not filtered out by the missing realm filter", logOutput.size(), is(0));
} else {
@@ -1509,8 +1515,8 @@ public void testRealmsFilter() throws Exception {
? createAuthentication(user, filteredRealm)
: createApiKeyAuthentication(apiKeyService, createAuthentication(user, filteredRealm));
auditTrail.tamperedRequest(randomAlphaOfLength(8), authentication, "_action", request);
- if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY &&
- false == authentication.getMetadata().containsKey(AuthenticationField.API_KEY_CREATOR_REALM_NAME)) {
+ if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY
+ && false == authentication.getMetadata().containsKey(AuthenticationField.API_KEY_CREATOR_REALM_NAME)) {
if (filterMissingRealm) {
assertThat("Tampered message: not filtered out by the missing realm filter", logOutput.size(), is(0));
} else {
@@ -1526,8 +1532,8 @@ public void testRealmsFilter() throws Exception {
? createAuthentication(user, unfilteredRealm)
: createApiKeyAuthentication(apiKeyService, createAuthentication(user, unfilteredRealm));
auditTrail.tamperedRequest(randomAlphaOfLength(8), authentication, "_action", request);
- if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY &&
- false == authentication.getMetadata().containsKey(AuthenticationField.API_KEY_CREATOR_REALM_NAME)) {
+ if (authentication.getAuthenticationType() == Authentication.AuthenticationType.API_KEY
+ && false == authentication.getMetadata().containsKey(AuthenticationField.API_KEY_CREATOR_REALM_NAME)) {
if (filterMissingRealm) {
assertThat("Tampered message: not filtered out by the missing realm filter", logOutput.size(), is(0));
} else {
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailTests.java
index 55329ca3583bc..beba1abb6c0c7 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/audit/logfile/LoggingAuditTrailTests.java
@@ -2603,8 +2603,10 @@ private static void authentication(Authentication authentication, MapBuilder superUserRdMap;
try (XContentBuilder builder = JsonXContent.contentBuilder()) {
- superUserRdMap = XContentHelper.convertToMap(XContentType.JSON.xContent(),
- BytesReference.bytes(SUPERUSER_ROLE_DESCRIPTOR
- .toXContent(builder, ToXContent.EMPTY_PARAMS, true))
- .streamInput(),
- false);
+ superUserRdMap = XContentHelper.convertToMap(
+ XContentType.JSON.xContent(),
+ BytesReference.bytes(SUPERUSER_ROLE_DESCRIPTOR.toXContent(builder, ToXContent.EMPTY_PARAMS, true)).streamInput(),
+ false
+ );
}
Map authMetadata = new HashMap<>();
authMetadata.put(AuthenticationField.API_KEY_ID_KEY, randomAlphaOfLength(12));
authMetadata.put(AuthenticationField.API_KEY_NAME_KEY, randomBoolean() ? null : randomAlphaOfLength(12));
- authMetadata.put(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY,
- Collections.singletonMap(SUPERUSER_ROLE_DESCRIPTOR.getName(), superUserRdMap));
- authMetadata.put(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
- Collections.singletonMap(SUPERUSER_ROLE_DESCRIPTOR.getName(), superUserRdMap));
+ authMetadata.put(
+ AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY,
+ Collections.singletonMap(SUPERUSER_ROLE_DESCRIPTOR.getName(), superUserRdMap)
+ );
+ authMetadata.put(
+ AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY,
+ Collections.singletonMap(SUPERUSER_ROLE_DESCRIPTOR.getName(), superUserRdMap)
+ );
final Authentication authentication = new Authentication(
new User("joe"),
@@ -616,9 +624,12 @@ public void testGetRolesForApiKey() throws Exception {
false
);
}
- authMetadata.put(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY,
- (emptyApiKeyRoleDescriptor) ? randomFrom(Arrays.asList(null, Collections.emptyMap()))
- : Collections.singletonMap("a role", roleARDMap));
+ authMetadata.put(
+ AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY,
+ (emptyApiKeyRoleDescriptor)
+ ? randomFrom(Arrays.asList(null, Collections.emptyMap()))
+ : Collections.singletonMap("a role", roleARDMap)
+ );
final RoleDescriptor limitedRoleDescriptor = new RoleDescriptor(
"limited role",
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java
index c6c5c77d46603..154ce73cbb69d 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStoreTests.java
@@ -1531,12 +1531,14 @@ public void testCacheEntryIsReusedForIdenticalApiKeyRoles() {
metadata.put(AuthenticationField.API_KEY_NAME_KEY, randomBoolean() ? null : randomAlphaOfLengthBetween(1, 16));
metadata.put(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY, roleBytes);
metadata.put(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, limitedByRoleBytes);
- Authentication authentication = new Authentication(new User("test api key user", "superuser"),
+ Authentication authentication = new Authentication(
+ new User("test api key user", "superuser"),
new RealmRef("_es_api_key", "_es_api_key", "node"),
null,
Version.CURRENT,
AuthenticationType.API_KEY,
- metadata);
+ metadata
+ );
doCallRealMethod().when(apiKeyService).getApiKeyIdAndRoleBytes(eq(authentication), anyBoolean());
PlainActionFuture roleFuture = new PlainActionFuture<>();
@@ -1553,12 +1555,14 @@ public void testCacheEntryIsReusedForIdenticalApiKeyRoles() {
metadata2.put(AuthenticationField.API_KEY_NAME_KEY, randomBoolean() ? null : randomAlphaOfLengthBetween(1, 16));
metadata2.put(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY, roleBytes);
metadata2.put(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, limitedByRoleBytes);
- authentication = new Authentication(new User("test api key user 2", "superuser"),
+ authentication = new Authentication(
+ new User("test api key user 2", "superuser"),
new RealmRef("_es_api_key", "_es_api_key", "node"),
null,
Version.CURRENT,
AuthenticationType.API_KEY,
- metadata2);
+ metadata2
+ );
doCallRealMethod().when(apiKeyService).getApiKeyIdAndRoleBytes(eq(authentication), anyBoolean());
roleFuture = new PlainActionFuture<>();
compositeRolesStore.getRoles(authentication.getUser(), authentication, roleFuture);
@@ -1574,12 +1578,14 @@ public void testCacheEntryIsReusedForIdenticalApiKeyRoles() {
metadata3.put(AuthenticationField.API_KEY_NAME_KEY, randomBoolean() ? null : randomAlphaOfLengthBetween(1, 16));
metadata3.put(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY, anotherRoleBytes);
metadata3.put(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY, limitedByRoleBytes);
- authentication = new Authentication(new User("test api key user 2", "superuser"),
+ authentication = new Authentication(
+ new User("test api key user 2", "superuser"),
new RealmRef("_es_api_key", "_es_api_key", "node"),
null,
Version.CURRENT,
AuthenticationType.API_KEY,
- metadata3);
+ metadata3
+ );
doCallRealMethod().when(apiKeyService).getApiKeyIdAndRoleBytes(eq(authentication), anyBoolean());
roleFuture = new PlainActionFuture<>();
compositeRolesStore.getRoles(authentication.getUser(), authentication, roleFuture);
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessorTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessorTests.java
index d9c6b79a9d462..2f3e26e72850e 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessorTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessorTests.java
@@ -316,7 +316,10 @@ public void testOverwriteExistingField() throws Exception {
public void testApiKeyPopulation() throws Exception {
User user = new User(randomAlphaOfLengthBetween(4, 12), null, null);
Authentication.RealmRef realmRef = new Authentication.RealmRef(
- AuthenticationField.API_KEY_REALM_NAME, AuthenticationField.API_KEY_REALM_TYPE, "_node_name");
+ AuthenticationField.API_KEY_REALM_NAME,
+ AuthenticationField.API_KEY_REALM_TYPE,
+ "_node_name"
+ );
final Map authMetadata = new HashMap<>();
authMetadata.put(AuthenticationField.API_KEY_ID_KEY, "api_key_id");
@@ -325,8 +328,10 @@ public void testApiKeyPopulation() throws Exception {
authMetadata.put(AuthenticationField.API_KEY_CREATOR_REALM_TYPE, "creator_realm_type");
final Map apiKeyMetadata = ApiKeyTests.randomMetadata();
if (apiKeyMetadata != null) {
- authMetadata.put(AuthenticationField.API_KEY_METADATA_KEY,
- XContentTestUtils.convertToXContent(apiKeyMetadata, XContentType.JSON));
+ authMetadata.put(
+ AuthenticationField.API_KEY_METADATA_KEY,
+ XContentTestUtils.convertToXContent(apiKeyMetadata, XContentType.JSON)
+ );
}
Authentication auth = new Authentication(user, realmRef, null, Version.CURRENT, AuthenticationType.API_KEY, authMetadata);
@@ -363,7 +368,10 @@ public void testApiKeyPopulation() throws Exception {
public void testWillNotOverwriteExistingApiKeyAndRealm() throws Exception {
User user = new User(randomAlphaOfLengthBetween(4, 12), null, null);
Authentication.RealmRef realmRef = new Authentication.RealmRef(
- AuthenticationField.API_KEY_REALM_NAME, AuthenticationField.API_KEY_REALM_TYPE, "_node_name");
+ AuthenticationField.API_KEY_REALM_NAME,
+ AuthenticationField.API_KEY_REALM_TYPE,
+ "_node_name"
+ );
final Map authMetadata = new HashMap<>();
authMetadata.put(AuthenticationField.API_KEY_ID_KEY, "api_key_id");
@@ -372,8 +380,10 @@ public void testWillNotOverwriteExistingApiKeyAndRealm() throws Exception {
authMetadata.put(AuthenticationField.API_KEY_CREATOR_REALM_TYPE, "creator_realm_type");
final Map apiKeyMetadata = ApiKeyTests.randomMetadata();
if (apiKeyMetadata != null) {
- authMetadata.put(AuthenticationField.API_KEY_METADATA_KEY,
- XContentTestUtils.convertToXContent(apiKeyMetadata, XContentType.JSON));
+ authMetadata.put(
+ AuthenticationField.API_KEY_METADATA_KEY,
+ XContentTestUtils.convertToXContent(apiKeyMetadata, XContentType.JSON)
+ );
}
Authentication auth = new Authentication(user, realmRef, null, Version.CURRENT, AuthenticationType.API_KEY, authMetadata);
From 2c156450f1bb1a457ae441bd588d70e2bea172f5 Mon Sep 17 00:00:00 2001
From: Justin Cranford
Date: Thu, 28 Oct 2021 16:38:41 -0400
Subject: [PATCH 24/25] Put null instead of remove for API KEY name
---
.../elasticsearch/xpack/security/authc/ApiKeyServiceTests.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/ApiKeyServiceTests.java b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/ApiKeyServiceTests.java
index f9e76f0723366..ba9b0a3a5327f 100644
--- a/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/ApiKeyServiceTests.java
+++ b/x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/authc/ApiKeyServiceTests.java
@@ -1528,7 +1528,7 @@ public static Authentication createApiKeyAuthentication(
// simulate authentication with nameless API Key, see https://github.com/elastic/elasticsearch/issues/59484
assert authenticationResult.getStatus() == AuthenticationResult.Status.SUCCESS;
Map authenticationResultMetadata = new HashMap<>(authenticationResult.getMetadata());
- authenticationResultMetadata.remove(AuthenticationField.API_KEY_NAME_KEY);
+ authenticationResultMetadata.put(AuthenticationField.API_KEY_NAME_KEY, null);
authenticationResult = AuthenticationResult.success(authenticationResult.getValue(), authenticationResultMetadata);
}
From 3e4b46873bb2b7c5b4211eba1c2895c32d0c347e Mon Sep 17 00:00:00 2001
From: Justin Cranford
Date: Thu, 28 Oct 2021 16:59:54 -0400
Subject: [PATCH 25/25] Deserialize authentication.api_key.name=null
---
.../security/ingest/SetSecurityUserProcessor.java | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessor.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessor.java
index 216c3bca32124..fcf21acc01f19 100644
--- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessor.java
+++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/ingest/SetSecurityUserProcessor.java
@@ -147,13 +147,11 @@ public IngestDocument execute(IngestDocument ingestDocument) throws Exception {
final Map apiKeyField = existingApiKeyField instanceof Map
? (Map) existingApiKeyField
: new HashMap<>();
- Object apiKeyName = authentication.getMetadata().get(AuthenticationField.API_KEY_NAME_KEY);
- if (apiKeyName != null) {
- apiKeyField.put("name", apiKeyName);
+ if (authentication.getMetadata().containsKey(AuthenticationField.API_KEY_NAME_KEY)) {
+ apiKeyField.put("name", authentication.getMetadata().get(AuthenticationField.API_KEY_NAME_KEY));
}
- Object apiKeyId = authentication.getMetadata().get(AuthenticationField.API_KEY_ID_KEY);
- if (apiKeyId != null) {
- apiKeyField.put("id", apiKeyId);
+ if (authentication.getMetadata().containsKey(AuthenticationField.API_KEY_ID_KEY)) {
+ apiKeyField.put("id", authentication.getMetadata().get(AuthenticationField.API_KEY_ID_KEY));
}
final Map apiKeyMetadata = ApiKeyService.getApiKeyMetadata(authentication);
if (false == apiKeyMetadata.isEmpty()) {