Skip to content

Commit

Permalink
Remove deprecated Authentication#getMetadata method
Browse files Browse the repository at this point in the history
This PR removes the deprecated Authentication#getMetadata method and
replaces its usages with #getAuthenticatingSubject#getMetadata.

Relates: elastic#88494
  • Loading branch information
ywangd committed Oct 24, 2022
1 parent 1f265eb commit 2830de8
Show file tree
Hide file tree
Showing 14 changed files with 127 additions and 64 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -222,14 +222,6 @@ public Version getVersion() {
return effectiveSubject.getVersion();
}

/**
* Use {@code getAuthenticatingSubject().getMetadata()} instead.
*/
@Deprecated
public Map<String, Object> getMetadata() {
return authenticatingSubject.getMetadata();
}

/**
* Returns a new {@code Authentication}, like this one, but which is compatible with older version nodes.
* This is commonly employed when the {@code Authentication} is serialized across cluster nodes with mixed versions.
Expand Down Expand Up @@ -510,7 +502,7 @@ public void writeTo(StreamOutput out) throws IOException {
out.writeBoolean(false);
}
out.writeVInt(type.ordinal());
out.writeGenericMap(getMetadata());
out.writeGenericMap(getAuthenticatingSubject().getMetadata());
}

/**
Expand Down Expand Up @@ -575,9 +567,9 @@ public void toXContentFragment(XContentBuilder builder) throws IOException {
builder.field(User.Fields.FULL_NAME.getPreferredName(), user.fullName());
builder.field(User.Fields.EMAIL.getPreferredName(), user.email());
if (isServiceAccount()) {
final String tokenName = (String) getMetadata().get(ServiceAccountSettings.TOKEN_NAME_FIELD);
final String tokenName = (String) getAuthenticatingSubject().getMetadata().get(ServiceAccountSettings.TOKEN_NAME_FIELD);
assert tokenName != null : "token name cannot be null";
final String tokenSource = (String) getMetadata().get(ServiceAccountSettings.TOKEN_SOURCE_FIELD);
final String tokenSource = (String) getAuthenticatingSubject().getMetadata().get(ServiceAccountSettings.TOKEN_SOURCE_FIELD);
assert tokenSource != null : "token source cannot be null";
builder.field(
User.Fields.TOKEN.getPreferredName(),
Expand Down Expand Up @@ -612,8 +604,8 @@ 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) getMetadata().get(AuthenticationField.API_KEY_ID_KEY);
final String apiKeyName = (String) getMetadata().get(AuthenticationField.API_KEY_NAME_KEY);
final String apiKeyId = (String) getAuthenticatingSubject().getMetadata().get(AuthenticationField.API_KEY_ID_KEY);
final String apiKeyName = (String) getAuthenticatingSubject().getMetadata().get(AuthenticationField.API_KEY_NAME_KEY);
if (apiKeyName == null) {
builder.field("api_key", Map.of("id", apiKeyId));
} else {
Expand Down Expand Up @@ -641,7 +633,8 @@ private void assertInternalConsistency() {
}

// Assert API key metadata
assert (false == isAuthenticatedAsApiKey()) || (this.getMetadata().get(AuthenticationField.API_KEY_ID_KEY) != null)
assert (false == isAuthenticatedAsApiKey())
|| (getAuthenticatingSubject().getMetadata().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 domain assignment
Expand Down Expand Up @@ -910,7 +903,7 @@ private static RealmRef maybeRewriteRealmRef(Version streamVersion, RealmRef rea

@SuppressWarnings("unchecked")
private static Map<String, Object> maybeRewriteMetadataForApiKeyRoleDescriptors(Version streamVersion, Authentication authentication) {
Map<String, Object> metadata = authentication.getMetadata();
Map<String, Object> metadata = authentication.getAuthenticatingSubject().getMetadata();
// If authentication user is an API key or a token created by an API key,
// regardless whether it has run-as, the metadata must contain API key role descriptors
if (authentication.isAuthenticatedAsApiKey()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,9 @@ private static boolean checkIfUserIsOwnerOfApiKeys(
private static boolean isCurrentAuthenticationUsingSameApiKeyIdFromRequest(Authentication authentication, String apiKeyId) {
if (authentication.isApiKey()) {
// API key id from authentication must match the id from request
final String authenticatedApiKeyId = (String) authentication.getMetadata().get(AuthenticationField.API_KEY_ID_KEY);
final String authenticatedApiKeyId = (String) authentication.getAuthenticatingSubject()
.getMetadata()
.get(AuthenticationField.API_KEY_ID_KEY);
if (Strings.hasText(apiKeyId)) {
return apiKeyId.equals(authenticatedApiKeyId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,9 @@ private void assertCanAccessResources(Authentication authentication0, Authentica
public void testToXContentWithApiKey() throws IOException {
final String apiKeyId = randomAlphaOfLength(20);
final Authentication authentication1 = randomApiKeyAuthentication(randomUser(), apiKeyId);
final String apiKeyName = (String) authentication1.getMetadata().get(AuthenticationField.API_KEY_NAME_KEY);
final String apiKeyName = (String) authentication1.getAuthenticatingSubject()
.getMetadata()
.get(AuthenticationField.API_KEY_NAME_KEY);
runWithAuthenticationToXContent(
authentication1,
m -> assertThat(
Expand All @@ -474,10 +476,12 @@ public void testToXContentWithApiKey() throws IOException {

public void testToXContentWithServiceAccount() throws IOException {
final Authentication authentication1 = randomServiceAccountAuthentication();
final String tokenName = (String) authentication1.getMetadata().get(ServiceAccountSettings.TOKEN_NAME_FIELD);
final String tokenName = (String) authentication1.getAuthenticatingSubject()
.getMetadata()
.get(ServiceAccountSettings.TOKEN_NAME_FIELD);
final String tokenType = ServiceAccountSettings.REALM_TYPE
+ "_"
+ authentication1.getMetadata().get(ServiceAccountSettings.TOKEN_SOURCE_FIELD);
+ authentication1.getAuthenticatingSubject().getMetadata().get(ServiceAccountSettings.TOKEN_SOURCE_FIELD);
runWithAuthenticationToXContent(
authentication1,
m -> assertThat(m, hasEntry("token", Map.of("name", tokenName, "type", tokenType)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1608,8 +1608,13 @@ LogEntryBuilder withAuthentication(Authentication authentication) {
logEntry.with(PRINCIPAL_FIELD_NAME, authentication.getUser().principal());
logEntry.with(AUTHENTICATION_TYPE_FIELD_NAME, authentication.getAuthenticationType().toString());
if (authentication.isApiKey()) {
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);
logEntry.with(
API_KEY_ID_FIELD_NAME,
(String) authentication.getAuthenticatingSubject().getMetadata().get(AuthenticationField.API_KEY_ID_KEY)
);
String apiKeyName = (String) authentication.getAuthenticatingSubject()
.getMetadata()
.get(AuthenticationField.API_KEY_NAME_KEY);
if (apiKeyName != null) {
logEntry.with(API_KEY_NAME_FIELD_NAME, apiKeyName);
}
Expand Down Expand Up @@ -1644,10 +1649,15 @@ LogEntryBuilder withAuthentication(Authentication authentication) {
}
// TODO: service token info is logged in a separate authentication field (#84394)
if (authentication.isAuthenticatedWithServiceAccount()) {
logEntry.with(SERVICE_TOKEN_NAME_FIELD_NAME, (String) authentication.getMetadata().get(TOKEN_NAME_FIELD))
logEntry.with(
SERVICE_TOKEN_NAME_FIELD_NAME,
(String) authentication.getAuthenticatingSubject().getMetadata().get(TOKEN_NAME_FIELD)
)
.with(
SERVICE_TOKEN_TYPE_FIELD_NAME,
ServiceAccountSettings.REALM_TYPE + "_" + authentication.getMetadata().get(TOKEN_SOURCE_FIELD)
ServiceAccountSettings.REALM_TYPE
+ "_"
+ authentication.getAuthenticatingSubject().getMetadata().get(TOKEN_SOURCE_FIELD)
);
}
return this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,9 @@ private static String authenticatedUserDescription(Authentication authentication
+ authentication.getAuthenticatingSubject().getUser().principal()
+ "]";
if (authentication.isAuthenticatedAsApiKey()) {
final String apiKeyId = (String) authentication.getMetadata().get(AuthenticationField.API_KEY_ID_KEY);
final String apiKeyId = (String) authentication.getAuthenticatingSubject()
.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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,9 @@ static boolean checkSameUserPermissions(String action, TransportRequest request,
} else if (request instanceof GetApiKeyRequest getApiKeyRequest) {
if (authentication.isApiKey()) {
// if the authentication is an API key then the request must also contain same API key id
String authenticatedApiKeyId = (String) authentication.getMetadata().get(AuthenticationField.API_KEY_ID_KEY);
String authenticatedApiKeyId = (String) authentication.getAuthenticatingSubject()
.getMetadata()
.get(AuthenticationField.API_KEY_ID_KEY);
if (Strings.hasText(getApiKeyRequest.getApiKeyId())) {
// An API key requires manage_api_key privilege or higher to view any limited-by role descriptors
return getApiKeyRequest.getApiKeyId().equals(authenticatedApiKeyId) && false == getApiKeyRequest.withLimitedBy();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,17 @@ public IngestDocument execute(IngestDocument ingestDocument) throws Exception {
final Map<String, Object> apiKeyField = existingApiKeyField instanceof Map
? (Map<String, Object>) existingApiKeyField
: new HashMap<>();
if (authentication.getMetadata().containsKey(AuthenticationField.API_KEY_NAME_KEY)) {
apiKeyField.put("name", authentication.getMetadata().get(AuthenticationField.API_KEY_NAME_KEY));
if (authentication.getAuthenticatingSubject().getMetadata().containsKey(AuthenticationField.API_KEY_NAME_KEY)) {
apiKeyField.put(
"name",
authentication.getAuthenticatingSubject().getMetadata().get(AuthenticationField.API_KEY_NAME_KEY)
);
}
if (authentication.getMetadata().containsKey(AuthenticationField.API_KEY_ID_KEY)) {
apiKeyField.put("id", authentication.getMetadata().get(AuthenticationField.API_KEY_ID_KEY));
if (authentication.getAuthenticatingSubject().getMetadata().containsKey(AuthenticationField.API_KEY_ID_KEY)) {
apiKeyField.put(
"id",
authentication.getAuthenticatingSubject().getMetadata().get(AuthenticationField.API_KEY_ID_KEY)
);
}
final Map<String, Object> apiKeyMetadata = ApiKeyService.getApiKeyMetadata(authentication);
if (false == apiKeyMetadata.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ public static ApiKeyBoolQueryBuilder build(QueryBuilder queryBuilder, @Nullable

if (authentication != null) {
if (authentication.isApiKey()) {
final String apiKeyId = (String) authentication.getMetadata().get(AuthenticationField.API_KEY_ID_KEY);
final String apiKeyId = (String) authentication.getAuthenticatingSubject()
.getMetadata()
.get(AuthenticationField.API_KEY_ID_KEY);
assert apiKeyId != null : "api key id must be present in the metadata";
finalQuery.filter(QueryBuilders.idsQuery().addIds(apiKeyId));
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -194,46 +194,56 @@ public void testExecuteAfterRewritingAuthenticationWillConditionallyRewriteNewAp
Authentication authentication = securityContext.getAuthentication();
assertEquals(
Map.of("a role", Map.of("cluster", List.of("all"))),
authentication.getMetadata().get(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY)
authentication.getAuthenticatingSubject().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)
authentication.getAuthenticatingSubject().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
securityContext.executeAfterRewritingAuthentication(originalCtx -> {
Authentication authentication = securityContext.getAuthentication();
assertSame(original.getMetadata(), authentication.getMetadata());
assertSame(original.getAuthenticatingSubject().getMetadata(), authentication.getAuthenticatingSubject().getMetadata());
}, VersionUtils.randomVersionBetween(random(), VERSION_API_KEY_ROLES_AS_BYTES, Version.CURRENT));
}

public void testExecuteAfterRewritingAuthenticationWillConditionallyRewriteOldApiKeyMetadata() throws IOException {
final Authentication original = AuthenticationTestHelper.builder().apiKey().version(Version.V_7_8_0).build();

// original authentication has the old style of role descriptor maps
assertThat(original.getMetadata().get(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY), instanceOf(Map.class));
assertThat(original.getMetadata().get(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY), instanceOf(Map.class));
assertThat(
original.getAuthenticatingSubject().getMetadata().get(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY),
instanceOf(Map.class)
);
assertThat(
original.getAuthenticatingSubject().getMetadata().get(AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY),
instanceOf(Map.class)
);

original.writeToContext(threadContext);

// If target is old node, no need to rewrite old style API key metadata
securityContext.executeAfterRewritingAuthentication(originalCtx -> {
Authentication authentication = securityContext.getAuthentication();
assertSame(original.getMetadata(), authentication.getMetadata());
assertSame(original.getAuthenticatingSubject().getMetadata(), authentication.getAuthenticatingSubject().getMetadata());
}, Version.V_7_8_0);

// If target is new node, ensure old map style API key metadata is rewritten to bytesreference
securityContext.executeAfterRewritingAuthentication(originalCtx -> {
Authentication authentication = securityContext.getAuthentication();
List.of(AuthenticationField.API_KEY_ROLE_DESCRIPTORS_KEY, AuthenticationField.API_KEY_LIMITED_ROLE_DESCRIPTORS_KEY)
.forEach(key -> {
assertThat(authentication.getMetadata().get(key), instanceOf(BytesReference.class));
assertThat(authentication.getAuthenticatingSubject().getMetadata().get(key), instanceOf(BytesReference.class));

assertThat(
XContentHelper.convertToMap((BytesReference) authentication.getMetadata().get(key), false, XContentType.JSON).v2(),
equalTo(original.getMetadata().get(key))
XContentHelper.convertToMap(
(BytesReference) authentication.getAuthenticatingSubject().getMetadata().get(key),
false,
XContentType.JSON
).v2(),
equalTo(original.getAuthenticatingSubject().getMetadata().get(key))
);
});
}, VersionUtils.randomVersionBetween(random(), VERSION_API_KEY_ROLES_AS_BYTES, Version.CURRENT));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ public void onFailure(Exception e) {
assertThat(auth.getLookedUpBy(), sameInstance(auth.getLookedUpBy()));
assertThat(auth.getVersion(), sameInstance(auth.getVersion()));
assertThat(auth.getAuthenticationType(), sameInstance(auth.getAuthenticationType()));
assertThat(auth.getMetadata(), sameInstance(auth.getMetadata()));
assertThat(auth.getAuthenticatingSubject().getMetadata(), sameInstance(auth.getAuthenticatingSubject().getMetadata()));
} else {
assertThat(responseRef.get().authentication(), sameInstance(authentication));
}
Expand Down Expand Up @@ -200,7 +200,7 @@ public void onFailure(Exception e) {
assertThat(auth.getLookedUpBy(), sameInstance(auth.getLookedUpBy()));
assertThat(auth.getVersion(), sameInstance(auth.getVersion()));
assertThat(auth.getAuthenticationType(), sameInstance(auth.getAuthenticationType()));
assertThat(auth.getMetadata(), sameInstance(auth.getMetadata()));
assertThat(auth.getAuthenticatingSubject().getMetadata(), sameInstance(auth.getAuthenticatingSubject().getMetadata()));
} else {
assertThat(responseRef.get().authentication(), sameInstance(authentication));
}
Expand Down
Loading

0 comments on commit 2830de8

Please sign in to comment.