From f051397d8f4b6ff87289a977b44b1eb62cf95b90 Mon Sep 17 00:00:00 2001 From: Sam Date: Wed, 5 Jul 2023 17:05:20 +0100 Subject: [PATCH] #2616 preliminary implementation of getTokenManager for extensions backwards compatibility using BWC_PLUGIN_MODE extension setting Signed-off-by: Sam --- .../security/OpenSearchSecurityPlugin.java | 40 +++++++++- .../security/auth/SecurityTokenManager.java | 73 +++++++++++++++++++ .../security/support/ConfigConstants.java | 2 - 3 files changed, 109 insertions(+), 6 deletions(-) create mode 100644 src/main/java/org/opensearch/security/auth/SecurityTokenManager.java diff --git a/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java b/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java index a46c03e24b..0479a760f7 100644 --- a/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java +++ b/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java @@ -98,6 +98,8 @@ import org.opensearch.extensions.ExtensionsManager; import org.opensearch.http.HttpServerTransport; import org.opensearch.http.HttpServerTransport.Dispatcher; +import org.opensearch.identity.Subject; +import org.opensearch.identity.tokens.TokenManager; import org.opensearch.index.Index; import org.opensearch.index.IndexModule; import org.opensearch.index.cache.query.QueryCache; @@ -106,6 +108,7 @@ import org.opensearch.indices.breaker.CircuitBreakerService; import org.opensearch.plugins.ClusterPlugin; import org.opensearch.plugins.ExtensionAwarePlugin; +import org.opensearch.plugins.IdentityPlugin; import org.opensearch.plugins.MapperPlugin; import org.opensearch.repositories.RepositoriesService; import org.opensearch.rest.RestController; @@ -127,6 +130,7 @@ import org.opensearch.security.auditlog.config.AuditConfig.Filter.FilterEntries; import org.opensearch.security.auditlog.impl.AuditLogImpl; import org.opensearch.security.auth.BackendRegistry; +import org.opensearch.security.auth.SecurityTokenManager; import org.opensearch.security.compliance.ComplianceIndexingOperationListener; import org.opensearch.security.compliance.ComplianceIndexingOperationListenerImpl; import org.opensearch.security.configuration.AdminDNs; @@ -192,7 +196,12 @@ import org.opensearch.watcher.ResourceWatcherService; // CS-ENFORCE-SINGLE -public final class OpenSearchSecurityPlugin extends OpenSearchSecuritySSLPlugin implements ClusterPlugin, MapperPlugin, ExtensionAwarePlugin { +public final class OpenSearchSecurityPlugin extends OpenSearchSecuritySSLPlugin + implements + ClusterPlugin, + MapperPlugin, + ExtensionAwarePlugin, + IdentityPlugin { private static final String KEYWORD = ".keyword"; private static final Logger actionTrace = LogManager.getLogger("opendistro_security_action_trace"); @@ -1103,9 +1112,14 @@ public Settings additionalSettings() { public List> getExtensionSettings() { List> extentionSettings = new ArrayList>(); - extentionSettings.add(Setting.boolSetting(ConfigConstants.EXTENSIONS_BWC_PLUGIN_MODE, ConfigConstants.EXTENSIONS_BWC_PLUGIN_MODE_DEFAULT, Property.ExtensionScope, Property.Final)); - extentionSettings.add(Setting.listSetting(ConfigConstants.EXTENSIONS_DISTIGUISHED_NAMES, ConfigConstants.EXTENSIONS_DISTINGUISHED_NAMES_DEFAULT, Function.identity(), Property.ExtensionScope, Property.Final)); - + extentionSettings.add( + Setting.boolSetting( + ConfigConstants.EXTENSIONS_BWC_PLUGIN_MODE, + ConfigConstants.EXTENSIONS_BWC_PLUGIN_MODE_DEFAULT, + Property.ExtensionScope, + Property.Final + ) + ); return extentionSettings; } @@ -1887,6 +1901,24 @@ private static String handleKeyword(final String field) { return field; } + @Override + public Subject getSubject() { + return null; + } + + @Override + public TokenManager getTokenManager() { + return new SecurityTokenManager( + settings.getAsBoolean(ConfigConstants.EXTENSIONS_BWC_PLUGIN_MODE, ConfigConstants.EXTENSIONS_BWC_PLUGIN_MODE_DEFAULT), + threadPool.getThreadContext(), + threadPool, + new XFFResolver(threadPool), + auditLog, + settings + ); + + } + public static class GuiceHolder implements LifecycleComponent { private static RepositoriesService repositoriesService; diff --git a/src/main/java/org/opensearch/security/auth/SecurityTokenManager.java b/src/main/java/org/opensearch/security/auth/SecurityTokenManager.java new file mode 100644 index 0000000000..4edb215026 --- /dev/null +++ b/src/main/java/org/opensearch/security/auth/SecurityTokenManager.java @@ -0,0 +1,73 @@ +/* + * 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.security.auth; + +import org.greenrobot.eventbus.Subscribe; +import org.opensearch.common.settings.Settings; +import org.opensearch.common.transport.TransportAddress; +import org.opensearch.common.util.concurrent.ThreadContext; +import org.opensearch.common.util.set.Sets; +import org.opensearch.identity.tokens.AuthToken; +import org.opensearch.identity.tokens.BasicAuthToken; +import org.opensearch.identity.tokens.TokenManager; +import org.opensearch.security.auditlog.AuditLog; +import org.opensearch.security.http.XFFResolver; +import org.opensearch.security.securityconf.ConfigModel; +import org.opensearch.security.support.ConfigConstants; +import org.opensearch.security.user.User; +import org.opensearch.threadpool.ThreadPool; + +import java.util.*; + +public class SecurityTokenManager implements TokenManager { + + Boolean extensionBwcCompatMode; + User user; + ConfigModel configModel; + Set mappedRoles; + UserInjector userInjector; + + @Subscribe + public void onConfigModelChanged(ConfigModel configModel) { + this.configModel = configModel; + } + + public SecurityTokenManager( + Boolean extensionBwcCompatMode, + ThreadContext threadContext, + ThreadPool threadPool, + final XFFResolver xffResolver, + AuditLog auditLog, + Settings settings + ) { + this.userInjector = new UserInjector(settings, threadPool, auditLog, xffResolver); + this.extensionBwcCompatMode = extensionBwcCompatMode; + this.user = threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_USER); + if (user == null) { + user = userInjector.getInjectedUser(); + } + final TransportAddress caller = threadContext.getTransient(ConfigConstants.OPENDISTRO_SECURITY_REMOTE_ADDRESS); + this.mappedRoles = configModel.mapSecurityRoles(user, caller); + } + + @Override + public AuthToken issueToken(String audience) { + + if (extensionBwcCompatMode) { + StringJoiner joiner = new StringJoiner("|"); + joiner.add(user.getName()); + joiner.add(String.join(",", user.getRoles())); + joiner.add(String.join(",", Sets.union(user.getSecurityRoles(), mappedRoles))); + + return new BasicAuthToken(joiner.toString() + "This is the Token including the encrypted backend roles"); + } else { + return new BasicAuthToken("This is standard Token without the roles"); + } + } +} diff --git a/src/main/java/org/opensearch/security/support/ConfigConstants.java b/src/main/java/org/opensearch/security/support/ConfigConstants.java index 5da931eb1f..2f518fafbf 100644 --- a/src/main/java/org/opensearch/security/support/ConfigConstants.java +++ b/src/main/java/org/opensearch/security/support/ConfigConstants.java @@ -324,8 +324,6 @@ public enum RolesMappingResolution { public static final String EXTENSIONS_SETTING = "extensions"; public static final String EXTENSIONS_BWC_PLUGIN_MODE = "bwcPluginMode"; public static final boolean EXTENSIONS_BWC_PLUGIN_MODE_DEFAULT = false; - public static final String EXTENSIONS_DISTIGUISHED_NAMES = "extensionDistinguishedNames"; - public static final List EXTENSIONS_DISTINGUISHED_NAMES_DEFAULT = Collections.emptyList(); public static Set getSettingAsSet( final Settings settings,