From 7e79110cbfa861df026f7b35ea6778fff1e844d7 Mon Sep 17 00:00:00 2001 From: Yang Wang Date: Wed, 23 Mar 2022 16:52:29 +1100 Subject: [PATCH] Merge AuthenticationContex into Authentication This PR removes the AuthenticationContext class introduced in #80926 and merges its functions into Authentication. It becomes more apparent that the most useful refactoring in #80926 is the new Subject class, which is also what AuthenticationContext provides most of its value. The AuthenticationContext is essentially just a thin wrapper of two subjects which represents the existing Authentication object in a more structured format. The original plan was to replace Authentication with AuthenticationContext. However, it has practical challenges that the usage of Authentication is too wide spread. It's hard to have a series of scoped changes to replace it. Therefore the new plan is to stick with Authentication, agumenting it with subjects similar to what AuthenticationContext has and remove AuthenticationContext. This PR also deprecates methods that should be replaced by methods of Subjects. In future, the plan is to remove the deprecated methods, also rework the User class so it does not need nest another User to represent run-as (which is another main reason for the original refactor #80926). Overall, the new plan makes it easier to spread the work in a few more tightly scoped PRs while achieving the same original goal. --- .../core/security/authc/Authentication.java | 84 +++++++++++--- .../security/authc/AuthenticationContext.java | 105 ------------------ .../profile/ProfileDomainIntegTests.java | 11 +- .../authc/support/ApiKeyGenerator.java | 3 +- .../authz/store/CompositeRolesStore.java | 8 +- .../security/profile/ProfileService.java | 3 +- .../authz/store/CompositeRolesStoreTests.java | 15 ++- 7 files changed, 84 insertions(+), 145 deletions(-) delete mode 100644 x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/AuthenticationContext.java 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 34ce70035a9e0..da818fdf520c1 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 @@ -72,6 +72,9 @@ public class Authentication implements ToXContentObject { private final AuthenticationType type; private final Map metadata; // authentication contains metadata, includes api_key details (including api_key metadata) + private Subject authenticatingSubject; + private Subject effectiveSubject; + public Authentication(User user, RealmRef authenticatedBy, RealmRef lookedUpBy) { this(user, authenticatedBy, lookedUpBy, Version.CURRENT, AuthenticationType.REALM, Collections.emptyMap()); } @@ -109,10 +112,44 @@ public Authentication(StreamInput in) throws IOException { this.assertDomainAssignment(); } + /** + * Get the {@link Subject} that performs the actual authentication. This normally means it provides a credentials. + */ + public Subject getAuthenticatingSubject() { + initializeSubjects(); + return authenticatingSubject; + } + + /** + * Get the {@link Subject} that the authentication effectively represents. It may not be the authenticating subject + * because the authentication subject can run-as another subject. + */ + public Subject getEffectiveSubject() { + initializeSubjects(); + return effectiveSubject; + } + + /** + * Whether the authentication contains a subject run-as another subject. That is, the authentication subject + * is different from the effective subject. + */ + public boolean isRunAs() { + initializeSubjects(); + return authenticatingSubject != effectiveSubject; + } + + /** + * Use {@code getEffectiveSubject().getUser()} instead. + */ + @Deprecated public User getUser() { return user; } + /** + * Use {@code getAuthenticatingSubject().getRealm()} instead. + */ + @Deprecated public RealmRef getAuthenticatedBy() { return authenticatedBy; } @@ -124,7 +161,10 @@ public RealmRef getLookedUpBy() { /** * Get the realm where the effective user comes from. * The effective user is the es-security-runas-user if present or the authenticated user. + * + * Use {@code getEffectiveSubject().getRealm()} instead. */ + @Deprecated public RealmRef getSourceRealm() { return lookedUpBy == null ? authenticatedBy : lookedUpBy; } @@ -231,19 +271,18 @@ public boolean isAuthenticatedWithServiceAccount() { /** * Whether the authenticating user is an API key, including a simple API key or a token created by an API key. - * @return */ public boolean isAuthenticatedAsApiKey() { - final boolean result = AuthenticationField.API_KEY_REALM_TYPE.equals(getAuthenticatedBy().getType()); - assert false == result || AuthenticationField.API_KEY_REALM_NAME.equals(getAuthenticatedBy().getName()); - return result; + initializeSubjects(); + return authenticatingSubject.getType() == Subject.Type.API_KEY; } - public boolean isAuthenticatedAnonymously() { + // TODO: this is not entirely accurate if anonymous user can create a token + private boolean isAuthenticatedAnonymously() { return AuthenticationType.ANONYMOUS.equals(getAuthenticationType()); } - public boolean isAuthenticatedInternally() { + private boolean isAuthenticatedInternally() { return AuthenticationType.INTERNAL.equals(getAuthenticationType()); } @@ -251,10 +290,8 @@ public boolean isAuthenticatedInternally() { * Authenticate with a service account and no run-as */ public boolean isServiceAccount() { - final boolean result = ServiceAccountSettings.REALM_TYPE.equals(getSourceRealm().getType()); - assert false == result || ServiceAccountSettings.REALM_NAME.equals(getSourceRealm().getName()) - : "service account realm name mismatch"; - return result; + initializeSubjects(); + return effectiveSubject.getType() == Subject.Type.SERVICE_ACCOUNT; } /** @@ -262,9 +299,8 @@ public boolean isServiceAccount() { * or a token created by the API key. */ public boolean isApiKey() { - final boolean result = AuthenticationField.API_KEY_REALM_TYPE.equals(getSourceRealm().getType()); - assert false == result || AuthenticationField.API_KEY_REALM_NAME.equals(getSourceRealm().getName()) : "api key realm name mismatch"; - return result; + initializeSubjects(); + return effectiveSubject.getType() == Subject.Type.API_KEY; } /** @@ -321,10 +357,8 @@ public boolean canAccessResourcesOf(Authentication resourceCreatorAuthentication ).containsAll(EnumSet.of(getAuthenticationType(), resourceCreatorAuthentication.getAuthenticationType())) : "cross AuthenticationType comparison for canAccessResourcesOf is not applicable for: " + EnumSet.of(getAuthenticationType(), resourceCreatorAuthentication.getAuthenticationType()); - final AuthenticationContext myAuthContext = AuthenticationContext.fromAuthentication(this); - final AuthenticationContext creatorAuthContext = AuthenticationContext.fromAuthentication(resourceCreatorAuthentication); - final Subject mySubject = myAuthContext.getEffectiveSubject(); - final Subject creatorSubject = creatorAuthContext.getEffectiveSubject(); + final Subject mySubject = getEffectiveSubject(); + final Subject creatorSubject = resourceCreatorAuthentication.getEffectiveSubject(); return mySubject.canAccessResourcesOf(creatorSubject); } @@ -410,6 +444,21 @@ public void toXContentFragment(XContentBuilder builder) throws IOException { } } + private void initializeSubjects() { + if (authenticatingSubject == null) { + if (user.isRunAs()) { + authenticatingSubject = new Subject(user.authenticatedUser(), authenticatedBy, version, metadata); + // The lookup user for run-as currently don't have authentication metadata associated with them because + // lookupUser only returns the User object. The lookup user for authorization delegation does have + // authentication metadata, but the realm does not expose this difference between authenticatingUser and + // delegateUser so effectively this is handled together with the authenticatingSubject not effectiveSubject. + effectiveSubject = new Subject(user, lookedUpBy, version, Map.of()); + } else { + authenticatingSubject = effectiveSubject = new Subject(user, authenticatedBy, version, metadata); + } + } + } + private void assertApiKeyMetadata() { assert (false == isAuthenticatedAsApiKey()) || (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."; @@ -757,6 +806,7 @@ static boolean equivalentRealms(String name1, String type1, String name2, String } } + // TODO: Rename to AuthenticationMethod public enum AuthenticationType { REALM, API_KEY, diff --git a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/AuthenticationContext.java b/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/AuthenticationContext.java deleted file mode 100644 index f9a5ca926170e..0000000000000 --- a/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/AuthenticationContext.java +++ /dev/null @@ -1,105 +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; - -import org.elasticsearch.Version; -import org.elasticsearch.xpack.core.security.user.User; - -import java.util.Map; - -import static org.elasticsearch.xpack.core.security.authc.Authentication.AuthenticationType; -import static org.elasticsearch.xpack.core.security.authc.Authentication.RealmRef; - -public class AuthenticationContext { - - private final Version version; - private final Subject authenticatingSubject; - private final Subject effectiveSubject; - // TODO: Rename to AuthenticationMethod - private final AuthenticationType type; - - private AuthenticationContext( - Version version, - Subject authenticatingSubject, - Subject effectiveSubject, - AuthenticationType authenticationType - ) { - this.version = version; - this.authenticatingSubject = authenticatingSubject; - this.effectiveSubject = effectiveSubject; - this.type = authenticationType; - } - - public boolean isRunAs() { - assert authenticatingSubject != null && effectiveSubject != null; - return authenticatingSubject != effectiveSubject; - } - - public Subject getAuthenticatingSubject() { - return authenticatingSubject; - } - - public Subject getEffectiveSubject() { - return effectiveSubject; - } - - public static AuthenticationContext fromAuthentication(Authentication authentication) { - final Builder builder = new Builder(authentication.getVersion()); - builder.authenticationType(authentication.getAuthenticationType()); - final User user = authentication.getUser(); - if (user.isRunAs()) { - builder.authenticatingSubject(user.authenticatedUser(), authentication.getAuthenticatedBy(), authentication.getMetadata()); - // The lookup user for run-as currently don't have authentication metadata associated with them because - // lookupUser only returns the User object. The lookup user for authorization delegation does have - // authentication metadata, but the realm does not expose this difference between authenticatingUser and - // delegateUser so effectively this is handled together with the authenticatingSubject not effectiveSubject. - builder.effectiveSubject(user, authentication.getLookedUpBy(), Map.of()); - } else { - builder.authenticatingSubject(user, authentication.getAuthenticatedBy(), authentication.getMetadata()); - } - return builder.build(); - } - - public static class Builder { - private final Version version; - private AuthenticationType authenticationType; - private Subject authenticatingSubject; - private Subject effectiveSubject; - - public Builder() { - this(Version.CURRENT); - } - - public Builder(Version version) { - this.version = version; - } - - public Builder authenticationType(AuthenticationType authenticationType) { - this.authenticationType = authenticationType; - return this; - } - - public Builder authenticatingSubject(User authenticatingUser, RealmRef authenticatingRealmRef, Map metadata) { - this.authenticatingSubject = new Subject(authenticatingUser, authenticatingRealmRef, version, metadata); - return this; - } - - public Builder effectiveSubject(User effectiveUser, RealmRef lookupRealmRef, Map metadata) { - this.effectiveSubject = new Subject(effectiveUser, lookupRealmRef, version, metadata); - return this; - } - - public AuthenticationContext build() { - if (effectiveSubject == null) { - effectiveSubject = authenticatingSubject; - } - return new AuthenticationContext(version, authenticatingSubject, effectiveSubject, authenticationType); - } - } - -} diff --git a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/profile/ProfileDomainIntegTests.java b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/profile/ProfileDomainIntegTests.java index b558ddcbb30c6..776d24c7b7232 100644 --- a/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/profile/ProfileDomainIntegTests.java +++ b/x-pack/plugin/security/src/internalClusterTest/java/org/elasticsearch/xpack/security/profile/ProfileDomainIntegTests.java @@ -21,7 +21,6 @@ import org.elasticsearch.xpack.core.security.action.user.PutUserAction; import org.elasticsearch.xpack.core.security.action.user.PutUserRequest; import org.elasticsearch.xpack.core.security.authc.Authentication; -import org.elasticsearch.xpack.core.security.authc.AuthenticationContext; import org.elasticsearch.xpack.core.security.authc.AuthenticationTests; import org.elasticsearch.xpack.core.security.authc.RealmConfig; import org.elasticsearch.xpack.core.security.authc.RealmDomain; @@ -143,7 +142,7 @@ public void testGetProfileByAuthenticationUnderDomain() { ), null ); - final Subject subject = AuthenticationContext.fromAuthentication(authentication).getEffectiveSubject(); + final Subject subject = authentication.getEffectiveSubject(); // Profile does not exist yet final PlainActionFuture future1 = new PlainActionFuture<>(); @@ -189,7 +188,7 @@ public void testGetProfileByAuthenticationDomainless() { new Authentication.RealmRef(realmIdentifier1.getName(), realmIdentifier1.getType(), nodeName), null ); - final Subject subject1 = AuthenticationContext.fromAuthentication(authentication1).getEffectiveSubject(); + final Subject subject1 = authentication1.getEffectiveSubject(); final PlainActionFuture future1 = new PlainActionFuture<>(); profileService.searchVersionedDocumentForSubject(subject1, future1); @@ -206,7 +205,7 @@ public void testGetProfileByAuthenticationDomainless() { new Authentication.RealmRef(realmIdentifier2.getName(), realmIdentifier2.getType(), nodeName, realmDomain1), null ); - final Subject subject2 = AuthenticationContext.fromAuthentication(authentication2).getEffectiveSubject(); + final Subject subject2 = authentication2.getEffectiveSubject(); final PlainActionFuture future2 = new PlainActionFuture<>(); profileService.searchVersionedDocumentForSubject(subject2, future2); @@ -219,7 +218,7 @@ public void testGetProfileByAuthenticationDomainless() { new Authentication.RealmRef(realmIdentifier2.getName(), realmIdentifier2.getType(), nodeName), null ); - final Subject subject3 = AuthenticationContext.fromAuthentication(authentication3).getEffectiveSubject(); + final Subject subject3 = authentication3.getEffectiveSubject(); final PlainActionFuture future3 = new PlainActionFuture<>(); profileService.searchVersionedDocumentForSubject(subject3, future3); @@ -406,7 +405,7 @@ public void testProfileDocumentPassCanAccessResourceCheck() { authentication = authentication.token(); } } - final Subject subject = AuthenticationContext.fromAuthentication(authentication).getEffectiveSubject(); + final Subject subject = authentication.getEffectiveSubject(); final ProfileService profileService = getInstanceFromRandomNode(ProfileService.class); final PlainActionFuture future1 = new PlainActionFuture<>(); profileService.activateProfile(authentication, future1); diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/support/ApiKeyGenerator.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/support/ApiKeyGenerator.java index 8b157a14b6631..619b6cbbc9c48 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/support/ApiKeyGenerator.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/support/ApiKeyGenerator.java @@ -14,7 +14,6 @@ import org.elasticsearch.xpack.core.security.action.apikey.CreateApiKeyRequest; import org.elasticsearch.xpack.core.security.action.apikey.CreateApiKeyResponse; import org.elasticsearch.xpack.core.security.authc.Authentication; -import org.elasticsearch.xpack.core.security.authc.AuthenticationContext; import org.elasticsearch.xpack.core.security.authc.Subject; import org.elasticsearch.xpack.core.security.authz.RoleDescriptor; import org.elasticsearch.xpack.core.security.authz.support.DLSRoleQueryValidator; @@ -54,7 +53,7 @@ public void generateApiKey(Authentication authentication, CreateApiKeyRequest re apiKeyService.createApiKey(authentication, request, roleDescriptors, listener); }, listener::onFailure); - final Subject effectiveSubject = AuthenticationContext.fromAuthentication(authentication).getEffectiveSubject(); + final Subject effectiveSubject = authentication.getEffectiveSubject(); // Retain current behaviour that User of an API key authentication has no roles if (effectiveSubject.getType() == Subject.Type.API_KEY) { diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStore.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStore.java index 246a7a6d2bbec..9940513bc6a2a 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStore.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authz/store/CompositeRolesStore.java @@ -26,7 +26,6 @@ import org.elasticsearch.core.Tuple; import org.elasticsearch.license.XPackLicenseState; import org.elasticsearch.xpack.core.security.authc.Authentication; -import org.elasticsearch.xpack.core.security.authc.AuthenticationContext; import org.elasticsearch.xpack.core.security.authc.Subject; import org.elasticsearch.xpack.core.security.authz.RestrictedIndices; import org.elasticsearch.xpack.core.security.authz.RoleDescriptor; @@ -170,11 +169,10 @@ public void providersChanged() { } public void getRoles(Authentication authentication, ActionListener> roleActionListener) { - final AuthenticationContext authenticationContext = AuthenticationContext.fromAuthentication(authentication); - getRole(authenticationContext.getEffectiveSubject(), ActionListener.wrap(role -> { - if (authenticationContext.isRunAs()) { + getRole(authentication.getEffectiveSubject(), ActionListener.wrap(role -> { + if (authentication.isRunAs()) { getRole( - authenticationContext.getAuthenticatingSubject(), + authentication.getAuthenticatingSubject(), ActionListener.wrap( authenticatingRole -> roleActionListener.onResponse(new Tuple<>(role, authenticatingRole)), roleActionListener::onFailure diff --git a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/profile/ProfileService.java b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/profile/ProfileService.java index 723cb7f64a3c7..85306fdf688dd 100644 --- a/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/profile/ProfileService.java +++ b/x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/profile/ProfileService.java @@ -56,7 +56,6 @@ import org.elasticsearch.xpack.core.security.action.profile.SearchProfilesResponse; import org.elasticsearch.xpack.core.security.action.profile.UpdateProfileDataRequest; import org.elasticsearch.xpack.core.security.authc.Authentication; -import org.elasticsearch.xpack.core.security.authc.AuthenticationContext; import org.elasticsearch.xpack.core.security.authc.Subject; import org.elasticsearch.xpack.core.security.user.User; import org.elasticsearch.xpack.security.support.SecurityIndexManager; @@ -116,7 +115,7 @@ public void getProfile(String uid, @Nullable Set dataKeys, ActionListene * to submit the request. */ public void activateProfile(Authentication authentication, ActionListener listener) { - final Subject subject = AuthenticationContext.fromAuthentication(authentication).getEffectiveSubject(); + final Subject subject = authentication.getEffectiveSubject(); if (Subject.Type.USER != subject.getType()) { listener.onFailure( new IllegalArgumentException( 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 53d474a50a72f..98218b9093334 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,7 +50,6 @@ 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.AuthenticationContext; import org.elasticsearch.xpack.core.security.authc.AuthenticationField; import org.elasticsearch.xpack.core.security.authc.Subject; import org.elasticsearch.xpack.core.security.authz.RoleDescriptor; @@ -1366,7 +1365,7 @@ public void testApiKeyAuthUsesApiKeyService() throws Exception { ); PlainActionFuture roleFuture = new PlainActionFuture<>(); - compositeRolesStore.getRole(AuthenticationContext.fromAuthentication(authentication).getEffectiveSubject(), roleFuture); + compositeRolesStore.getRole(authentication.getEffectiveSubject(), roleFuture); Role role = roleFuture.actionGet(); assertThat(effectiveRoleDescriptors.get(), is(nullValue())); @@ -1440,7 +1439,7 @@ public void testApiKeyAuthUsesApiKeyServiceWithScopedRole() throws Exception { final String apiKeyId = (String) authentication.getMetadata().get(API_KEY_ID_KEY); PlainActionFuture roleFuture = new PlainActionFuture<>(); - compositeRolesStore.getRole(AuthenticationContext.fromAuthentication(authentication).getEffectiveSubject(), roleFuture); + compositeRolesStore.getRole(authentication.getEffectiveSubject(), roleFuture); Role role = roleFuture.actionGet(); assertThat(role.checkClusterAction("cluster:admin/foo", Empty.INSTANCE, mock(Authentication.class)), is(false)); assertThat(effectiveRoleDescriptors.get(), is(nullValue())); @@ -1509,7 +1508,7 @@ public void testGetRolesForRunAs() { ) ); final PlainActionFuture future1 = new PlainActionFuture<>(); - compositeRolesStore.getRole(AuthenticationContext.fromAuthentication(authentication1).getAuthenticatingSubject(), future1); + compositeRolesStore.getRole(authentication1.getAuthenticatingSubject(), future1); future1.actionGet(); verify(apiKeyService).parseRoleDescriptorsBytes(apiKeyId, limitedByRoleDescriptorBytes, RoleReference.ApiKeyRoleType.LIMITED_BY); @@ -1530,7 +1529,7 @@ public void testGetRolesForRunAs() { listener.onResponse(new RoleDescriptor(authenticatedUser2.principal(), null, null, null)); return null; }).when(serviceAccountService).getRoleDescriptorForPrincipal(eq(authenticatedUser2.principal()), anyActionListener()); - compositeRolesStore.getRole(AuthenticationContext.fromAuthentication(authentication2).getAuthenticatingSubject(), future2); + compositeRolesStore.getRole(authentication2.getAuthenticatingSubject(), future2); future2.actionGet(); verify(serviceAccountService).getRoleDescriptorForPrincipal(eq(authenticatedUser2.principal()), anyActionListener()); } @@ -1700,7 +1699,7 @@ public void testCacheEntryIsReusedForIdenticalApiKeyRoles() { ); PlainActionFuture roleFuture = new PlainActionFuture<>(); - compositeRolesStore.getRole(AuthenticationContext.fromAuthentication(authentication).getEffectiveSubject(), roleFuture); + compositeRolesStore.getRole(authentication.getEffectiveSubject(), roleFuture); roleFuture.actionGet(); assertThat(effectiveRoleDescriptors.get(), is(nullValue())); verify(apiKeyService).parseRoleDescriptorsBytes("key-id-1", roleBytes, RoleReference.ApiKeyRoleType.ASSIGNED); @@ -1721,7 +1720,7 @@ public void testCacheEntryIsReusedForIdenticalApiKeyRoles() { metadata2 ); roleFuture = new PlainActionFuture<>(); - compositeRolesStore.getRole(AuthenticationContext.fromAuthentication(authentication).getEffectiveSubject(), roleFuture); + compositeRolesStore.getRole(authentication.getEffectiveSubject(), roleFuture); roleFuture.actionGet(); assertThat(effectiveRoleDescriptors.get(), is(nullValue())); verify(apiKeyService, never()).parseRoleDescriptorsBytes(eq("key-id-2"), any(BytesReference.class), any()); @@ -1742,7 +1741,7 @@ public void testCacheEntryIsReusedForIdenticalApiKeyRoles() { metadata3 ); roleFuture = new PlainActionFuture<>(); - compositeRolesStore.getRole(AuthenticationContext.fromAuthentication(authentication).getEffectiveSubject(), roleFuture); + compositeRolesStore.getRole(authentication.getEffectiveSubject(), roleFuture); roleFuture.actionGet(); assertThat(effectiveRoleDescriptors.get(), is(nullValue())); verify(apiKeyService).parseRoleDescriptorsBytes("key-id-3", anotherRoleBytes, RoleReference.ApiKeyRoleType.ASSIGNED);