From 11d70ba6e6645a49e73ec5ef632835ed292b69ef Mon Sep 17 00:00:00 2001 From: Sam Date: Wed, 26 Jul 2023 12:05:32 +0100 Subject: [PATCH 1/6] initial changes Signed-off-by: Sam --- .../security/OpenSearchSecurityPlugin.java | 43 +++++++++++- .../security/auth/SecurityTokenManager.java | 70 +++++++++++++++++++ .../security/support/ConfigConstants.java | 4 ++ 3 files changed, 116 insertions(+), 1 deletion(-) 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 c4b2002fa8..bcf27a5425 100644 --- a/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java +++ b/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java @@ -100,12 +100,16 @@ import org.opensearch.http.HttpServerTransport; import org.opensearch.http.HttpServerTransport.Dispatcher; import org.opensearch.core.index.Index; +import org.opensearch.identity.Subject; +import org.opensearch.identity.tokens.TokenManager; import org.opensearch.index.IndexModule; import org.opensearch.index.cache.query.QueryCache; import org.opensearch.indices.IndicesService; 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; @@ -128,6 +132,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; @@ -194,7 +199,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"); @@ -1111,6 +1121,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>(); @@ -1898,6 +1923,22 @@ public static void setLocalNode(DiscoveryNode node) { localNode = node; } + + @Override + public Subject getSubject() { + return null; + } + + @Override + public TokenManager getTokenManager() { + return new SecurityTokenManager( + 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..45eabd59eb --- /dev/null +++ b/src/main/java/org/opensearch/security/auth/SecurityTokenManager.java @@ -0,0 +1,70 @@ +/* + * 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.*; + +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.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 ee04ff62f3..cc50e48457 100644 --- a/src/main/java/org/opensearch/security/support/ConfigConstants.java +++ b/src/main/java/org/opensearch/security/support/ConfigConstants.java @@ -320,6 +320,10 @@ public enum RolesMappingResolution { public static final String TENANCY_GLOBAL_TENANT_NAME = "global"; public static final String TENANCY_GLOBAL_TENANT_DEFAULT_NAME = ""; + 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, From 1ec0cf06aca0eb9f34aad59f4132f17562a4eb36 Mon Sep 17 00:00:00 2001 From: Sam Date: Tue, 15 Aug 2023 15:23:37 +0100 Subject: [PATCH 2/6] Editing JwtVendor.java to add backend roles if BwcMode is active Signed-off-by: Sam --- .../security/auth/SecurityTokenManager.java | 70 ------------------- .../security/authtoken/jwt/JwtVendor.java | 12 +++- 2 files changed, 10 insertions(+), 72 deletions(-) delete mode 100644 src/main/java/org/opensearch/security/auth/SecurityTokenManager.java diff --git a/src/main/java/org/opensearch/security/auth/SecurityTokenManager.java b/src/main/java/org/opensearch/security/auth/SecurityTokenManager.java deleted file mode 100644 index 45eabd59eb..0000000000 --- a/src/main/java/org/opensearch/security/auth/SecurityTokenManager.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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.*; - -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.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/authtoken/jwt/JwtVendor.java b/src/main/java/org/opensearch/security/authtoken/jwt/JwtVendor.java index 21d7caad57..a5625002e2 100644 --- a/src/main/java/org/opensearch/security/authtoken/jwt/JwtVendor.java +++ b/src/main/java/org/opensearch/security/authtoken/jwt/JwtVendor.java @@ -14,6 +14,7 @@ import java.time.Instant; import java.util.List; import java.util.Optional; +import java.util.StringJoiner; import java.util.function.LongSupplier; import com.google.common.base.Strings; @@ -30,6 +31,9 @@ import org.apache.logging.log4j.Logger; import org.opensearch.common.settings.Settings; +import org.opensearch.common.util.set.Sets; +import org.opensearch.identity.tokens.BasicAuthToken; +import org.opensearch.security.support.ConfigConstants; public class JwtVendor { private static final Logger logger = LogManager.getLogger(JwtVendor.class); @@ -103,7 +107,8 @@ public String createJwt( String audience, Integer expirySeconds, List roles, - List backendRoles + List backendRoles, + Boolean bwcModeEnabled ) throws Exception { String tokenIdentifier = "obo"; long timeMillis = timeProvider.getAsLong(); @@ -142,7 +147,10 @@ public String createJwt( throw new Exception("Roles cannot be null"); } - /* TODO: If the backendRoles is not null and the BWC Mode is on, put them into the "dbr" claim */ + if (bwcModeEnabled && backendRoles != null) { + String listOfBackendRoles = String.join(",", backendRoles); + jwtClaims.setProperty("br", EncryptionDecryptionUtil.encrypt(claimsEncryptionKey, listOfBackendRoles)); + } String encodedJwt = jwtProducer.processJwt(jwt); From 771513b61857070f02fc4a64fd62c27b07aca3b3 Mon Sep 17 00:00:00 2001 From: Sam Date: Tue, 15 Aug 2023 15:23:37 +0100 Subject: [PATCH 3/6] Editing JwtVendor.java to add backend roles if BwcMode is active Signed-off-by: Sam --- .../security/auth/SecurityTokenManager.java | 70 ------------------- .../security/authtoken/jwt/JwtVendor.java | 12 +++- 2 files changed, 10 insertions(+), 72 deletions(-) delete mode 100644 src/main/java/org/opensearch/security/auth/SecurityTokenManager.java diff --git a/src/main/java/org/opensearch/security/auth/SecurityTokenManager.java b/src/main/java/org/opensearch/security/auth/SecurityTokenManager.java deleted file mode 100644 index 45eabd59eb..0000000000 --- a/src/main/java/org/opensearch/security/auth/SecurityTokenManager.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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.*; - -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.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/authtoken/jwt/JwtVendor.java b/src/main/java/org/opensearch/security/authtoken/jwt/JwtVendor.java index 21d7caad57..a5625002e2 100644 --- a/src/main/java/org/opensearch/security/authtoken/jwt/JwtVendor.java +++ b/src/main/java/org/opensearch/security/authtoken/jwt/JwtVendor.java @@ -14,6 +14,7 @@ import java.time.Instant; import java.util.List; import java.util.Optional; +import java.util.StringJoiner; import java.util.function.LongSupplier; import com.google.common.base.Strings; @@ -30,6 +31,9 @@ import org.apache.logging.log4j.Logger; import org.opensearch.common.settings.Settings; +import org.opensearch.common.util.set.Sets; +import org.opensearch.identity.tokens.BasicAuthToken; +import org.opensearch.security.support.ConfigConstants; public class JwtVendor { private static final Logger logger = LogManager.getLogger(JwtVendor.class); @@ -103,7 +107,8 @@ public String createJwt( String audience, Integer expirySeconds, List roles, - List backendRoles + List backendRoles, + Boolean bwcModeEnabled ) throws Exception { String tokenIdentifier = "obo"; long timeMillis = timeProvider.getAsLong(); @@ -142,7 +147,10 @@ public String createJwt( throw new Exception("Roles cannot be null"); } - /* TODO: If the backendRoles is not null and the BWC Mode is on, put them into the "dbr" claim */ + if (bwcModeEnabled && backendRoles != null) { + String listOfBackendRoles = String.join(",", backendRoles); + jwtClaims.setProperty("br", EncryptionDecryptionUtil.encrypt(claimsEncryptionKey, listOfBackendRoles)); + } String encodedJwt = jwtProducer.processJwt(jwt); From 49ca97bcd4e7e02914fbc0980b430ac3edb52b08 Mon Sep 17 00:00:00 2001 From: Sam Date: Tue, 15 Aug 2023 15:52:23 +0100 Subject: [PATCH 4/6] Editing JwtVendor.java to add backend roles if BwcMode is active Signed-off-by: Sam --- .../security/OpenSearchSecurityPlugin.java | 35 ++----------------- .../security/authtoken/jwt/JwtVendor.java | 8 ++--- .../security/support/ConfigConstants.java | 1 - 3 files changed, 6 insertions(+), 38 deletions(-) diff --git a/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java b/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java index 9788046579..a8f2f4bc4a 100644 --- a/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java +++ b/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java @@ -101,15 +101,12 @@ import org.opensearch.http.HttpServerTransport; import org.opensearch.http.HttpServerTransport.Dispatcher; import org.opensearch.core.index.Index; -import org.opensearch.identity.Subject; -import org.opensearch.identity.tokens.TokenManager; import org.opensearch.index.IndexModule; import org.opensearch.index.cache.query.QueryCache; import org.opensearch.indices.IndicesService; import org.opensearch.indices.SystemIndexDescriptor; 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; @@ -132,7 +129,6 @@ 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; @@ -199,12 +195,11 @@ import org.opensearch.watcher.ResourceWatcherService; // CS-ENFORCE-SINGLE - public final class OpenSearchSecurityPlugin extends OpenSearchSecuritySSLPlugin - implements +public final class OpenSearchSecurityPlugin extends OpenSearchSecuritySSLPlugin + implements ClusterPlugin, MapperPlugin, - ExtensionAwarePlugin, - IdentityPlugin { + ExtensionAwarePlugin { private static final String KEYWORD = ".keyword"; private static final Logger actionTrace = LogManager.getLogger("opendistro_security_action_trace"); @@ -1915,30 +1910,6 @@ private static String handleKeyword(final String field) { return field; } - public static DiscoveryNode getLocalNode() { - return localNode; - } - - public static void setLocalNode(DiscoveryNode node) { - localNode = node; - } - - - @Override - public Subject getSubject() { - return null; - } - - @Override - public TokenManager getTokenManager() { - return new SecurityTokenManager( - 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/authtoken/jwt/JwtVendor.java b/src/main/java/org/opensearch/security/authtoken/jwt/JwtVendor.java index a5625002e2..cc116dfe06 100644 --- a/src/main/java/org/opensearch/security/authtoken/jwt/JwtVendor.java +++ b/src/main/java/org/opensearch/security/authtoken/jwt/JwtVendor.java @@ -14,7 +14,6 @@ import java.time.Instant; import java.util.List; import java.util.Optional; -import java.util.StringJoiner; import java.util.function.LongSupplier; import com.google.common.base.Strings; @@ -31,8 +30,6 @@ import org.apache.logging.log4j.Logger; import org.opensearch.common.settings.Settings; -import org.opensearch.common.util.set.Sets; -import org.opensearch.identity.tokens.BasicAuthToken; import org.opensearch.security.support.ConfigConstants; public class JwtVendor { @@ -44,6 +41,7 @@ public class JwtVendor { private final JsonWebKey signingKey; private final JoseJwtProducer jwtProducer; private final LongSupplier timeProvider; + private final Boolean bwcModeEnabled; public JwtVendor(final Settings settings, final Optional timeProvider) { JoseJwtProducer jwtProducer = new JoseJwtProducer(); @@ -63,6 +61,7 @@ public JwtVendor(final Settings settings, final Optional timeProvi } else { this.timeProvider = () -> System.currentTimeMillis() / 1000; } + this.bwcModeEnabled = settings.getAsBoolean(ConfigConstants.EXTENSIONS_BWC_PLUGIN_MODE, true); } /* @@ -107,8 +106,7 @@ public String createJwt( String audience, Integer expirySeconds, List roles, - List backendRoles, - Boolean bwcModeEnabled + List backendRoles ) throws Exception { String tokenIdentifier = "obo"; long timeMillis = timeProvider.getAsLong(); diff --git a/src/main/java/org/opensearch/security/support/ConfigConstants.java b/src/main/java/org/opensearch/security/support/ConfigConstants.java index cc50e48457..fe8aecffd1 100644 --- a/src/main/java/org/opensearch/security/support/ConfigConstants.java +++ b/src/main/java/org/opensearch/security/support/ConfigConstants.java @@ -323,7 +323,6 @@ public enum RolesMappingResolution { 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, From ce96b6a490efba4c489213ab700706ae9ce1c1e0 Mon Sep 17 00:00:00 2001 From: Sam Date: Thu, 17 Aug 2023 15:57:40 +0100 Subject: [PATCH 5/6] Test Added. Making backend roles not encrypted. Suppress 'extensions' warning Signed-off-by: Sam --- .../security/OpenSearchSecurityPlugin.java | 14 ++++-- .../security/authtoken/jwt/JwtVendor.java | 9 +++- .../security/support/ConfigConstants.java | 2 + .../security/authtoken/jwt/JwtVendorTest.java | 43 ++++++++++++++++++- 4 files changed, 61 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java b/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java index a8f2f4bc4a..b40b0186ac 100644 --- a/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java +++ b/src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java @@ -199,7 +199,11 @@ public final class OpenSearchSecurityPlugin extends OpenSearchSecuritySSLPlugin implements ClusterPlugin, MapperPlugin, - ExtensionAwarePlugin { + // CS-SUPPRESS-SINGLE: RegexpSingleline get Extensions Settings + ExtensionAwarePlugin +// CS-ENFORCE-SINGLE + +{ private static final String KEYWORD = ".keyword"; private static final Logger actionTrace = LogManager.getLogger("opendistro_security_action_trace"); @@ -1115,12 +1119,13 @@ public Settings additionalSettings() { } return builder.build(); } + // CS-SUPPRESS-SINGLE: RegexpSingleline get Extensions Settings @Override public List> getExtensionSettings() { - List> extentionSettings = new ArrayList>(); + List> extensionSettings = new ArrayList>(); - extentionSettings.add( + extensionSettings.add( Setting.boolSetting( ConfigConstants.EXTENSIONS_BWC_PLUGIN_MODE, ConfigConstants.EXTENSIONS_BWC_PLUGIN_MODE_DEFAULT, @@ -1128,8 +1133,9 @@ public List> getExtensionSettings() { Property.Final ) ); - return extentionSettings; + return extensionSettings; } + // CS-ENFORCE-SINGLE: @Override public List> getSettings() { diff --git a/src/main/java/org/opensearch/security/authtoken/jwt/JwtVendor.java b/src/main/java/org/opensearch/security/authtoken/jwt/JwtVendor.java index cc116dfe06..4372e2dfee 100644 --- a/src/main/java/org/opensearch/security/authtoken/jwt/JwtVendor.java +++ b/src/main/java/org/opensearch/security/authtoken/jwt/JwtVendor.java @@ -61,7 +61,12 @@ public JwtVendor(final Settings settings, final Optional timeProvi } else { this.timeProvider = () -> System.currentTimeMillis() / 1000; } - this.bwcModeEnabled = settings.getAsBoolean(ConfigConstants.EXTENSIONS_BWC_PLUGIN_MODE, true); + // CS-SUPPRESS-SINGLE: RegexpSingleline get Extensions Settings + this.bwcModeEnabled = settings.getAsBoolean( + ConfigConstants.EXTENSIONS_BWC_PLUGIN_MODE, + ConfigConstants.EXTENSIONS_BWC_PLUGIN_MODE_DEFAULT + ); + // CS-ENFORCE-SINGLE } /* @@ -147,7 +152,7 @@ public String createJwt( if (bwcModeEnabled && backendRoles != null) { String listOfBackendRoles = String.join(",", backendRoles); - jwtClaims.setProperty("br", EncryptionDecryptionUtil.encrypt(claimsEncryptionKey, listOfBackendRoles)); + jwtClaims.setProperty("dbr", listOfBackendRoles); } String encodedJwt = jwtProducer.processJwt(jwt); diff --git a/src/main/java/org/opensearch/security/support/ConfigConstants.java b/src/main/java/org/opensearch/security/support/ConfigConstants.java index fe8aecffd1..3b0b6a1091 100644 --- a/src/main/java/org/opensearch/security/support/ConfigConstants.java +++ b/src/main/java/org/opensearch/security/support/ConfigConstants.java @@ -320,8 +320,10 @@ public enum RolesMappingResolution { public static final String TENANCY_GLOBAL_TENANT_NAME = "global"; public static final String TENANCY_GLOBAL_TENANT_DEFAULT_NAME = ""; + // CS-SUPPRESS-SINGLE: RegexpSingleline get Extensions Settings public static final String EXTENSIONS_BWC_PLUGIN_MODE = "bwcPluginMode"; public static final boolean EXTENSIONS_BWC_PLUGIN_MODE_DEFAULT = false; + // CS-ENFORCE-SINGLE public static Set getSettingAsSet( final Settings settings, diff --git a/src/test/java/org/opensearch/security/authtoken/jwt/JwtVendorTest.java b/src/test/java/org/opensearch/security/authtoken/jwt/JwtVendorTest.java index 60ed365285..a93ddbd2cd 100644 --- a/src/test/java/org/opensearch/security/authtoken/jwt/JwtVendorTest.java +++ b/src/test/java/org/opensearch/security/authtoken/jwt/JwtVendorTest.java @@ -23,6 +23,7 @@ import org.junit.Test; import org.opensearch.common.settings.Settings; +import org.opensearch.security.support.ConfigConstants; public class JwtVendorTest { @@ -48,7 +49,7 @@ public void testCreateJwtWithRoles() throws Exception { String subject = "admin"; String audience = "audience_0"; List roles = List.of("IT", "HR"); - List backendRoles = List.of("Sales"); + List backendRoles = List.of("Sales", "Support"); String expectedRoles = "IT,HR"; Integer expirySeconds = 300; LongSupplier currentTime = () -> (int) 100; @@ -71,6 +72,46 @@ public void testCreateJwtWithRoles() throws Exception { Assert.assertEquals(expectedExp, jwt.getClaim("exp")); Assert.assertNotEquals(expectedRoles, jwt.getClaim("er")); Assert.assertEquals(expectedRoles, EncryptionDecryptionUtil.decrypt(claimsEncryptionKey, jwt.getClaim("er").toString())); + Assert.assertNull(jwt.getClaim("dbr")); + } + + @Test + public void testCreateJwtWithBackwardsCompatibilityMode() throws Exception { + String issuer = "cluster_0"; + String subject = "admin"; + String audience = "audience_0"; + List roles = List.of("IT", "HR"); + List backendRoles = List.of("Sales", "Support"); + String expectedRoles = "IT,HR"; + String expectedBackendRoles = "Sales,Support"; + + Integer expirySeconds = 300; + LongSupplier currentTime = () -> (int) 100; + String claimsEncryptionKey = RandomStringUtils.randomAlphanumeric(16); + Settings settings = Settings.builder() + .put("signing_key", "abc123") + .put("encryption_key", claimsEncryptionKey) + .put(ConfigConstants.EXTENSIONS_BWC_PLUGIN_MODE, true) + .build(); + Long expectedExp = currentTime.getAsLong() + expirySeconds; + + JwtVendor jwtVendor = new JwtVendor(settings, Optional.of(currentTime)); + String encodedJwt = jwtVendor.createJwt(issuer, subject, audience, expirySeconds, roles, backendRoles); + + JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(encodedJwt); + JwtToken jwt = jwtConsumer.getJwtToken(); + + Assert.assertEquals("obo", jwt.getClaim("typ")); + Assert.assertEquals("cluster_0", jwt.getClaim("iss")); + Assert.assertEquals("admin", jwt.getClaim("sub")); + Assert.assertEquals("audience_0", jwt.getClaim("aud")); + Assert.assertNotNull(jwt.getClaim("iat")); + Assert.assertNotNull(jwt.getClaim("exp")); + Assert.assertEquals(expectedExp, jwt.getClaim("exp")); + Assert.assertNotEquals(expectedRoles, jwt.getClaim("er")); + Assert.assertEquals(expectedRoles, EncryptionDecryptionUtil.decrypt(claimsEncryptionKey, jwt.getClaim("er").toString())); + Assert.assertNotNull(jwt.getClaim("dbr")); + Assert.assertEquals(expectedBackendRoles, jwt.getClaim("dbr")); } @Test(expected = Exception.class) From 752dd9a24737eb257bf11bb4e767f4c880a7eb77 Mon Sep 17 00:00:00 2001 From: Sam Date: Thu, 17 Aug 2023 17:24:23 +0100 Subject: [PATCH 6/6] Suppress 'extensions' warning Signed-off-by: Sam --- .../org/opensearch/security/authtoken/jwt/JwtVendorTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/java/org/opensearch/security/authtoken/jwt/JwtVendorTest.java b/src/test/java/org/opensearch/security/authtoken/jwt/JwtVendorTest.java index a93ddbd2cd..3477432462 100644 --- a/src/test/java/org/opensearch/security/authtoken/jwt/JwtVendorTest.java +++ b/src/test/java/org/opensearch/security/authtoken/jwt/JwtVendorTest.java @@ -91,7 +91,9 @@ public void testCreateJwtWithBackwardsCompatibilityMode() throws Exception { Settings settings = Settings.builder() .put("signing_key", "abc123") .put("encryption_key", claimsEncryptionKey) + // CS-SUPPRESS-SINGLE: RegexpSingleline get Extensions Settings .put(ConfigConstants.EXTENSIONS_BWC_PLUGIN_MODE, true) + // CS-ENFORCE-SINGLE .build(); Long expectedExp = currentTime.getAsLong() + expirySeconds;