diff --git a/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java b/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java index ffb7cfc075..4e9f171d90 100644 --- a/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java +++ b/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java @@ -99,6 +99,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,8 @@ import org.opensearch.indices.SystemIndexDescriptor; 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 +131,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; @@ -193,7 +198,12 @@ import org.opensearch.watcher.ResourceWatcherService; // CS-ENFORCE-SINGLE -public final class OpenSearchSecurityPlugin extends OpenSearchSecuritySSLPlugin implements ClusterPlugin, MapperPlugin { +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"); @@ -1107,6 +1117,21 @@ public Settings additionalSettings() { return builder.build(); } + @Override + 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 + ) + ); + return extentionSettings; + } + @Override public List> getSettings() { List> settings = new ArrayList>(); @@ -1886,6 +1911,15 @@ private static String handleKeyword(final String field) { return field; } + @Override + public Subject getSubject() { + return null; + } + + @Override + public TokenManager getTokenManager() { + return new SecurityTokenManager(threadPool, new XFFResolver(threadPool), auditLog, settings); + public static DiscoveryNode getLocalNode() { return localNode; } 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..d9567e8ee9 --- /dev/null +++ b/src/main/java/org/opensearch/security/auth/SecurityTokenManager.java @@ -0,0 +1,69 @@ +/* + * 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.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.Set; +import java.util.StringJoiner; + +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(ThreadPool threadPool, final XFFResolver xffResolver, AuditLog auditLog, Settings settings) { + this.userInjector = new UserInjector(settings, threadPool, auditLog, xffResolver); + this.extensionBwcCompatMode = settings.getAsBoolean( + ConfigConstants.EXTENSIONS_BWC_PLUGIN_MODE, + ConfigConstants.EXTENSIONS_BWC_PLUGIN_MODE_DEFAULT + ); + this.user = threadPool.getThreadContext().getTransient(ConfigConstants.OPENDISTRO_SECURITY_USER); + final TransportAddress caller = threadPool.getThreadContext().getTransient(ConfigConstants.OPENDISTRO_SECURITY_REMOTE_ADDRESS); + + if (user == null) { + user = userInjector.getInjectedUser(); + } + 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 + "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 ee04ff62f3..2f518fafbf 100644 --- a/src/main/java/org/opensearch/security/support/ConfigConstants.java +++ b/src/main/java/org/opensearch/security/support/ConfigConstants.java @@ -320,6 +320,11 @@ public enum RolesMappingResolution { public static final String TENANCY_GLOBAL_TENANT_NAME = "global"; public static final String TENANCY_GLOBAL_TENANT_DEFAULT_NAME = ""; + // Extension Settings + 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 Set getSettingAsSet( final Settings settings, final String key,