From 7374479938f892fc2ab9af9cd27d967b4086f9d1 Mon Sep 17 00:00:00 2001 From: Craig Perkins Date: Fri, 16 Aug 2024 16:02:44 -0400 Subject: [PATCH] Separate UserSubject and PluginSubject Signed-off-by: Craig Perkins --- .../identity/shiro/ShiroIdentityPlugin.java | 4 +-- .../identity/shiro/ShiroSubject.java | 3 +- .../rest/RestSendToExtensionAction.java | 2 +- .../opensearch/identity/IdentityService.java | 6 ++-- .../opensearch/identity/PluginSubject.java | 19 +----------- .../java/org/opensearch/identity/Subject.java | 10 ------- .../org/opensearch/identity/UserSubject.java | 29 +++++++++++++++++++ .../identity/noop/NoopIdentityPlugin.java | 4 +-- .../opensearch/identity/noop/NoopSubject.java | 3 +- .../opensearch/plugins/IdentityPlugin.java | 7 +++-- .../org/opensearch/rest/RestController.java | 4 +-- .../bootstrap/IdentityPluginTests.java | 2 +- .../rest/ExtensionRestRequestTests.java | 4 +-- 13 files changed, 51 insertions(+), 46 deletions(-) create mode 100644 server/src/main/java/org/opensearch/identity/UserSubject.java diff --git a/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroIdentityPlugin.java b/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroIdentityPlugin.java index 658040ef7206a..435b0acdb06af 100644 --- a/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroIdentityPlugin.java +++ b/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroIdentityPlugin.java @@ -22,7 +22,7 @@ import org.opensearch.env.Environment; import org.opensearch.env.NodeEnvironment; import org.opensearch.identity.PluginSubject; -import org.opensearch.identity.Subject; +import org.opensearch.identity.UserSubject; import org.opensearch.identity.tokens.TokenManager; import org.opensearch.plugins.IdentityPlugin; import org.opensearch.plugins.Plugin; @@ -86,7 +86,7 @@ public Collection createComponents( * @return The current subject */ @Override - public Subject getSubject() { + public UserSubject getUserSubject() { return new ShiroSubject(authTokenHandler, SecurityUtils.getSubject()); } diff --git a/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroSubject.java b/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroSubject.java index e55204593621c..72a168f23c5cd 100644 --- a/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroSubject.java +++ b/plugins/identity-shiro/src/main/java/org/opensearch/identity/shiro/ShiroSubject.java @@ -9,6 +9,7 @@ package org.opensearch.identity.shiro; import org.opensearch.identity.Subject; +import org.opensearch.identity.UserSubject; import org.opensearch.identity.tokens.AuthToken; import java.security.Principal; @@ -19,7 +20,7 @@ * * @opensearch.experimental */ -public class ShiroSubject implements Subject { +public class ShiroSubject implements UserSubject { private final ShiroTokenManager authTokenHandler; private final org.apache.shiro.subject.Subject shiroSubject; diff --git a/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java b/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java index f4503ce55e6bc..2e64ded6c5158 100644 --- a/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java +++ b/server/src/main/java/org/opensearch/extensions/rest/RestSendToExtensionAction.java @@ -249,7 +249,7 @@ public String executor() { Map> filteredHeaders = filterHeaders(headers, allowList, denyList); TokenManager tokenManager = identityService.getTokenManager(); - Subject subject = this.identityService.getSubject(); + Subject subject = this.identityService.getUserSubject(); OnBehalfOfClaims claims = new OnBehalfOfClaims(discoveryExtensionNode.getId(), subject.getPrincipal().getName()); transportService.sendRequest( diff --git a/server/src/main/java/org/opensearch/identity/IdentityService.java b/server/src/main/java/org/opensearch/identity/IdentityService.java index 5e9c146fbd2f5..186b30020c676 100644 --- a/server/src/main/java/org/opensearch/identity/IdentityService.java +++ b/server/src/main/java/org/opensearch/identity/IdentityService.java @@ -48,10 +48,10 @@ public IdentityService(final Settings settings, final ThreadPool threadPool, fin } /** - * Gets the current Subject + * Gets the current UserSubject */ - public Subject getSubject() { - return identityPlugin.getSubject(); + public UserSubject getUserSubject() { + return identityPlugin.getUserSubject(); } /** diff --git a/server/src/main/java/org/opensearch/identity/PluginSubject.java b/server/src/main/java/org/opensearch/identity/PluginSubject.java index 290c27b23468b..3ea42182d3fc3 100644 --- a/server/src/main/java/org/opensearch/identity/PluginSubject.java +++ b/server/src/main/java/org/opensearch/identity/PluginSubject.java @@ -10,27 +10,10 @@ import org.opensearch.common.annotation.ExperimentalApi; -import java.security.Principal; -import java.util.concurrent.Callable; - /** * Similar to {@link Subject}, but represents a plugin executing actions * * @opensearch.experimental */ @ExperimentalApi -public interface PluginSubject { - - /** - * Get the application-wide uniquely identifying principal - * */ - Principal getPrincipal(); - - /** - * runAs allows the caller to run a callable function as this subject - */ - default T runAs(Callable callable) throws Exception { - callable.call(); - return null; - }; -} +public interface PluginSubject extends Subject {} diff --git a/server/src/main/java/org/opensearch/identity/Subject.java b/server/src/main/java/org/opensearch/identity/Subject.java index 349ce120244e4..e138ab7a957ca 100644 --- a/server/src/main/java/org/opensearch/identity/Subject.java +++ b/server/src/main/java/org/opensearch/identity/Subject.java @@ -6,7 +6,6 @@ package org.opensearch.identity; import org.opensearch.common.annotation.ExperimentalApi; -import org.opensearch.identity.tokens.AuthToken; import java.security.Principal; import java.util.concurrent.Callable; @@ -24,15 +23,6 @@ public interface Subject { * */ Principal getPrincipal(); - /** - * Authenticate via an auth token - * throws UnsupportedAuthenticationMethod - * throws InvalidAuthenticationToken - * throws SubjectNotFound - * throws SubjectDisabled - */ - void authenticate(final AuthToken token); - /** * runAs allows the caller to run a callable function as this subject */ diff --git a/server/src/main/java/org/opensearch/identity/UserSubject.java b/server/src/main/java/org/opensearch/identity/UserSubject.java new file mode 100644 index 0000000000000..50f8ac6b37be3 --- /dev/null +++ b/server/src/main/java/org/opensearch/identity/UserSubject.java @@ -0,0 +1,29 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * The OpenSearch Contributors require contributions made to + * this file be licensed under the Apache-2.0 license or a + * compatible open source license. + */ + +package org.opensearch.identity; + +import org.opensearch.common.annotation.ExperimentalApi; +import org.opensearch.identity.tokens.AuthToken; + +/** + * An instance of a subject representing a User. UserSubjects must pass credentials for authentication. + * + * @opensearch.experimental + */ +@ExperimentalApi +public interface UserSubject extends Subject { + /** + * Authenticate via an auth token + * throws UnsupportedAuthenticationMethod + * throws InvalidAuthenticationToken + * throws SubjectNotFound + * throws SubjectDisabled + */ + void authenticate(final AuthToken token); +} diff --git a/server/src/main/java/org/opensearch/identity/noop/NoopIdentityPlugin.java b/server/src/main/java/org/opensearch/identity/noop/NoopIdentityPlugin.java index 15ee4af9cefbd..80f8c06728067 100644 --- a/server/src/main/java/org/opensearch/identity/noop/NoopIdentityPlugin.java +++ b/server/src/main/java/org/opensearch/identity/noop/NoopIdentityPlugin.java @@ -9,7 +9,7 @@ package org.opensearch.identity.noop; import org.opensearch.identity.PluginSubject; -import org.opensearch.identity.Subject; +import org.opensearch.identity.UserSubject; import org.opensearch.identity.tokens.TokenManager; import org.opensearch.plugins.IdentityPlugin; import org.opensearch.plugins.Plugin; @@ -35,7 +35,7 @@ public NoopIdentityPlugin(ThreadPool threadPool) { * @return Must never return null */ @Override - public Subject getSubject() { + public UserSubject getUserSubject() { return new NoopSubject(); } diff --git a/server/src/main/java/org/opensearch/identity/noop/NoopSubject.java b/server/src/main/java/org/opensearch/identity/noop/NoopSubject.java index 964a218db3cf5..fda88a8b7e8af 100644 --- a/server/src/main/java/org/opensearch/identity/noop/NoopSubject.java +++ b/server/src/main/java/org/opensearch/identity/noop/NoopSubject.java @@ -10,6 +10,7 @@ import org.opensearch.identity.NamedPrincipal; import org.opensearch.identity.Subject; +import org.opensearch.identity.UserSubject; import org.opensearch.identity.tokens.AuthToken; import java.security.Principal; @@ -22,7 +23,7 @@ * * @opensearch.internal */ -public class NoopSubject implements Subject { +public class NoopSubject implements UserSubject { @Override public Principal getPrincipal() { diff --git a/server/src/main/java/org/opensearch/plugins/IdentityPlugin.java b/server/src/main/java/org/opensearch/plugins/IdentityPlugin.java index 74d079e358a92..1e5584051cdc7 100644 --- a/server/src/main/java/org/opensearch/plugins/IdentityPlugin.java +++ b/server/src/main/java/org/opensearch/plugins/IdentityPlugin.java @@ -10,7 +10,7 @@ import org.opensearch.common.annotation.ExperimentalApi; import org.opensearch.identity.PluginSubject; -import org.opensearch.identity.Subject; +import org.opensearch.identity.UserSubject; import org.opensearch.identity.tokens.TokenManager; /** @@ -22,10 +22,11 @@ public interface IdentityPlugin { /** - * Get the current subject. + * Get the current user subject. + * * @return Should never return null * */ - Subject getSubject(); + UserSubject getUserSubject(); /** * Get the Identity Plugin's token manager implementation diff --git a/server/src/main/java/org/opensearch/rest/RestController.java b/server/src/main/java/org/opensearch/rest/RestController.java index 7d0c1e2260de1..197c998a9b714 100644 --- a/server/src/main/java/org/opensearch/rest/RestController.java +++ b/server/src/main/java/org/opensearch/rest/RestController.java @@ -57,7 +57,7 @@ import org.opensearch.http.HttpChunk; import org.opensearch.http.HttpServerTransport; import org.opensearch.identity.IdentityService; -import org.opensearch.identity.Subject; +import org.opensearch.identity.UserSubject; import org.opensearch.identity.tokens.AuthToken; import org.opensearch.identity.tokens.RestTokenExtractor; import org.opensearch.usage.UsageService; @@ -593,7 +593,7 @@ private boolean handleAuthenticateUser(final RestRequest request, final RestChan // Authentication did not fail so return true. Authorization is handled at the action level. return true; } - final Subject currentSubject = identityService.getSubject(); + final UserSubject currentSubject = identityService.getUserSubject(); currentSubject.authenticate(token); logger.debug("Logged in as user " + currentSubject); } catch (final Exception e) { diff --git a/server/src/test/java/org/opensearch/bootstrap/IdentityPluginTests.java b/server/src/test/java/org/opensearch/bootstrap/IdentityPluginTests.java index e08f8e71d42a7..ae17a90cacc77 100644 --- a/server/src/test/java/org/opensearch/bootstrap/IdentityPluginTests.java +++ b/server/src/test/java/org/opensearch/bootstrap/IdentityPluginTests.java @@ -29,7 +29,7 @@ public void testSingleIdentityPluginSucceeds() { IdentityPlugin identityPlugin1 = new NoopIdentityPlugin(threadPool); List pluginList1 = List.of(identityPlugin1); IdentityService identityService1 = new IdentityService(Settings.EMPTY, threadPool, pluginList1); - assertTrue(identityService1.getSubject().getPrincipal().getName().equalsIgnoreCase("Unauthenticated")); + assertTrue(identityService1.getUserSubject().getPrincipal().getName().equalsIgnoreCase("Unauthenticated")); assertThat(identityService1.getTokenManager(), is(instanceOf(NoopTokenManager.class))); } diff --git a/server/src/test/java/org/opensearch/extensions/rest/ExtensionRestRequestTests.java b/server/src/test/java/org/opensearch/extensions/rest/ExtensionRestRequestTests.java index c0158a347a7c2..e9fc561632a8f 100644 --- a/server/src/test/java/org/opensearch/extensions/rest/ExtensionRestRequestTests.java +++ b/server/src/test/java/org/opensearch/extensions/rest/ExtensionRestRequestTests.java @@ -76,10 +76,10 @@ public void setUp() throws Exception { extensionTokenProcessor = "placeholder_extension_token_processor"; identityService = new IdentityService(Settings.EMPTY, mock(ThreadPool.class), List.of()); TokenManager tokenManager = identityService.getTokenManager(); - Subject subject = this.identityService.getSubject(); + Subject subject = this.identityService.getUserSubject(); OnBehalfOfClaims claims = new OnBehalfOfClaims("testID", subject.getPrincipal().getName()); expectedRequestIssuerIdentity = identityService.getTokenManager() - .issueOnBehalfOfToken(identityService.getSubject(), claims) + .issueOnBehalfOfToken(identityService.getUserSubject(), claims) .asAuthHeaderValue(); }