From 7980b5defb4c4dfb9bdb9e0cf52a6456d48b962c Mon Sep 17 00:00:00 2001 From: Avgustin Marinov Date: Thu, 18 Sep 2025 14:46:51 +0300 Subject: [PATCH] Remove Java security context serialization (#2677) Remove Java security context serialization - it is replaced by JSON security context serialization (optimized as size). Backward incompatible change. Java security context serialization was not used in default hawkbit runtime out of the box. So, it's assumed none uses it. Anyway, if anyone has enabled it, he could, in order to keep backward compatibility, get the java security context serialization from the previous hawkbit releases/commits and register it again as a spring bean in his hawkbit extension. Signed-off-by: Avgustin Marinov --- .../security/SecurityAutoConfiguration.java | 7 ++-- .../GatewayTokenAuthenticatorTest.java | 32 +++++++------------ .../SecurityHeaderAuthenticatorTest.java | 29 ++++++----------- .../SecurityTokenAuthenticatorTest.java | 18 ++++------- .../amqp/AmqpMessageHandlerServiceTest.java | 5 +-- .../jpa/acm/AcmTestConfiguration.java | 25 +++++++++++++++ .../repository/jpa/acm/ContextAwareTest.java | 2 ++ .../jpa/acm/TargetAccessControllerTest.java | 2 +- .../repository/test/TestConfiguration.java | 9 ++---- .../security/SecurityContextSerializer.java | 23 +------------ .../SecurityContextSerializerTest.java | 21 +----------- 11 files changed, 66 insertions(+), 107 deletions(-) create mode 100644 hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/AcmTestConfiguration.java diff --git a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityAutoConfiguration.java b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityAutoConfiguration.java index 08defa6f5..96b9980bb 100644 --- a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityAutoConfiguration.java +++ b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityAutoConfiguration.java @@ -65,11 +65,12 @@ public class SecurityAutoConfiguration { } /** - * Creates a {@link ContextAware} (hence {@link TenantAware}) bean based on the given {@link UserAuthoritiesResolver} and - * {@link SecurityContextSerializer}. + * Creates a {@link ContextAware} (hence {@link TenantAware}) bean based on the given {@link UserAuthoritiesResolver}, + * {@link SecurityContextSerializer} and {@link TenantResolver}. * * @param authoritiesResolver The user authorities/roles resolver - * @param securityContextSerializer The security context serializer. + * @param securityContextSerializer The security context serializer (optional, if not found the default {@link SecurityContextSerializer#NOP} is used). + * @param tenantResolver The tenant resolver (optional, if not found the default {@link DefaultTenantResolver} is used). * @return the {@link ContextAware} singleton bean. */ @Bean diff --git a/hawkbit-ddi/hawkbit-ddi-security/src/test/java/org/eclipse/hawkbit/security/controller/GatewayTokenAuthenticatorTest.java b/hawkbit-ddi/hawkbit-ddi-security/src/test/java/org/eclipse/hawkbit/security/controller/GatewayTokenAuthenticatorTest.java index cc23cd637..346f50eb6 100644 --- a/hawkbit-ddi/hawkbit-ddi-security/src/test/java/org/eclipse/hawkbit/security/controller/GatewayTokenAuthenticatorTest.java +++ b/hawkbit-ddi/hawkbit-ddi-security/src/test/java/org/eclipse/hawkbit/security/controller/GatewayTokenAuthenticatorTest.java @@ -10,15 +10,16 @@ package org.eclipse.hawkbit.security.controller; import static org.assertj.core.api.Assertions.assertThat; +import static org.eclipse.hawkbit.security.controller.GatewayTokenAuthenticator.GATEWAY_SECURITY_TOKEN_AUTH_SCHEME; +import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_ENABLED; +import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY; import static org.mockito.Mockito.when; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; -import org.eclipse.hawkbit.security.SecurityContextSerializer; import org.eclipse.hawkbit.security.SecurityContextTenantAware; import org.eclipse.hawkbit.security.SystemSecurityContext; import org.eclipse.hawkbit.tenancy.UserAuthoritiesResolver; -import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -32,7 +33,7 @@ import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) class GatewayTokenAuthenticatorTest { - private static final String CONTROLLER_ID = "controllerId_gwtoken"; + private static final String CONTROLLER_ID = "controllerId_gwToken"; private static final String GATEWAY_TOKEN = "test-gw-token"; private static final String UNKNOWN_TOKEN = "unknown"; @@ -49,15 +50,11 @@ class GatewayTokenAuthenticatorTest { private TenantConfigurationManagement tenantConfigurationManagementMock; @Mock private UserAuthoritiesResolver authoritiesResolver; - @Mock - private SecurityContextSerializer securityContextSerializer; @BeforeEach void before() { - final SecurityContextTenantAware tenantAware = new SecurityContextTenantAware(authoritiesResolver, securityContextSerializer); - authenticator = new GatewayTokenAuthenticator( - tenantConfigurationManagementMock, tenantAware, - new SystemSecurityContext(tenantAware)); + final SecurityContextTenantAware tenantAware = new SecurityContextTenantAware(authoritiesResolver); + authenticator = new GatewayTokenAuthenticator(tenantConfigurationManagementMock, tenantAware, new SystemSecurityContext(tenantAware)); } /** @@ -66,11 +63,9 @@ class GatewayTokenAuthenticatorTest { @Test void testWithGwToken() { final ControllerSecurityToken securityToken = prepareSecurityToken(GATEWAY_TOKEN); - when(tenantConfigurationManagementMock.getConfigurationValue( - TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY, String.class)) + when(tenantConfigurationManagementMock.getConfigurationValue(AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY, String.class)) .thenReturn(CONFIG_VALUE_GW_TOKEN); - when(tenantConfigurationManagementMock.getConfigurationValue( - TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_ENABLED, Boolean.class)) + when(tenantConfigurationManagementMock.getConfigurationValue(AUTHENTICATION_GATEWAY_SECURITY_TOKEN_ENABLED, Boolean.class)) .thenReturn(CONFIG_VALUE_ENABLED); assertThat(authenticator.authenticate(securityToken)) @@ -84,11 +79,9 @@ class GatewayTokenAuthenticatorTest { @Test void testWithBadGwToken() { final ControllerSecurityToken securityToken = prepareSecurityToken(UNKNOWN_TOKEN); - when(tenantConfigurationManagementMock.getConfigurationValue( - TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY, String.class)) + when(tenantConfigurationManagementMock.getConfigurationValue(AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY, String.class)) .thenReturn(CONFIG_VALUE_GW_TOKEN); - when(tenantConfigurationManagementMock.getConfigurationValue( - TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_ENABLED, Boolean.class)) + when(tenantConfigurationManagementMock.getConfigurationValue(AUTHENTICATION_GATEWAY_SECURITY_TOKEN_ENABLED, Boolean.class)) .thenReturn(CONFIG_VALUE_ENABLED); assertThat(authenticator.authenticate(securityToken)).isNull(); @@ -108,8 +101,7 @@ class GatewayTokenAuthenticatorTest { @Test void testWithGwTokenButDisabled() { final ControllerSecurityToken securityToken = prepareSecurityToken(GATEWAY_TOKEN); - when(tenantConfigurationManagementMock.getConfigurationValue( - TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_ENABLED, Boolean.class)) + when(tenantConfigurationManagementMock.getConfigurationValue(AUTHENTICATION_GATEWAY_SECURITY_TOKEN_ENABLED, Boolean.class)) .thenReturn(CONFIG_VALUE_DISABLED); assertThat(authenticator.authenticate(securityToken)).isNull(); @@ -117,7 +109,7 @@ class GatewayTokenAuthenticatorTest { private static ControllerSecurityToken prepareSecurityToken(final String gwToken) { final ControllerSecurityToken securityToken = new ControllerSecurityToken("DEFAULT", CONTROLLER_ID); - securityToken.putHeader(ControllerSecurityToken.AUTHORIZATION_HEADER, GatewayTokenAuthenticator.GATEWAY_SECURITY_TOKEN_AUTH_SCHEME + gwToken); + securityToken.putHeader(ControllerSecurityToken.AUTHORIZATION_HEADER, GATEWAY_SECURITY_TOKEN_AUTH_SCHEME + gwToken); return securityToken; } } \ No newline at end of file diff --git a/hawkbit-ddi/hawkbit-ddi-security/src/test/java/org/eclipse/hawkbit/security/controller/SecurityHeaderAuthenticatorTest.java b/hawkbit-ddi/hawkbit-ddi-security/src/test/java/org/eclipse/hawkbit/security/controller/SecurityHeaderAuthenticatorTest.java index 20c89b0b1..73e4190f3 100644 --- a/hawkbit-ddi/hawkbit-ddi-security/src/test/java/org/eclipse/hawkbit/security/controller/SecurityHeaderAuthenticatorTest.java +++ b/hawkbit-ddi/hawkbit-ddi-security/src/test/java/org/eclipse/hawkbit/security/controller/SecurityHeaderAuthenticatorTest.java @@ -10,15 +10,15 @@ package org.eclipse.hawkbit.security.controller; import static org.assertj.core.api.Assertions.assertThat; +import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.AUTHENTICATION_HEADER_AUTHORITY_NAME; +import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.AUTHENTICATION_HEADER_ENABLED; import static org.mockito.Mockito.when; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; -import org.eclipse.hawkbit.security.SecurityContextSerializer; import org.eclipse.hawkbit.security.SecurityContextTenantAware; import org.eclipse.hawkbit.security.SystemSecurityContext; import org.eclipse.hawkbit.tenancy.UserAuthoritiesResolver; -import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -59,12 +59,10 @@ class SecurityHeaderAuthenticatorTest { private TenantConfigurationManagement tenantConfigurationManagementMock; @Mock private UserAuthoritiesResolver authoritiesResolver; - @Mock - private SecurityContextSerializer securityContextSerializer; @BeforeEach void before() { - final SecurityContextTenantAware tenantAware = new SecurityContextTenantAware(authoritiesResolver, securityContextSerializer); + final SecurityContextTenantAware tenantAware = new SecurityContextTenantAware(authoritiesResolver); authenticator = new SecurityHeaderAuthenticator( tenantConfigurationManagementMock, tenantAware, new SystemSecurityContext(tenantAware), CA_COMMON_NAME, "X-Ssl-Issuer-Hash-%d" @@ -77,11 +75,9 @@ class SecurityHeaderAuthenticatorTest { @Test void testWithSingleKnownHash() { final ControllerSecurityToken securityToken = prepareSecurityToken(SINGLE_HASH); - when(tenantConfigurationManagementMock.getConfigurationValue( - TenantConfigurationKey.AUTHENTICATION_HEADER_AUTHORITY_NAME, String.class)) + when(tenantConfigurationManagementMock.getConfigurationValue(AUTHENTICATION_HEADER_AUTHORITY_NAME, String.class)) .thenReturn(CONFIG_VALUE_SINGLE_HASH); - when(tenantConfigurationManagementMock.getConfigurationValue( - TenantConfigurationKey.AUTHENTICATION_HEADER_ENABLED, Boolean.class)) + when(tenantConfigurationManagementMock.getConfigurationValue(AUTHENTICATION_HEADER_ENABLED, Boolean.class)) .thenReturn(CONFIG_VALUE_ENABLED); assertThat(authenticator.authenticate(securityToken)) @@ -94,11 +90,9 @@ class SecurityHeaderAuthenticatorTest { */ @Test void testWithMultipleKnownHashes() { - when(tenantConfigurationManagementMock.getConfigurationValue( - TenantConfigurationKey.AUTHENTICATION_HEADER_AUTHORITY_NAME, String.class)) + when(tenantConfigurationManagementMock.getConfigurationValue(AUTHENTICATION_HEADER_AUTHORITY_NAME, String.class)) .thenReturn(CONFIG_VALUE_MULTI_HASH); - when(tenantConfigurationManagementMock.getConfigurationValue( - TenantConfigurationKey.AUTHENTICATION_HEADER_ENABLED, Boolean.class)) + when(tenantConfigurationManagementMock.getConfigurationValue(AUTHENTICATION_HEADER_ENABLED, Boolean.class)) .thenReturn(CONFIG_VALUE_ENABLED); assertThat(authenticator.authenticate(prepareSecurityToken(SINGLE_HASH))) @@ -118,11 +112,9 @@ class SecurityHeaderAuthenticatorTest { @Test void testWithUnknownHash() { final ControllerSecurityToken securityToken = prepareSecurityToken(UNKNOWN_HASH); - when(tenantConfigurationManagementMock.getConfigurationValue( - TenantConfigurationKey.AUTHENTICATION_HEADER_AUTHORITY_NAME, String.class)) + when(tenantConfigurationManagementMock.getConfigurationValue(AUTHENTICATION_HEADER_AUTHORITY_NAME, String.class)) .thenReturn(CONFIG_VALUE_MULTI_HASH); - when(tenantConfigurationManagementMock.getConfigurationValue( - TenantConfigurationKey.AUTHENTICATION_HEADER_ENABLED, Boolean.class)) + when(tenantConfigurationManagementMock.getConfigurationValue(AUTHENTICATION_HEADER_ENABLED, Boolean.class)) .thenReturn(CONFIG_VALUE_ENABLED); assertThat(authenticator.authenticate(securityToken)).isNull(); @@ -154,8 +146,7 @@ class SecurityHeaderAuthenticatorTest { @Test void testWithSingleKnownHashButDisabled() { final ControllerSecurityToken securityToken = prepareSecurityToken(SINGLE_HASH); - when(tenantConfigurationManagementMock.getConfigurationValue( - TenantConfigurationKey.AUTHENTICATION_HEADER_ENABLED, Boolean.class)) + when(tenantConfigurationManagementMock.getConfigurationValue(AUTHENTICATION_HEADER_ENABLED, Boolean.class)) .thenReturn(CONFIG_VALUE_DISABLED); assertThat(authenticator.authenticate(securityToken)).isNull(); diff --git a/hawkbit-ddi/hawkbit-ddi-security/src/test/java/org/eclipse/hawkbit/security/controller/SecurityTokenAuthenticatorTest.java b/hawkbit-ddi/hawkbit-ddi-security/src/test/java/org/eclipse/hawkbit/security/controller/SecurityTokenAuthenticatorTest.java index 008438c0d..bce2cea42 100644 --- a/hawkbit-ddi/hawkbit-ddi-security/src/test/java/org/eclipse/hawkbit/security/controller/SecurityTokenAuthenticatorTest.java +++ b/hawkbit-ddi/hawkbit-ddi-security/src/test/java/org/eclipse/hawkbit/security/controller/SecurityTokenAuthenticatorTest.java @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.security.controller; import static org.assertj.core.api.Assertions.assertThat; +import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.AUTHENTICATION_TARGET_SECURITY_TOKEN_ENABLED; import static org.mockito.Mockito.when; import java.util.Optional; @@ -18,11 +19,9 @@ import org.eclipse.hawkbit.repository.ControllerManagement; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; -import org.eclipse.hawkbit.security.SecurityContextSerializer; import org.eclipse.hawkbit.security.SecurityContextTenantAware; import org.eclipse.hawkbit.security.SystemSecurityContext; import org.eclipse.hawkbit.tenancy.UserAuthoritiesResolver; -import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -37,7 +36,7 @@ import org.mockito.junit.jupiter.MockitoExtension; @ExtendWith(MockitoExtension.class) class SecurityTokenAuthenticatorTest { - private static final String CONTROLLER_ID = "controllerId_gwtoken"; + private static final String CONTROLLER_ID = "controllerId_token"; private static final String SECURITY_TOKEN = "test-sec-token"; private static final String UNKNOWN_TOKEN = "unknown"; @@ -54,12 +53,10 @@ class SecurityTokenAuthenticatorTest { private ControllerManagement controllerManagementMock; @Mock private UserAuthoritiesResolver authoritiesResolver; - @Mock - private SecurityContextSerializer securityContextSerializer; @BeforeEach void before() { - final SecurityContextTenantAware tenantAware = new SecurityContextTenantAware(authoritiesResolver, securityContextSerializer); + final SecurityContextTenantAware tenantAware = new SecurityContextTenantAware(authoritiesResolver); authenticator = new SecurityTokenAuthenticator( tenantConfigurationManagementMock, tenantAware, new SystemSecurityContext(tenantAware), controllerManagementMock); @@ -71,8 +68,7 @@ class SecurityTokenAuthenticatorTest { @Test void testWithSecToken() { final ControllerSecurityToken securityToken = prepareSecurityToken(SECURITY_TOKEN); - when(tenantConfigurationManagementMock.getConfigurationValue( - TenantConfigurationKey.AUTHENTICATION_TARGET_SECURITY_TOKEN_ENABLED, Boolean.class)) + when(tenantConfigurationManagementMock.getConfigurationValue(AUTHENTICATION_TARGET_SECURITY_TOKEN_ENABLED, Boolean.class)) .thenReturn(CONFIG_VALUE_ENABLED); final Target target = Mockito.mock(Target.class); @@ -91,8 +87,7 @@ class SecurityTokenAuthenticatorTest { @Test void testWithBadSecToken() { final ControllerSecurityToken securityToken = prepareSecurityToken(UNKNOWN_TOKEN); - when(tenantConfigurationManagementMock.getConfigurationValue( - TenantConfigurationKey.AUTHENTICATION_TARGET_SECURITY_TOKEN_ENABLED, Boolean.class)) + when(tenantConfigurationManagementMock.getConfigurationValue(AUTHENTICATION_TARGET_SECURITY_TOKEN_ENABLED, Boolean.class)) .thenReturn(CONFIG_VALUE_ENABLED); assertThat(authenticator.authenticate(securityToken)).isNull(); @@ -112,8 +107,7 @@ class SecurityTokenAuthenticatorTest { @Test void testWithSecTokenButDisabled() { final ControllerSecurityToken securityToken = prepareSecurityToken(SECURITY_TOKEN); - when(tenantConfigurationManagementMock.getConfigurationValue( - TenantConfigurationKey.AUTHENTICATION_TARGET_SECURITY_TOKEN_ENABLED, Boolean.class)) + when(tenantConfigurationManagementMock.getConfigurationValue(AUTHENTICATION_TARGET_SECURITY_TOKEN_ENABLED, Boolean.class)) .thenReturn(CONFIG_VALUE_DISABLED); assertThat(authenticator.authenticate(securityToken)).isNull(); diff --git a/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java b/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java index c047956a4..bf97431d4 100644 --- a/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java +++ b/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java @@ -46,7 +46,6 @@ import org.eclipse.hawkbit.repository.model.ActionProperties; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; -import org.eclipse.hawkbit.security.SecurityContextSerializer; import org.eclipse.hawkbit.security.SecurityContextTenantAware; import org.eclipse.hawkbit.security.SecurityTokenGenerator; import org.eclipse.hawkbit.security.SystemSecurityContext; @@ -96,8 +95,6 @@ class AmqpMessageHandlerServiceTest { private RabbitTemplate rabbitTemplate; @Mock private UserAuthoritiesResolver authoritiesResolver; - @Mock - private SecurityContextSerializer securityContextSerializer; @Captor private ArgumentCaptor> attributesCaptor; @@ -126,7 +123,7 @@ class AmqpMessageHandlerServiceTest { lenient().when(tenantConfigurationManagement.getConfigurationValue(MULTI_ASSIGNMENTS_ENABLED, Boolean.class)) .thenReturn(multiAssignmentConfig); - final SecurityContextTenantAware tenantAware = new SecurityContextTenantAware(authoritiesResolver, securityContextSerializer); + final SecurityContextTenantAware tenantAware = new SecurityContextTenantAware(authoritiesResolver); final SystemSecurityContext systemSecurityContext = new SystemSecurityContext(tenantAware); amqpMessageHandlerService = new AmqpMessageHandlerService(rabbitTemplate, amqpMessageDispatcherServiceMock, diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/AcmTestConfiguration.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/AcmTestConfiguration.java new file mode 100644 index 000000000..f52fa3633 --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/AcmTestConfiguration.java @@ -0,0 +1,25 @@ +/** + * Copyright (c) 2025 Contributors to the Eclipse Foundation + * + * This program and the accompanying materials are made + * available under the terms of the Eclipse Public License 2.0 + * which is available at https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.hawkbit.repository.jpa.acm; + +import org.eclipse.hawkbit.security.SecurityContextSerializer; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +class AcmTestConfiguration { + + @Bean + @ConditionalOnMissingBean + SecurityContextSerializer securityContextSerializer() { + return SecurityContextSerializer.JSON_SERIALIZATION; + } +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/ContextAwareTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/ContextAwareTest.java index 94705aac0..1fb410741 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/ContextAwareTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/ContextAwareTest.java @@ -37,11 +37,13 @@ import org.springframework.security.authentication.UsernamePasswordAuthenticatio import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.test.context.ContextConfiguration; /** * Feature: Component Tests - Context runner
* Story: Test Context Runner */ +@ContextConfiguration(classes = { AcmTestConfiguration.class }) class ContextAwareTest extends AbstractJpaIntegrationTest { private static final List AUTHORITIES = SpPermission.getAllAuthorities(); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/TargetAccessControllerTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/TargetAccessControllerTest.java index c1995a45f..6e8069e9d 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/TargetAccessControllerTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/acm/TargetAccessControllerTest.java @@ -49,7 +49,7 @@ import org.springframework.test.context.ContextConfiguration; * Feature: Component Tests - Access Control
* Story: Test Target Access Controller */ -@ContextConfiguration(classes = { DefaultAccessControllerConfiguration.class }) +@ContextConfiguration(classes = { DefaultAccessControllerConfiguration.class, AcmTestConfiguration.class }) class TargetAccessControllerTest extends AbstractJpaIntegrationTest { @Autowired diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/TestConfiguration.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/TestConfiguration.java index ed53e2a59..e982ca730 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/TestConfiguration.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/TestConfiguration.java @@ -47,6 +47,7 @@ import org.eclipse.hawkbit.tenancy.configuration.ControllerPollProperties; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties; import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; import org.springframework.aop.interceptor.SimpleAsyncUncaughtExceptionHandler; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cache.caffeine.CaffeineCacheManager; @@ -144,11 +145,6 @@ public class TestConfiguration implements AsyncConfigurer { return (tenant, username) -> Collections.emptyList(); } - @Bean - SecurityContextSerializer securityContextSerializer() { - return SecurityContextSerializer.JSON_SERIALIZATION; - } - @Bean TenantResolver tenantResolver() { return new DefaultTenantResolver(); @@ -156,7 +152,8 @@ public class TestConfiguration implements AsyncConfigurer { @Bean ContextAware contextAware( - final UserAuthoritiesResolver authoritiesResolver, final SecurityContextSerializer securityContextSerializer, + final UserAuthoritiesResolver authoritiesResolver, + @Autowired(required = false) final SecurityContextSerializer securityContextSerializer, final TenantResolver tenantResolver) { // allow spying the security context return org.mockito.Mockito.spy(new SecurityContextTenantAware(authoritiesResolver, securityContextSerializer, tenantResolver)); diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SecurityContextSerializer.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SecurityContextSerializer.java index 0d7ed06bf..b04c34342 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SecurityContextSerializer.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SecurityContextSerializer.java @@ -32,7 +32,6 @@ import org.eclipse.hawkbit.security.SpringSecurityAuditorAware.AuditorAwarePrinc import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails; import org.eclipse.hawkbit.tenancy.TenantAwareUser; import org.springframework.security.core.Authentication; -import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.context.SecurityContext; @@ -49,17 +48,8 @@ public interface SecurityContextSerializer { SecurityContextSerializer NOP = new Nop(); /** * Serializer the uses JSON serialization. - *

- * Note that on deserialization this serialization does (if configured) fallback to {@link #JAVA_SERIALIZATION}. */ SecurityContextSerializer JSON_SERIALIZATION = new JsonSerialization(); - /** - * Serializer the uses Java serialization of {@link java.io.Serializable} objects (legacy, not recommended). - *

- * Note that serialized via java serialization context might become unreadable if incompatible - * changes are made to the object classes. - */ - SecurityContextSerializer JAVA_SERIALIZATION = new JavaSerialization(); /** * Return security context as string (could be just a reference) @@ -82,11 +72,9 @@ public interface SecurityContextSerializer { * It returns null as serialized context and throws exception if * someone try to deserialize anything. */ + @NoArgsConstructor(access = AccessLevel.PRIVATE) class Nop implements SecurityContextSerializer { - private Nop() { - } - @Override public String serialize(final SecurityContext securityContext) { return null; @@ -106,8 +94,6 @@ public interface SecurityContextSerializer { class JsonSerialization implements SecurityContextSerializer { private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); - private static final boolean FALLBACK_TO_JAVA_SERIALIZATION = - !Boolean.getBoolean("hawkbit.security.contextSerializer.json.no-fallback-to-java"); @Override public String serialize(final SecurityContext securityContext) { @@ -124,13 +110,6 @@ public interface SecurityContextSerializer { Objects.requireNonNull(securityContextString); final String securityContextTrimmed = securityContextString.trim(); try { - // java serialization starts with {@link ObjectStreamConstants#STREAM_MAGIC} (0xAC, 0xED) bytes - // while trimmed json object starts with '{' - if (FALLBACK_TO_JAVA_SERIALIZATION && - (securityContextTrimmed.isEmpty() || securityContextTrimmed.charAt(0) != '{')) { - return JAVA_SERIALIZATION.deserialize(securityContextString); - } - return OBJECT_MAPPER.readerFor(SecCtxInfo.class). readValue(securityContextTrimmed).toSecurityContext(); } catch (final JsonProcessingException e) { throw new RuntimeException(e); diff --git a/hawkbit-security-core/src/test/java/org/eclipse/hawkbit/security/SecurityContextSerializerTest.java b/hawkbit-security-core/src/test/java/org/eclipse/hawkbit/security/SecurityContextSerializerTest.java index bb9e93192..75c66a900 100644 --- a/hawkbit-security-core/src/test/java/org/eclipse/hawkbit/security/SecurityContextSerializerTest.java +++ b/hawkbit-security-core/src/test/java/org/eclipse/hawkbit/security/SecurityContextSerializerTest.java @@ -10,7 +10,6 @@ package org.eclipse.hawkbit.security; import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.hawkbit.security.SecurityContextSerializer.JAVA_SERIALIZATION; import static org.eclipse.hawkbit.security.SecurityContextSerializer.JSON_SERIALIZATION; import java.util.List; @@ -63,24 +62,6 @@ class SecurityContextSerializerTest { assertThat(serialized).hasSizeLessThan(4096); // ensure that it is not too big } - // test JSON serialization fallback to java serialization - @Test - void backwardCompatibilityOfJavaSerialization() { - final SecurityContext securityContext = SecurityContextHolder.getContext(); - securityContext.setAuthentication( - new UsernamePasswordAuthenticationToken("user", null, AUTHORITIES.stream().map(SimpleGrantedAuthority::new).toList())); - - final String newSerialized = JSON_SERIALIZATION.serialize(securityContext); - final String oldSerialized = JAVA_SERIALIZATION.serialize(securityContext); - - assertThat(oldSerialized).isNotEqualTo(newSerialized); - final Authentication deserializedOld = JSON_SERIALIZATION.deserialize(oldSerialized).getAuthentication(); - final Authentication deserializedNew = JSON_SERIALIZATION.deserialize(newSerialized).getAuthentication(); - assertThat(SpringSecurityAuditorAware.resolveAuditor(deserializedOld)).hasToString(SpringSecurityAuditorAware.resolveAuditor(deserializedNew)); - assertThat(deserializedOld.getAuthorities()).isEqualTo(deserializedNew.getAuthorities()); - assertThat(deserializedOld.isAuthenticated()).isEqualTo(deserializedNew.isAuthenticated()); - } - @Test void testUsername() { final SecurityContext securityContext = SecurityContextHolder.getContext(); @@ -106,4 +87,4 @@ class SecurityContextSerializerTest { } return sb.toString(); } -} +} \ No newline at end of file