Skip to content

Commit 6966cea

Browse files
committed
Authenticator
1 parent 7bfb559 commit 6966cea

File tree

11 files changed

+116
-167
lines changed

11 files changed

+116
-167
lines changed

x-pack/plugin/core/src/main/java/module-info.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@
230230
exports org.elasticsearch.xpack.core.watcher.trigger;
231231
exports org.elasticsearch.xpack.core.watcher.watch;
232232
exports org.elasticsearch.xpack.core.watcher;
233-
exports org.elasticsearch.xpack.core.security.authc.cloud;
233+
exports org.elasticsearch.xpack.core.security.authc.apikey;
234234

235235
provides org.elasticsearch.action.admin.cluster.node.info.ComponentVersionNumber
236236
with

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/SecurityExtension.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
import org.elasticsearch.watcher.ResourceWatcherService;
1717
import org.elasticsearch.xpack.core.security.authc.AuthenticationFailureHandler;
1818
import org.elasticsearch.xpack.core.security.authc.Realm;
19-
import org.elasticsearch.xpack.core.security.authc.cloud.CloudApiKeyService;
19+
import org.elasticsearch.xpack.core.security.authc.apikey.CustomApiKeyAuthenticator;
2020
import org.elasticsearch.xpack.core.security.authc.service.NodeLocalServiceAccountTokenStore;
2121
import org.elasticsearch.xpack.core.security.authc.service.ServiceAccountTokenStore;
2222
import org.elasticsearch.xpack.core.security.authc.support.UserRoleMapper;
@@ -129,7 +129,7 @@ default ServiceAccountTokenStore getServiceAccountTokenStore(SecurityComponents
129129
return null;
130130
}
131131

