- * SPDX-License-Identifier: Apache-2.0 - */ -package com.sap.cloud.security.spring.autoconfig; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; -import org.springframework.boot.web.servlet.ServletContextInitializer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.Ordered; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.context.SecurityContextHolderStrategy; - -import com.sap.cloud.security.spring.token.authentication.JavaSecurityContextHolderStrategy; - -import jakarta.servlet.ServletContext; -import jakarta.servlet.ServletException; -/** - * {@link EnableAutoConfiguration} uses a - * {@link com.sap.cloud.security.spring.token.authentication.JavaSecurityContextHolderStrategy}, which keeps the - * {@code com.sap.cloud.security.token.SecurityContext} in sync - * - *
- * Can be disabled with {@code @EnableAutoConfiguration(exclude={SecurityContextAutoConfiguration.class})} or with - * property {@code sap.spring.security.hybrid.auto = false}. - */ -@Configuration -@ConditionalOnProperty(name = "sap.spring.security.hybrid.auto", havingValue = "true", matchIfMissing = true) -@ConditionalOnWebApplication -@ConditionalOnClass(ServletContextInitializer.class) -public class SecurityContextAutoConfiguration { - - @Bean - @ConditionalOnMissingBean(SecurityContextHolderStrategy.class) - @ConditionalOnProperty(name = "sap.spring.security.hybrid.sync_securitycontext", havingValue = "true", matchIfMissing = true) - SecurityContextSetter securityContextSetter() { - return new SecurityContextSetter(); - } - - static class SecurityContextSetter implements InitializingBean, ServletContextInitializer, Ordered { - - @Override - public void afterPropertiesSet() throws Exception { - if (!(SecurityContextHolder.getContextHolderStrategy() instanceof JavaSecurityContextHolderStrategy)) { - SecurityContextHolder.setContextHolderStrategy(new JavaSecurityContextHolderStrategy()); - } - } - - @Override - public void onStartup(ServletContext servletContext) throws ServletException { - // empty, used to hook early into the initialization phase - } - - @Override - public int getOrder() { - return Ordered.HIGHEST_PRECEDENCE; - } - - } - -} diff --git a/spring-security/src/main/java/com/sap/cloud/security/spring/autoconfig/SecurityContextEnvironmentPostProcessor.java b/spring-security/src/main/java/com/sap/cloud/security/spring/autoconfig/SecurityContextEnvironmentPostProcessor.java new file mode 100644 index 0000000000..9cd19acd92 --- /dev/null +++ b/spring-security/src/main/java/com/sap/cloud/security/spring/autoconfig/SecurityContextEnvironmentPostProcessor.java @@ -0,0 +1,34 @@ +/** + * SPDX-FileCopyrightText: 2018-2023 SAP SE or an SAP affiliate company and Cloud Security Client Java contributors + *
+ * SPDX-License-Identifier: Apache-2.0 + */ +package com.sap.cloud.security.spring.autoconfig; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.env.EnvironmentPostProcessor; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.security.core.context.SecurityContextHolder; + +import com.sap.cloud.security.spring.token.authentication.JavaSecurityContextHolderStrategy; +/** + * Instantiates a {@link com.sap.cloud.security.spring.token.authentication.JavaSecurityContextHolderStrategy}, which keeps the + * {@code com.sap.cloud.security.token.SecurityContext} in sync + * + *
+ * Can be disabled with with property {@code sap.spring.security.hybrid.auto = false}.
+ */
+public class SecurityContextEnvironmentPostProcessor implements EnvironmentPostProcessor {
+
+ @Override
+ public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
+ String autoConfig = environment.getProperty("sap.spring.security.hybrid.auto");
+ String syncContext = environment.getProperty("sap.spring.security.hybrid.sync_securitycontext");
+ if ((autoConfig == null || Boolean.valueOf(autoConfig)) &&
+ (syncContext == null || Boolean.valueOf(syncContext)) &&
+ !(SecurityContextHolder.getContextHolderStrategy() instanceof JavaSecurityContextHolderStrategy)) {
+ SecurityContextHolder.setContextHolderStrategy(new JavaSecurityContextHolderStrategy());
+ }
+ }
+
+}
diff --git a/spring-security/src/main/java/com/sap/cloud/security/spring/token/authentication/JavaSecurityContextHolderStrategy.java b/spring-security/src/main/java/com/sap/cloud/security/spring/token/authentication/JavaSecurityContextHolderStrategy.java
index a5dc2ba62b..a75a0760d1 100644
--- a/spring-security/src/main/java/com/sap/cloud/security/spring/token/authentication/JavaSecurityContextHolderStrategy.java
+++ b/spring-security/src/main/java/com/sap/cloud/security/spring/token/authentication/JavaSecurityContextHolderStrategy.java
@@ -5,19 +5,20 @@
*/
package com.sap.cloud.security.spring.token.authentication;
-import com.sap.cloud.security.token.Token;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolderStrategy;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.util.Assert;
+import com.sap.cloud.security.token.Token;
+
/**
* This is an alternative to {@code ThreadLocalSecurityContextHolderStrategy} which keeps the
* {@code com.sap.cloud.security.token.SecurityContext} in sync.
*
* It's included in Spring Autoconfiguration
- * {@link com.sap.cloud.security.spring.autoconfig.SecurityContextAutoConfiguration}
+ * {@link com.sap.cloud.security.spring.autoconfig.SecurityContextEnvironmentPostProcessor}
*
*
* In cases when Spring Autoconfiguration is not used it can be enabled by setting the system environment variable
diff --git a/spring-security/src/test/java/com/sap/cloud/security/spring/autoconfig/SecurityContextAutoConfigurationTest.java b/spring-security/src/test/java/com/sap/cloud/security/spring/autoconfig/SecurityContextAutoConfigurationTest.java
deleted file mode 100644
index ea30704db7..0000000000
--- a/spring-security/src/test/java/com/sap/cloud/security/spring/autoconfig/SecurityContextAutoConfigurationTest.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * SPDX-FileCopyrightText: 2018-2023 SAP SE or an SAP affiliate company and Cloud Security Client Java contributors
- *
- * SPDX-License-Identifier: Apache-2.0 - */ -package com.sap.cloud.security.spring.autoconfig; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import org.junit.jupiter.api.Test; -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.WebApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.core.context.SecurityContextHolderStrategy; - -import com.sap.cloud.security.spring.token.authentication.JavaSecurityContextHolderStrategy; - -class SecurityContextAutoConfigurationTest { - - private final WebApplicationContextRunner runner = new WebApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(SecurityContextAutoConfiguration.class)); - - @Test - void autoConfigurationActiveByDefault() { - runner.run(context -> { - assertNotNull(context.getBean("securityContextSetter")); - assertEquals(JavaSecurityContextHolderStrategy.class, - SecurityContextHolder.getContextHolderStrategy().getClass()); - }); - } - - @Test - void autoConfigurationDisabledByProperty() { - runner.withPropertyValues("sap.spring.security.hybrid.auto:false") - .run((context) -> assertFalse(context.containsBean("securityContextSetter"))); - } - - @Test - void autoConfigurationDisabledBySpecificProperty() { - runner.withPropertyValues("sap.spring.security.hybrid.sync_securitycontext:false") - .run((context) -> assertFalse(context.containsBean("securityContextSetter"))); - } - - @Test - void autoConfigurationEnabledByProperty() { - runner.withPropertyValues("sap.spring.security.hybrid.auto:true") - .run((context) -> assertTrue(context.containsBean("securityContextSetter"))); - } - - @Test - void autoConfigurationEnabledBySpecificProperty() { - runner.withPropertyValues("sap.spring.security.hybrid.sync_securitycontext:true") - .run((context) -> assertTrue(context.containsBean("securityContextSetter"))); - } - - @Test - void userConfigurationCanOverrideDefaultBeans() { - runner.withUserConfiguration(UserConfiguration.class) - .run((context) -> { - assertFalse(context.containsBean("securityContextSetter")); - assertNotNull(context.getBean("customStrategy", SecurityContextHolderStrategy.class)); - assertNotEquals(JavaSecurityContextHolderStrategy.class, - SecurityContextHolder.getContextHolderStrategy().getClass()); - }); - } - - @Configuration - static class UserConfiguration { - - @Bean - static SecurityContextHolderStrategy customStrategy() { - SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_THREADLOCAL); - return SecurityContextHolder.getContextHolderStrategy(); - } - } -} diff --git a/spring-security/src/test/java/com/sap/cloud/security/spring/autoconfig/SecurityContextEnvironmentPostProcessorTest.java b/spring-security/src/test/java/com/sap/cloud/security/spring/autoconfig/SecurityContextEnvironmentPostProcessorTest.java new file mode 100644 index 0000000000..c00a10cd49 --- /dev/null +++ b/spring-security/src/test/java/com/sap/cloud/security/spring/autoconfig/SecurityContextEnvironmentPostProcessorTest.java @@ -0,0 +1,64 @@ +/** + * SPDX-FileCopyrightText: 2018-2023 SAP SE or an SAP affiliate company and Cloud Security Client Java contributors + *
+ * SPDX-License-Identifier: Apache-2.0
+ */
+package com.sap.cloud.security.spring.autoconfig;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.mock.env.MockEnvironment;
+import org.springframework.security.core.context.SecurityContextHolder;
+
+import com.sap.cloud.security.spring.token.authentication.JavaSecurityContextHolderStrategy;
+
+class SecurityContextEnvironmentPostProcessorTest {
+
+ private MockEnvironment env = new MockEnvironment();
+
+ @Test
+ void securityContextStrategyActiveByDefault() {
+ assertStrategy(true);
+ }
+
+ @Test
+ void securityContextStrategyDisabledByProperty() {
+ env.setProperty("sap.spring.security.hybrid.auto", "false");
+ assertStrategy(false);
+ }
+
+ @Test
+ void securityContextStrategyDisabledBySpecificProperty() {
+ env.setProperty("sap.spring.security.hybrid.sync_securitycontext", "false");
+ assertStrategy(false);
+ }
+
+ @Test
+ void securityContextStrategyEnabledByProperty() {
+ env.setProperty("sap.spring.security.hybrid.auto", "true");
+ assertStrategy(true);
+ }
+
+ @Test
+ void securityContextStrategyEnabledBySpecificProperty() {
+ env.setProperty("sap.spring.security.hybrid.sync_securitycontext", "true");
+ assertStrategy(true);
+ }
+
+ void assertStrategy(boolean applied) {
+ try {
+ SecurityContextHolder.setStrategyName(null);
+ new SecurityContextEnvironmentPostProcessor().postProcessEnvironment(env, null);
+ if (applied) {
+ assertTrue(SecurityContextHolder.getContextHolderStrategy() instanceof JavaSecurityContextHolderStrategy, "Expected custom strategy");
+ } else {
+ assertFalse(SecurityContextHolder.getContextHolderStrategy() instanceof JavaSecurityContextHolderStrategy, "Expected default strategy");
+ }
+ } finally {
+ SecurityContextHolder.setStrategyName(null);
+ }
+ }
+
+}
diff --git a/spring-xsuaa-test/pom.xml b/spring-xsuaa-test/pom.xml
index ce6cf633b6..25a69c41aa 100644
--- a/spring-xsuaa-test/pom.xml
+++ b/spring-xsuaa-test/pom.xml
@@ -21,7 +21,7 @@