Refactor hawkbit core and security (#2833)

* Refactor hawkbit core and security

* improve access to the base core features - static
* thus easiear access
* and less boilerplate passing of instances

Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>

* Refactor context classes

* make JSON context serialization default

* AccessContext

* Split hawkbit-security-core to other modules and remove it

---------

Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2025-11-27 13:07:49 +02:00
committed by GitHub
parent 58dbc32a80
commit f6f62db0ad
274 changed files with 2534 additions and 4458 deletions

View File

@@ -9,30 +9,13 @@
*/
package org.eclipse.hawkbit.autoconfigure.security;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.Optional;
import org.eclipse.hawkbit.ContextAware;
import org.eclipse.hawkbit.audit.AuditContextProvider;
import org.eclipse.hawkbit.audit.AuditLoggingAspect;
import org.eclipse.hawkbit.context.AccessContext;
import org.eclipse.hawkbit.repository.RepositoryConfiguration;
import org.eclipse.hawkbit.tenancy.TenantAware.DefaultTenantResolver;
import org.eclipse.hawkbit.tenancy.TenantAware.TenantResolver;
import org.eclipse.hawkbit.tenancy.TenantAwareUserProperties;
import org.eclipse.hawkbit.tenancy.TenantAwareUserProperties.User;
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
import org.eclipse.hawkbit.security.InMemoryUserAuthoritiesResolver;
import org.eclipse.hawkbit.security.MdcHandler;
import org.eclipse.hawkbit.security.SecurityContextSerializer;
import org.eclipse.hawkbit.security.SecurityContextTenantAware;
import org.eclipse.hawkbit.security.SecurityTokenGenerator;
import org.eclipse.hawkbit.security.SpringSecurityAuditorAware;
import org.eclipse.hawkbit.security.SystemSecurityContext;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.eclipse.hawkbit.tenancy.UserAuthoritiesResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.eclipse.hawkbit.tenancy.TenantAwareUserProperties;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
@@ -41,14 +24,12 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.domain.AuditorAware;
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.security.web.authentication.logout.SimpleUrlLogoutSuccessHandler;
import org.springframework.util.CollectionUtils;
/**
* {@link EnableAutoConfiguration Auto-configuration} for security.
@@ -58,48 +39,6 @@ import org.springframework.util.CollectionUtils;
@Import(RepositoryConfiguration.class)
public class SecurityAutoConfiguration {
/**
* 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 (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
@ConditionalOnMissingBean
public ContextAware contextAware(
final UserAuthoritiesResolver authoritiesResolver,
@Autowired(required = false) final SecurityContextSerializer securityContextSerializer,
@Autowired(required = false) final TenantResolver tenantResolver) {
return new SecurityContextTenantAware(authoritiesResolver, securityContextSerializer, tenantResolver);
}
/**
* Creates a {@link UserAuthoritiesResolver} bean that is responsible for resolving user authorities/roles.
*
* @param securityProperties The Spring {@link SecurityProperties} for the security user
* @param tenantAwareUserProperties The {@link TenantAwareUserProperties} for the managed users
* @return an {@link InMemoryUserAuthoritiesResolver} bean
*/
@Bean
@ConditionalOnMissingBean
public UserAuthoritiesResolver inMemoryAuthoritiesResolver(
final SecurityProperties securityProperties,
final TenantAwareUserProperties tenantAwareUserProperties) {
final Map<String, User> tenantAwareUsers = tenantAwareUserProperties.getUser();
final Map<String, List<String>> usersToPermissions;
if (!CollectionUtils.isEmpty(tenantAwareUsers)) {
usersToPermissions = tenantAwareUsers.entrySet().stream().collect(
Collectors.toMap(Map.Entry::getKey, e -> e.getValue().getRoles()));
} else {
usersToPermissions = Collections.singletonMap(securityProperties.getUser().getName(),
securityProperties.getUser().getRoles());
}
return new InMemoryUserAuthoritiesResolver(usersToPermissions);
}
/**
* Creates the auditor aware.
*
@@ -108,13 +47,7 @@ public class SecurityAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public AuditorAware<String> auditorAware() {
return new SpringSecurityAuditorAware();
}
@Bean
@ConditionalOnMissingBean
public AuditContextProvider auditContextProvider() {
return AuditContextProvider.getInstance();
return () -> Optional.ofNullable(AccessContext.actor());
}
@Bean
@@ -123,28 +56,6 @@ public class SecurityAutoConfiguration {
return new AuditLoggingAspect();
}
/**
* @param tenantAware singleton bean
* @return tenantAware {@link SystemSecurityContext}
*/
@Bean
@ConditionalOnMissingBean
public SystemSecurityContext systemSecurityContext(final TenantAware tenantAware, final RoleHierarchy roleHierarchy) {
return new SystemSecurityContext(tenantAware, roleHierarchy);
}
@Bean
@ConditionalOnMissingBean
public MdcHandler mdcHandler() {
return MdcHandler.getInstance();
}
@Bean
@ConditionalOnMissingBean
public SecurityTokenGenerator securityTokenGenerator() {
return new SecurityTokenGenerator();
}
@Bean
@ConditionalOnMissingBean
public AuthenticationSuccessHandler authenticationSuccessHandler() {

View File

@@ -9,7 +9,7 @@
*/
package org.eclipse.hawkbit.autoconfigure.security;
import org.eclipse.hawkbit.im.authentication.StaticAuthenticationProvider;
import org.eclipse.hawkbit.auth.StaticAuthenticationProvider;
import org.eclipse.hawkbit.tenancy.TenantAwareUserProperties;
import org.springframework.boot.autoconfigure.security.SecurityProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;

View File

@@ -14,7 +14,7 @@ hawkbit.artifact.url.protocols.download-http.hostname=localhost
hawkbit.artifact.url.protocols.download-http.ip=127.0.0.1
hawkbit.artifact.url.protocols.download-http.protocol=http
hawkbit.artifact.url.protocols.download-http.port=8080
hawkbit.artifact.url.protocols.download-http.supports=DMF,DDI
hawkbit.artifact.url.protocols.download-http.supports=DDI,DMF
hawkbit.artifact.url.protocols.download-http.ref={protocolRequest}://{hostnameRequest}:{portRequest}/{tenant}/controller/v1/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/{artifactFileName}
hawkbit.artifact.url.protocols.md5sum-http.rel=md5sum-http
hawkbit.artifact.url.protocols.md5sum-http.protocol=${hawkbit.artifact.url.protocols.download-http.protocol}