132-
default CloudApiKeyService getCloudApiKeyService(SecurityComponents components) {
132+
default CustomApiKeyAuthenticator getCustomApiKeyAuthenticator(SecurityComponents components) {
133133
return null;
134134
}
135135

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
package org.elasticsearch.xpack.core.security.authc.apikey;
9+
10+
import org.elasticsearch.action.ActionListener;
11+
import org.elasticsearch.common.settings.SecureString;
12+
import org.elasticsearch.core.Nullable;
13+
import org.elasticsearch.xpack.core.security.authc.Authentication;
14+
import org.elasticsearch.xpack.core.security.authc.AuthenticationResult;
15+
import org.elasticsearch.xpack.core.security.authc.AuthenticationToken;
16+
17+
public interface CustomApiKeyAuthenticator {
18+
String name();
19+
20+
AuthenticationToken extractCredentials(@Nullable SecureString apiKeyCredentials);
21+
22+
void authenticate(@Nullable AuthenticationToken authenticationToken, ActionListener<AuthenticationResult<Authentication>> listener);
23+
24+
class Noop implements CustomApiKeyAuthenticator {
25+
@Override
26+
public String name() {
27+
return "noop";
28+
}
29+
30+
@Override
31+
public AuthenticationToken extractCredentials(@Nullable SecureString apiKeyCredentials) {
32+
return null;
33+
}
34+
35+
@Override
36+
public void authenticate(
37+
@Nullable AuthenticationToken authenticationToken,
38+
ActionListener<AuthenticationResult<Authentication>> listener
39+
) {
40+
listener.onResponse(AuthenticationResult.notHandled());
41+
}
42+
}
43+
}

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/cloud/CloudApiKey.java

Lines changed: 0 additions & 50 deletions
This file was deleted.

x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authc/cloud/CloudApiKeyService.java

Lines changed: 0 additions & 33 deletions
This file was deleted.

x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/Security.java

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@
208208
import org.elasticsearch.xpack.core.security.authc.RealmConfig;
209209
import org.elasticsearch.xpack.core.security.authc.RealmSettings;
210210
import org.elasticsearch.xpack.core.security.authc.Subject;
211-
import org.elasticsearch.xpack.core.security.authc.cloud.CloudApiKeyService;
211+
import org.elasticsearch.xpack.core.security.authc.apikey.CustomApiKeyAuthenticator;
212212
import org.elasticsearch.xpack.core.security.authc.service.NodeLocalServiceAccountTokenStore;
213213
import org.elasticsearch.xpack.core.security.authc.service.ServiceAccountTokenStore;
214214
import org.elasticsearch.xpack.core.security.authc.support.UserRoleMapper;
@@ -1102,9 +1102,9 @@ Collection<Object> createComponents(
11021102
operatorPrivilegesService.set(OperatorPrivileges.NOOP_OPERATOR_PRIVILEGES_SERVICE);
11031103
}
11041104

1105-
final CloudApiKeyService cloudApiKeyService = createCloudApiKeyService(extensionComponents);
1105+
final CustomApiKeyAuthenticator customApiKeyAuthenticator = createCustomApiKeyAuthenticator(extensionComponents);
11061106

1107-
components.add(cloudApiKeyService);
1107+
components.add(customApiKeyAuthenticator);
11081108

11091109
authcService.set(
11101110
new AuthenticationService(
@@ -1118,7 +1118,7 @@ Collection<Object> createComponents(
11181118
apiKeyService,
11191119
serviceAccountService,
11201120
operatorPrivilegesService.get(),
1121-
cloudApiKeyService,
1121+
customApiKeyAuthenticator,
11221122
telemetryProvider.getMeterRegistry()
11231123
)
11241124
);
@@ -1254,34 +1254,34 @@ Collection<Object> createComponents(
12541254
return components;
12551255
}
12561256

1257-
private CloudApiKeyService createCloudApiKeyService(SecurityExtension.SecurityComponents extensionComponents) {
1258-
final SetOnce<CloudApiKeyService> cloudApiKeyServiceSetOnce = new SetOnce<>();
1257+
private CustomApiKeyAuthenticator createCustomApiKeyAuthenticator(SecurityExtension.SecurityComponents extensionComponents) {
1258+
final SetOnce<CustomApiKeyAuthenticator> customApiKeyAuthenticatorSetOnce = new SetOnce<>();
12591259
for (var extension : securityExtensions) {
1260-
final CloudApiKeyService cloudApiKeyService = extension.getCloudApiKeyService(extensionComponents);
1261-
if (cloudApiKeyService != null) {
1260+
final CustomApiKeyAuthenticator customApiKeyAuthenticator = extension.getCustomApiKeyAuthenticator(extensionComponents);
1261+
if (customApiKeyAuthenticator != null) {
12621262
if (false == isInternalExtension(extension)) {
12631263
throw new IllegalStateException(
12641264
"The ["
12651265
+ extension.getClass().getName()
1266-
+ "] extension tried to install a custom CloudApiKeyService. "
1266+
+ "] extension tried to install a custom CustomApiKeyAuthenticator. "
12671267
+ "This functionality is not available to external extensions."
12681268
);
12691269
}
1270-
boolean success = cloudApiKeyServiceSetOnce.trySet(cloudApiKeyService);
1270+
boolean success = customApiKeyAuthenticatorSetOnce.trySet(customApiKeyAuthenticator);
12711271
if (false == success) {
12721272
throw new IllegalStateException(
12731273
"The ["
12741274
+ extension.getClass().getName()
1275-
+ "] extension tried to install a custom CloudApiKeyService, but one has already been installed."
1275+
+ "] extension tried to install a custom CustomApiKeyAuthenticator, but one has already been installed."
12761276
);
12771277
}
1278-
logger.debug("CloudApiKeyService provided by extension [{}]", extension.extensionName());
1278+
logger.debug("CustomApiKeyAuthenticator provided by extension [{}]", extension.extensionName());
12791279
}
12801280
}
1281-
if (cloudApiKeyServiceSetOnce.get() == null) {
1282-
cloudApiKeyServiceSetOnce.set(new CloudApiKeyService.Noop());
1281+
if (customApiKeyAuthenticatorSetOnce.get() == null) {
1282+
customApiKeyAuthenticatorSetOnce.set(new CustomApiKeyAuthenticator.Noop());
12831283
}
1284-
return cloudApiKeyServiceSetOnce.get();
1284+
return customApiKeyAuthenticatorSetOnce.get();
12851285
}
12861286

12871287
private ServiceAccountService createServiceAccountService(

x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/AuthenticationService.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
import org.elasticsearch.xpack.core.security.authc.AuthenticationServiceField;
3131
import org.elasticsearch.xpack.core.security.authc.AuthenticationToken;
3232
import org.elasticsearch.xpack.core.security.authc.Realm;
33-
import org.elasticsearch.xpack.core.security.authc.cloud.CloudApiKeyService;
33+
import org.elasticsearch.xpack.core.security.authc.apikey.CustomApiKeyAuthenticator;
3434
import org.elasticsearch.xpack.core.security.authc.support.AuthenticationContextSerializer;
3535
import org.elasticsearch.xpack.core.security.authz.AuthorizationEngine.EmptyAuthorizationInfo;
3636
import org.elasticsearch.xpack.core.security.user.AnonymousUser;
@@ -93,7 +93,7 @@ public AuthenticationService(
9393
ApiKeyService apiKeyService,
9494
ServiceAccountService serviceAccountService,
9595
OperatorPrivilegesService operatorPrivilegesService,
96-
CloudApiKeyService cloudApiKeyService,
96+
CustomApiKeyAuthenticator customApiKeyAuthenticator,
9797
MeterRegistry meterRegistry
9898
) {
9999
this.realms = realms;
@@ -117,7 +117,7 @@ public AuthenticationService(
117117
new AuthenticationContextSerializer(),
118118
new ServiceAccountAuthenticator(serviceAccountService, nodeName, meterRegistry),
119119
new OAuth2TokenAuthenticator(tokenService, meterRegistry),
120-
new CloudApiKeyAuthenticator(nodeName, cloudApiKeyService),
120+
new PluggableApiKeyAuthenticator(customApiKeyAuthenticator),
121121
new ApiKeyAuthenticator(apiKeyService, nodeName, meterRegistry),
122122
new RealmsAuthenticator(numInvalidation, lastSuccessfulAuthCache, meterRegistry)
123123
);

x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/AuthenticatorChain.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class AuthenticatorChain {
5454
AuthenticationContextSerializer authenticationSerializer,
5555
ServiceAccountAuthenticator serviceAccountAuthenticator,
5656
OAuth2TokenAuthenticator oAuth2TokenAuthenticator,
57-
CloudApiKeyAuthenticator cloudApiKeyAuthenticator,
57+
PluggableApiKeyAuthenticator customApiKeyAuthenticator,
5858
ApiKeyAuthenticator apiKeyAuthenticator,
5959
RealmsAuthenticator realmsAuthenticator
6060
) {
@@ -68,7 +68,7 @@ class AuthenticatorChain {
6868
this.allAuthenticators = List.of(
6969
serviceAccountAuthenticator,
7070
oAuth2TokenAuthenticator,
71-
cloudApiKeyAuthenticator,
71+
customApiKeyAuthenticator,
7272
apiKeyAuthenticator,
7373
realmsAuthenticator
7474
);

x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/authc/CloudApiKeyAuthenticator.java

Lines changed: 0 additions & 55 deletions
This file was deleted.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
package org.elasticsearch.xpack.security.authc;
9+
10+
import org.elasticsearch.action.ActionListener;
11+
import org.elasticsearch.xpack.core.security.authc.Authentication;
12+
import org.elasticsearch.xpack.core.security.authc.AuthenticationResult;
13+
import org.elasticsearch.xpack.core.security.authc.AuthenticationToken;
14+
import org.elasticsearch.xpack.core.security.authc.apikey.CustomApiKeyAuthenticator;
15+
16+
public class PluggableApiKeyAuthenticator implements Authenticator {
17+
private final CustomApiKeyAuthenticator authenticator;
18+
19+
public PluggableApiKeyAuthenticator(CustomApiKeyAuthenticator authenticator) {
20+
this.authenticator = authenticator;
21+
}
22+
23+
@Override
24+
public String name() {
25+
return authenticator.name();
26+
}
27+
28+
@Override
29+
public AuthenticationToken extractCredentials(Context context) {
30+
return authenticator.extractCredentials(context.getApiKeyString());
31+
}
32+
33+
@Override
34+
public void authenticate(Context context, ActionListener<AuthenticationResult<Authentication>> listener) {
35+
final AuthenticationToken authenticationToken = context.getMostRecentAuthenticationToken();
36+
authenticator.authenticate(
37+
authenticationToken,
38+
ActionListener.wrap(
39+
listener::onResponse,
40+
ex -> listener.onFailure(context.getRequest().exceptionProcessingRequest(ex, authenticationToken))
41+
)
42+
);
43+
}
44+
}

0 commit comments

Comments
 (0)