mirror of
https://github.com/honeymoose/OpenSearch.git
synced 2025-02-28 16:09:10 +00:00
[Backport][API keys] Add full_name and email to API key doc and use them to populate authing User (#61354) (#61403)
The API key document currently doesn't include the user's full_name or email attributes, and as a result, when those attributes return `null` when hitting `GET`ing `/_security/_authenticate`, and in the SAML response from the [IdP Plugin](https://github.com/elastic/elasticsearch/pull/54046). This changeset adds those fields to the document and extracts them to fill in the User when authenticating. They're effectively going to be a snapshot of the User from when the key was created, but this is in line with roles and metadata as well. Signed-off-by: lloydmeta <lloydmeta@gmail.com>
This commit is contained in:
parent
e09058df1a
commit
cb83e7011c
@ -188,6 +188,13 @@
|
||||
"principal" : {
|
||||
"type": "keyword"
|
||||
},
|
||||
"full_name" : {
|
||||
"type" : "text"
|
||||
},
|
||||
"email" : {
|
||||
"type" : "text",
|
||||
"analyzer" : "email"
|
||||
},
|
||||
"metadata" : {
|
||||
"type" : "object",
|
||||
"dynamic" : false
|
||||
|
@ -302,6 +302,8 @@ public class ApiKeyService {
|
||||
.field("version", version.id)
|
||||
.startObject("creator")
|
||||
.field("principal", authentication.getUser().principal())
|
||||
.field("full_name", authentication.getUser().fullName())
|
||||
.field("email", authentication.getUser().email())
|
||||
.field("metadata", authentication.getUser().metadata())
|
||||
.field("realm", authentication.getSourceRealm().getName())
|
||||
.field("realm_type", authentication.getSourceRealm().getType())
|
||||
@ -597,8 +599,10 @@ public class ApiKeyService {
|
||||
ActionListener<AuthenticationResult> listener) {
|
||||
if (apiKeyDoc.expirationTime == -1 || Instant.ofEpochMilli(apiKeyDoc.expirationTime).isAfter(clock.instant())) {
|
||||
final String principal = Objects.requireNonNull((String) apiKeyDoc.creator.get("principal"));
|
||||
final String fullName = (String) apiKeyDoc.creator.get("full_name");
|
||||
final String email = (String) apiKeyDoc.creator.get("email");
|
||||
Map<String, Object> metadata = (Map<String, Object>) apiKeyDoc.creator.get("metadata");
|
||||
final User apiKeyUser = new User(principal, Strings.EMPTY_ARRAY, null, null, metadata, true);
|
||||
final User apiKeyUser = new User(principal, Strings.EMPTY_ARRAY, fullName, email, metadata, true);
|
||||
final Map<String, Object> 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"));
|
||||
|
@ -196,9 +196,26 @@ public class ApiKeyServiceTests extends ESTestCase {
|
||||
|
||||
final User user;
|
||||
if (randomBoolean()) {
|
||||
user = new User("hulk", new String[] { "superuser" }, new User("authenticated_user", new String[] { "other" }));
|
||||
user = new User(
|
||||
new User(
|
||||
"hulk",
|
||||
new String[]{"superuser"},
|
||||
"Bruce Banner",
|
||||
"hulk@test.com",
|
||||
org.elasticsearch.common.collect.Map.of(),
|
||||
true
|
||||
),
|
||||
new User("authenticated_user", new String[]{"other"})
|
||||
);
|
||||
} else {
|
||||
user = new User("hulk", new String[] { "superuser" });
|
||||
user = new User(
|
||||
"hulk",
|
||||
new String[]{"superuser"},
|
||||
"Bruce Banner",
|
||||
"hulk@test.com",
|
||||
org.elasticsearch.common.collect.Map.of(),
|
||||
true
|
||||
);
|
||||
}
|
||||
mockKeyDocument(service, id, key, user);
|
||||
|
||||
@ -206,6 +223,8 @@ public class ApiKeyServiceTests extends ESTestCase {
|
||||
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.getMetadata().get(ApiKeyService.API_KEY_CREATOR_REALM_NAME), is("realm1"));
|
||||
assertThat(auth.getMetadata().get(ApiKeyService.API_KEY_CREATOR_REALM_TYPE), is("native"));
|
||||
assertThat(auth.getMetadata().get(ApiKeyService.API_KEY_ID_KEY), is(id));
|
||||
@ -377,6 +396,8 @@ public class ApiKeyServiceTests extends ESTestCase {
|
||||
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.getMetadata().get(API_KEY_ROLE_DESCRIPTORS_KEY), equalTo(apiKeyDoc.roleDescriptorsBytes));
|
||||
@ -391,6 +412,8 @@ public class ApiKeyServiceTests extends ESTestCase {
|
||||
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.getMetadata().get(API_KEY_ROLE_DESCRIPTORS_KEY), equalTo(apiKeyDoc.roleDescriptorsBytes));
|
||||
@ -923,6 +946,8 @@ public class ApiKeyServiceTests extends ESTestCase {
|
||||
sourceMap.put("limited_by_role_descriptors", Collections.singletonMap("limited role", Collections.singletonMap("cluster", "all")));
|
||||
Map<String, Object> creatorMap = new HashMap<>();
|
||||
creatorMap.put("principal", "test_user");
|
||||
creatorMap.put("full_name", "test user");
|
||||
creatorMap.put("email", "test@user.com");
|
||||
creatorMap.put("metadata", Collections.emptyMap());
|
||||
sourceMap.put("creator", creatorMap);
|
||||
sourceMap.put("api_key_invalidated", false);
|
||||
@ -954,8 +979,13 @@ public class ApiKeyServiceTests extends ESTestCase {
|
||||
new BytesArray("{\"a role\": {\"cluster\": [\"all\"]}}"),
|
||||
new BytesArray("{\"limited role\": {\"cluster\": [\"all\"]}}"),
|
||||
org.elasticsearch.common.collect.Map.of(
|
||||
"principal", "test_user", "realm", "realm1", "realm_type", "realm_type1", "metadata",
|
||||
org.elasticsearch.common.collect.Map.of())
|
||||
"principal", "test_user",
|
||||
"full_name", "test user",
|
||||
"email", "test@user.com",
|
||||
"realm", "realm1",
|
||||
"realm_type", "realm_type1",
|
||||
"metadata", org.elasticsearch.common.collect.Map.of()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1421,6 +1421,8 @@ public class AuthenticationServiceTests extends ESTestCase {
|
||||
source.put("version", 0);
|
||||
Map<String, Object> creatorMap = new HashMap<>();
|
||||
creatorMap.put("principal", "johndoe");
|
||||
creatorMap.put("full_name", "john doe");
|
||||
creatorMap.put("email", "john@doe.com");
|
||||
creatorMap.put("metadata", Collections.emptyMap());
|
||||
creatorMap.put("realm", "auth realm");
|
||||
source.put("creator", creatorMap);
|
||||
@ -1439,6 +1441,8 @@ public class AuthenticationServiceTests extends ESTestCase {
|
||||
threadContext.putHeader("Authorization", headerValue);
|
||||
final Authentication authentication = authenticateBlocking("_action", transportRequest, null);
|
||||
assertThat(authentication.getUser().principal(), is("johndoe"));
|
||||
assertThat(authentication.getUser().fullName(), is("john doe"));
|
||||
assertThat(authentication.getUser().email(), is("john@doe.com"));
|
||||
assertThat(authentication.getAuthenticationType(), is(AuthenticationType.API_KEY));
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user