diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 72b5a6380..f7942085e 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -33,7 +33,7 @@ dependencies on hawkBit users. We in fact are looking into reducing them in futu
So we kindly ask contributors:
* not introduce extra utility library dependencies
-* keep them out of the core modules (e.g. hawkbit-core, hawkbit-rest-core, hawkbit-http-security) to avoid that all
+* keep them out of the core modules (e.g. hawkbit-core, hawkbit-rest-core) to avoid that all
modules have them as transitive dependency
* use utility functions in general based in the following priority:
* use utility functions from JDK if feasible
diff --git a/hawkbit-autoconfigure/pom.xml b/hawkbit-autoconfigure/pom.xml
index 06a52e6a4..22fdb0b66 100644
--- a/hawkbit-autoconfigure/pom.xml
+++ b/hawkbit-autoconfigure/pom.xml
@@ -33,12 +33,6 @@
${project.version}
true
-
- org.eclipse.hawkbit
- hawkbit-http-security
- ${project.version}
- true
-
org.eclipse.hawkbit
hawkbit-security-core
diff --git a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/EnableHawkbitManagedSecurityConfiguration.java b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/EnableHawkbitManagedSecurityConfiguration.java
deleted file mode 100644
index ddbe7b8f5..000000000
--- a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/EnableHawkbitManagedSecurityConfiguration.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/**
- * Copyright (c) 2015 Bosch Software Innovations GmbH and others
- *
- * 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.autoconfigure.security;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-import org.springframework.context.annotation.Import;
-
-/**
- * Annotation to enable the managed security configuration.
- */
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.RUNTIME)
-@Import(SecurityManagedConfiguration.class)
-public @interface EnableHawkbitManagedSecurityConfiguration {
-
-}
diff --git a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java
deleted file mode 100644
index c74ae3ee4..000000000
--- a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java
+++ /dev/null
@@ -1,526 +0,0 @@
-/**
- * Copyright (c) 2015 Bosch Software Innovations GmbH and others
- *
- * 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.autoconfigure.security;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
-import jakarta.servlet.http.HttpServletRequest;
-
-import lombok.extern.slf4j.Slf4j;
-import org.eclipse.hawkbit.ddi.rest.api.DdiRestConstants;
-import org.eclipse.hawkbit.ddi.rest.resource.DdiApiConfiguration;
-import org.eclipse.hawkbit.im.authentication.SpPermission;
-import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
-import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
-import org.eclipse.hawkbit.mgmt.rest.resource.MgmtApiConfiguration;
-import org.eclipse.hawkbit.repository.ControllerManagement;
-import org.eclipse.hawkbit.repository.SystemManagement;
-import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
-import org.eclipse.hawkbit.security.ControllerTenantAwareAuthenticationDetailsSource;
-import org.eclipse.hawkbit.security.DdiSecurityProperties;
-import org.eclipse.hawkbit.security.DosFilter;
-import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
-import org.eclipse.hawkbit.security.HttpControllerPreAuthenticateAnonymousDownloadFilter;
-import org.eclipse.hawkbit.security.HttpControllerPreAuthenticateSecurityTokenFilter;
-import org.eclipse.hawkbit.security.HttpControllerPreAuthenticatedGatewaySecurityTokenFilter;
-import org.eclipse.hawkbit.security.HttpControllerPreAuthenticatedSecurityHeaderFilter;
-import org.eclipse.hawkbit.security.MdcHandler;
-import org.eclipse.hawkbit.security.PreAuthTokenSourceTrustAuthenticationProvider;
-import org.eclipse.hawkbit.security.SystemSecurityContext;
-import org.eclipse.hawkbit.tenancy.TenantAware;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
-import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
-import org.springframework.boot.web.servlet.FilterRegistrationBean;
-import org.springframework.context.annotation.AdviceMode;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.PropertySource;
-import org.springframework.core.Ordered;
-import org.springframework.core.annotation.Order;
-import org.springframework.http.HttpStatus;
-import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.config.Customizer;
-import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
-import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
-import org.springframework.security.config.annotation.web.builders.HttpSecurity;
-import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
-import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
-import org.springframework.security.config.http.SessionCreationPolicy;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.authority.SimpleGrantedAuthority;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.web.SecurityFilterChain;
-import org.springframework.security.web.authentication.AnonymousAuthenticationFilter;
-import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;
-import org.springframework.security.web.firewall.FirewalledRequest;
-import org.springframework.security.web.firewall.HttpFirewall;
-import org.springframework.security.web.firewall.StrictHttpFirewall;
-import org.springframework.security.web.session.SessionManagementFilter;
-import org.springframework.util.CollectionUtils;
-import org.springframework.web.cors.CorsConfiguration;
-import org.springframework.web.cors.CorsConfigurationSource;
-
-/**
- * All configurations related to HawkBit's authentication and authorization layer.
- */
-@Slf4j
-@Configuration
-@EnableWebSecurity
-@EnableGlobalMethodSecurity(prePostEnabled = true, mode = AdviceMode.ASPECTJ, proxyTargetClass = true, securedEnabled = true)
-@Order(Ordered.HIGHEST_PRECEDENCE)
-@PropertySource("classpath:hawkbit-security-defaults.properties")
-public class SecurityManagedConfiguration {
-
- public static final String ANONYMOUS_CONTROLLER_SECURITY_ENABLED_SHOULD_ONLY_BE_USED_FOR_DEVELOPMENT_PURPOSES = """
- ******************
- ** Anonymous controller security enabled, should only be used for development purposes **
- ******************""";
- private static final int DOS_FILTER_ORDER = -200;
-
- /**
- * Filter to protect the hawkBit server system management interface against too many requests.
- *
- * @param securityProperties for filter configuration
- * @return the spring filter registration bean for registering a denial of service protection filter in the filter chain
- */
- @Bean
- @ConditionalOnProperty(prefix = "hawkbit.server.security.dos.filter", name = "enabled", matchIfMissing = true)
- public FilterRegistrationBean dosSystemFilter(final HawkbitSecurityProperties securityProperties) {
- final FilterRegistrationBean filterRegBean = dosFilter(Collections.emptyList(),
- securityProperties.getDos().getFilter(), securityProperties.getClients());
- filterRegBean.setUrlPatterns(List.of("/system/*"));
- filterRegBean.setOrder(DOS_FILTER_ORDER);
- filterRegBean.setName("dosSystemFilter");
-
- return filterRegBean;
- }
-
- /**
- * HttpFirewall which enables to define a list of allowed host names.
- *
- * @return the http firewall.
- */
- @Bean
- public HttpFirewall httpFirewall(final HawkbitSecurityProperties hawkbitSecurityProperties) {
- final List allowedHostNames = hawkbitSecurityProperties.getAllowedHostNames();
- final IgnorePathsStrictHttpFirewall firewall = new IgnorePathsStrictHttpFirewall(
- hawkbitSecurityProperties.getHttpFirewallIgnoredPaths());
-
- if (!CollectionUtils.isEmpty(allowedHostNames)) {
- firewall.setAllowedHostnames(hostName -> {
- log.debug("Firewall check host: {}, allowed: {}", hostName, allowedHostNames.contains(hostName));
- return allowedHostNames.contains(hostName);
- });
- }
- return firewall;
- }
-
- private static FilterRegistrationBean dosFilter(final Collection includeAntPaths,
- final HawkbitSecurityProperties.Dos.Filter filterProperties,
- final HawkbitSecurityProperties.Clients clientProperties) {
- final FilterRegistrationBean filterRegBean = new FilterRegistrationBean<>();
-
- filterRegBean.setFilter(new DosFilter(includeAntPaths, filterProperties.getMaxRead(),
- filterProperties.getMaxWrite(), filterProperties.getWhitelist(), clientProperties.getBlacklist(),
- clientProperties.getRemoteIpHeader()));
-
- return filterRegBean;
- }
-
- private static AuthenticationManager setAuthenticationManager(final HttpSecurity http, final DdiSecurityProperties ddiSecurityConfiguration)
- throws Exception {
- // configure authentication manager
- final AuthenticationManager authenticationManager =
- http
- .getSharedObject(AuthenticationManagerBuilder.class)
- .authenticationProvider(
- new PreAuthTokenSourceTrustAuthenticationProvider(ddiSecurityConfiguration.getRp().getTrustedIPs()))
- .build();
- http.authenticationManager(authenticationManager);
- return authenticationManager;
- }
-
- /**
- * Security configuration for the hawkBit server DDI interface.
- */
- @Configuration
- @EnableWebSecurity
- @ConditionalOnClass(DdiApiConfiguration.class)
- static class ControllerSecurityConfigurationAdapter {
-
- private static final String[] DDI_ANT_MATCHERS = {
- DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}",
- DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/confirmationBase/**",
- DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/deploymentBase/**",
- DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/installedBase/**",
- DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/cancelAction/**",
- DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/configData",
- DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/softwaremodules/{softwareModuleId}/artifacts" };
-
- private final ControllerManagement controllerManagement;
- private final TenantConfigurationManagement tenantConfigurationManagement;
- private final TenantAware tenantAware;
- private final DdiSecurityProperties ddiSecurityConfiguration;
- private final HawkbitSecurityProperties securityProperties;
- private final SystemSecurityContext systemSecurityContext;
-
- @Autowired
- ControllerSecurityConfigurationAdapter(final ControllerManagement controllerManagement,
- final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware,
- final DdiSecurityProperties ddiSecurityConfiguration,
- final HawkbitSecurityProperties securityProperties, final SystemSecurityContext systemSecurityContext) {
- this.controllerManagement = controllerManagement;
- this.tenantConfigurationManagement = tenantConfigurationManagement;
- this.tenantAware = tenantAware;
- this.ddiSecurityConfiguration = ddiSecurityConfiguration;
- this.securityProperties = securityProperties;
- this.systemSecurityContext = systemSecurityContext;
- }
-
- /**
- * Filter to protect the hawkBit server DDI interface against too many requests.
- *
- * @param securityProperties for filter configuration
- * @return the spring filter registration bean for registering a denial of service protection filter in the filter chain
- */
- @Bean
- @ConditionalOnProperty(prefix = "hawkbit.server.security.dos.filter", name = "enabled", matchIfMissing = true)
- protected FilterRegistrationBean dosFilterDDI(final HawkbitSecurityProperties securityProperties) {
- final FilterRegistrationBean filterRegBean =
- dosFilter(List.of(DDI_ANT_MATCHERS),
- securityProperties.getDos().getFilter(), securityProperties.getClients());
- filterRegBean.setOrder(DOS_FILTER_ORDER);
- filterRegBean.setName("dosDDiFilter");
-
- return filterRegBean;
- }
-
- @Bean
- @Order(300)
- protected SecurityFilterChain filterChainDDI(final HttpSecurity http) throws Exception {
- final AuthenticationManager authenticationManager = setAuthenticationManager(http, ddiSecurityConfiguration);
-
- http
- .securityMatcher(DDI_ANT_MATCHERS)
- .csrf(AbstractHttpConfigurer::disable);
-
- if (securityProperties.isRequireSsl()) {
- http.requiresChannel(crmRegistry -> crmRegistry.anyRequest().requiresSecure());
- }
-
- final ControllerTenantAwareAuthenticationDetailsSource authenticationDetailsSource = new ControllerTenantAwareAuthenticationDetailsSource();
- if (ddiSecurityConfiguration.getAuthentication().getAnonymous().isEnabled()) {
- log.warn(ANONYMOUS_CONTROLLER_SECURITY_ENABLED_SHOULD_ONLY_BE_USED_FOR_DEVELOPMENT_PURPOSES);
-
- final AnonymousAuthenticationFilter anonymousFilter = new AnonymousAuthenticationFilter(
- "controllerAnonymousFilter", "anonymous",
- List.of(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS)));
- anonymousFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
- http
- .securityContext(AbstractHttpConfigurer::disable)
- .anonymous(configurer -> configurer.authenticationFilter(anonymousFilter));
- } else {
- final HttpControllerPreAuthenticatedSecurityHeaderFilter securityHeaderFilter = new HttpControllerPreAuthenticatedSecurityHeaderFilter(
- ddiSecurityConfiguration.getRp().getCnHeader(),
- ddiSecurityConfiguration.getRp().getSslIssuerHashHeader(), tenantConfigurationManagement,
- tenantAware, systemSecurityContext);
- securityHeaderFilter.setAuthenticationManager(authenticationManager);
- securityHeaderFilter.setCheckForPrincipalChanges(true);
- securityHeaderFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
-
- final HttpControllerPreAuthenticateSecurityTokenFilter securityTokenFilter = new HttpControllerPreAuthenticateSecurityTokenFilter(
- tenantConfigurationManagement, tenantAware, controllerManagement, systemSecurityContext);
- securityTokenFilter.setAuthenticationManager(authenticationManager);
- securityTokenFilter.setCheckForPrincipalChanges(true);
- securityTokenFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
-
- final HttpControllerPreAuthenticatedGatewaySecurityTokenFilter gatewaySecurityTokenFilter = new HttpControllerPreAuthenticatedGatewaySecurityTokenFilter(
- tenantConfigurationManagement, tenantAware, systemSecurityContext);
- gatewaySecurityTokenFilter.setAuthenticationManager(authenticationManager);
- gatewaySecurityTokenFilter.setCheckForPrincipalChanges(true);
- gatewaySecurityTokenFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
-
- http
- .authorizeHttpRequests(amrmRegistry ->
- amrmRegistry.anyRequest().authenticated())
- .anonymous(AbstractHttpConfigurer::disable)
- .addFilter(securityHeaderFilter)
- .addFilter(securityTokenFilter)
- .addFilter(gatewaySecurityTokenFilter)
- .exceptionHandling(configurer -> configurer.authenticationEntryPoint(
- (request, response, authException) ->
- response.setStatus(HttpStatus.UNAUTHORIZED.value())))
- .sessionManagement(configurer -> configurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
- }
-
- MdcHandler.Filter.addMdcFilter(http);
-
- return http.build();
- }
- }
-
- /**
- * Security configuration for the hawkBit server DDI download interface.
- */
- @Configuration
- @ConditionalOnClass(DdiApiConfiguration.class)
- static class ControllerDownloadSecurityConfigurationAdapter {
-
- private static final String DDI_DL_ANT_MATCHER = DdiRestConstants.BASE_V1_REQUEST_MAPPING
- + "/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/*";
-
- private final ControllerManagement controllerManagement;
- private final TenantConfigurationManagement tenantConfigurationManagement;
- private final TenantAware tenantAware;
- private final DdiSecurityProperties ddiSecurityConfiguration;
- private final HawkbitSecurityProperties securityProperties;
- private final SystemSecurityContext systemSecurityContext;
-
- @Autowired
- ControllerDownloadSecurityConfigurationAdapter(final ControllerManagement controllerManagement,
- final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware,
- final DdiSecurityProperties ddiSecurityConfiguration,
- final HawkbitSecurityProperties securityProperties, final SystemSecurityContext systemSecurityContext) {
- this.controllerManagement = controllerManagement;
- this.tenantConfigurationManagement = tenantConfigurationManagement;
- this.tenantAware = tenantAware;
- this.ddiSecurityConfiguration = ddiSecurityConfiguration;
- this.securityProperties = securityProperties;
- this.systemSecurityContext = systemSecurityContext;
- }
-
- /**
- * Filter to protect the hawkBit server DDI download interface against too many requests.
- *
- * @param securityProperties for filter configuration
- * @return the spring filter registration bean for registering a denial of service protection filter in the filter chain
- */
- @Bean
- @ConditionalOnProperty(prefix = "hawkbit.server.security.dos.filter", name = "enabled", matchIfMissing = true)
- public FilterRegistrationBean dosFilterDDIDL(final HawkbitSecurityProperties securityProperties) {
- final FilterRegistrationBean filterRegBean = dosFilter(List.of(DDI_DL_ANT_MATCHER),
- securityProperties.getDos().getFilter(), securityProperties.getClients());
- filterRegBean.setOrder(DOS_FILTER_ORDER);
- filterRegBean.setName("dosDDiDlFilter");
-
- return filterRegBean;
- }
-
- @Bean
- @Order(301)
- protected SecurityFilterChain filterChainDDIDL(final HttpSecurity http) throws Exception {
- final AuthenticationManager authenticationManager = setAuthenticationManager(http, ddiSecurityConfiguration);
-
- http
- .securityMatcher(DDI_DL_ANT_MATCHER)
- .csrf(AbstractHttpConfigurer::disable);
-
- if (securityProperties.isRequireSsl()) {
- http.requiresChannel(crmRegistry -> crmRegistry.anyRequest().requiresSecure());
- }
-
- final ControllerTenantAwareAuthenticationDetailsSource authenticationDetailsSource = new ControllerTenantAwareAuthenticationDetailsSource();
-
- if (ddiSecurityConfiguration.getAuthentication().getAnonymous().isEnabled()) {
- log.warn(ANONYMOUS_CONTROLLER_SECURITY_ENABLED_SHOULD_ONLY_BE_USED_FOR_DEVELOPMENT_PURPOSES);
-
- final AnonymousAuthenticationFilter anonymousFilter = new AnonymousAuthenticationFilter(
- "controllerAnonymousFilter", "anonymous",
- List.of(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS)));
- anonymousFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
- http
- .securityContext(AbstractHttpConfigurer::disable)
- .anonymous(configurer -> configurer.authenticationFilter(anonymousFilter));
- } else {
- final HttpControllerPreAuthenticatedSecurityHeaderFilter securityHeaderFilter = new HttpControllerPreAuthenticatedSecurityHeaderFilter(
- ddiSecurityConfiguration.getRp().getCnHeader(),
- ddiSecurityConfiguration.getRp().getSslIssuerHashHeader(), tenantConfigurationManagement,
- tenantAware, systemSecurityContext);
- securityHeaderFilter.setAuthenticationManager(authenticationManager);
- securityHeaderFilter.setCheckForPrincipalChanges(true);
- securityHeaderFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
-
- final HttpControllerPreAuthenticateSecurityTokenFilter securityTokenFilter = new HttpControllerPreAuthenticateSecurityTokenFilter(
- tenantConfigurationManagement, tenantAware, controllerManagement, systemSecurityContext);
- securityTokenFilter.setAuthenticationManager(authenticationManager);
- securityTokenFilter.setCheckForPrincipalChanges(true);
- securityTokenFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
-
- final HttpControllerPreAuthenticatedGatewaySecurityTokenFilter gatewaySecurityTokenFilter = new HttpControllerPreAuthenticatedGatewaySecurityTokenFilter(
- tenantConfigurationManagement, tenantAware, systemSecurityContext);
- gatewaySecurityTokenFilter.setAuthenticationManager(authenticationManager);
- gatewaySecurityTokenFilter.setCheckForPrincipalChanges(true);
- gatewaySecurityTokenFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
-
- final HttpControllerPreAuthenticateAnonymousDownloadFilter controllerAnonymousDownloadFilter = new HttpControllerPreAuthenticateAnonymousDownloadFilter(
- tenantConfigurationManagement, tenantAware, systemSecurityContext);
- controllerAnonymousDownloadFilter.setAuthenticationManager(authenticationManager);
- controllerAnonymousDownloadFilter.setCheckForPrincipalChanges(true);
- controllerAnonymousDownloadFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
-
- http
- .authorizeHttpRequests(amrmRegistry -> amrmRegistry.anyRequest().authenticated())
- .anonymous(AbstractHttpConfigurer::disable)
- .addFilter(securityHeaderFilter)
- .addFilter(securityTokenFilter)
- .addFilter(gatewaySecurityTokenFilter)
- .addFilter(controllerAnonymousDownloadFilter)
- .exceptionHandling(configurer -> configurer.authenticationEntryPoint(
- (request, response, authException) -> response.setStatus(HttpStatus.UNAUTHORIZED.value())))
- .sessionManagement(configurer -> configurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
- }
-
- MdcHandler.Filter.addMdcFilter(http);
-
- return http.build();
- }
- }
-
- /**
- * Security configuration for the REST management API.
- */
- @Configuration
- @EnableWebSecurity
- @ConditionalOnClass(MgmtApiConfiguration.class)
- public static class RestSecurityConfigurationAdapter {
-
- private final HawkbitSecurityProperties securityProperties;
-
- public RestSecurityConfigurationAdapter(final HawkbitSecurityProperties securityProperties) {
- this.securityProperties = securityProperties;
- }
-
- /**
- * Filter to protect the hawkBit server Management interface against to
- * many requests.
- *
- * @return the spring filter registration bean for registering a denial of service protection filter in the filter chain
- */
- @Bean
- @ConditionalOnProperty(prefix = "hawkbit.server.security.dos.filter", name = "enabled", matchIfMissing = true)
- public FilterRegistrationBean dosFilterREST() {
- final FilterRegistrationBean filterRegBean = dosFilter(null,
- securityProperties.getDos().getFilter(), securityProperties.getClients());
- filterRegBean.setUrlPatterns(List.of(
- MgmtRestConstants.BASE_REST_MAPPING + "/*",
- MgmtRestConstants.BASE_SYSTEM_MAPPING + "/admin/*"));
- filterRegBean.setOrder(DOS_FILTER_ORDER);
- filterRegBean.setName("dosMgmtFilter");
-
- return filterRegBean;
- }
-
- @Bean
- @Order(350)
- SecurityFilterChain filterChainREST(
- final HttpSecurity http,
- @Autowired(required = false)
- @Qualifier("hawkbitOAuth2ResourceServerCustomizer") final Customizer> oauth2ResourceServerCustomizer,
- // called just before build of the SecurityFilterChain.
- // could be used for instance to set authentication provider
- // Note: implementation of the customizer shall always take in account what is the already set by the
- // hawkBit
- @Autowired(required = false)
- @Qualifier("hawkbitHttpSecurityCustomizer") final Customizer httpSecurityCustomizer,
- final SystemManagement systemManagement,
- final SystemSecurityContext systemSecurityContext) throws Exception {
- http
- .securityMatcher(MgmtRestConstants.BASE_REST_MAPPING + "/**", MgmtRestConstants.BASE_SYSTEM_MAPPING + "/admin/**")
- .authorizeHttpRequests(amrmRegistry ->
- amrmRegistry
- .requestMatchers(MgmtRestConstants.BASE_SYSTEM_MAPPING + "/admin/**")
- .hasAnyAuthority(SpPermission.SYSTEM_ADMIN)
- .anyRequest()
- .authenticated())
- .anonymous(AbstractHttpConfigurer::disable)
- .csrf(AbstractHttpConfigurer::disable)
- .requestCache(AbstractHttpConfigurer::disable)
- .exceptionHandling(Customizer.withDefaults())
- .sessionManagement(configurer -> configurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
- .addFilterAfter(
- // Servlet filter to create metadata after successful authentication over RESTful.
- (request, response, chain) -> {
- final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
- if (authentication != null && authentication.isAuthenticated()) {
- systemSecurityContext.runAsSystem(systemManagement::getTenantMetadata);
- }
- chain.doFilter(request, response);
- },
- SessionManagementFilter.class);
-
- if (securityProperties.getCors().isEnabled()) {
- http.cors(configurer -> configurer.configurationSource(corsConfigurationSource()));
- }
-
- if (securityProperties.isRequireSsl()) {
- http.requiresChannel(crmRegistry -> crmRegistry.anyRequest().requiresSecure());
- }
-
- if (oauth2ResourceServerCustomizer != null) {
- http.oauth2ResourceServer(oauth2ResourceServerCustomizer);
- }
- if (oauth2ResourceServerCustomizer == null || securityProperties.isAllowHttpBasicOnOAuthEnabled()) {
- http.httpBasic(configurer -> {
- final BasicAuthenticationEntryPoint basicAuthEntryPoint = new BasicAuthenticationEntryPoint();
- basicAuthEntryPoint.setRealmName(securityProperties.getBasicRealm());
- configurer.authenticationEntryPoint(basicAuthEntryPoint);
- });
- }
-
- if (httpSecurityCustomizer != null) {
- httpSecurityCustomizer.customize(http);
- }
-
- MdcHandler.Filter.addMdcFilter(http);
-
- return http.build();
- }
-
- private CorsConfigurationSource corsConfigurationSource() {
- final CorsConfiguration corsConfiguration = new CorsConfiguration();
-
- corsConfiguration.setAllowedOrigins(securityProperties.getCors().getAllowedOrigins());
- corsConfiguration.setAllowCredentials(true);
- corsConfiguration.setAllowedHeaders(securityProperties.getCors().getAllowedHeaders());
- corsConfiguration.setAllowedMethods(securityProperties.getCors().getAllowedMethods());
- corsConfiguration.setExposedHeaders(securityProperties.getCors().getExposedHeaders());
- return request -> corsConfiguration;
- }
- }
-
- private static class IgnorePathsStrictHttpFirewall extends StrictHttpFirewall {
-
- private final Collection pathsToIgnore;
-
- public IgnorePathsStrictHttpFirewall(final Collection pathsToIgnore) {
- super();
- this.pathsToIgnore = pathsToIgnore;
- }
-
- @Override
- public FirewalledRequest getFirewalledRequest(final HttpServletRequest request) {
- if (pathsToIgnore != null && pathsToIgnore.contains(request.getRequestURI())) {
- return new FirewalledRequest(request) {
-
- @Override
- public void reset() {
- // nothing to do
- }
- };
- }
- return super.getFirewalledRequest(request);
- }
- }
-}
diff --git a/hawkbit-ddi/hawkbit-ddi-resource/pom.xml b/hawkbit-ddi/hawkbit-ddi-resource/pom.xml
index 83298d8f3..38e65cb9c 100644
--- a/hawkbit-ddi/hawkbit-ddi-resource/pom.xml
+++ b/hawkbit-ddi/hawkbit-ddi-resource/pom.xml
@@ -80,12 +80,6 @@
spring-security-config
test
-
- org.eclipse.hawkbit
- hawkbit-http-security
- ${project.version}
- test
-
org.springframework.boot
spring-boot-starter-json
diff --git a/hawkbit-ddi/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DosFilterTest.java b/hawkbit-ddi/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DosFilterTest.java
index de3d89f26..3da6f9f0a 100644
--- a/hawkbit-ddi/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DosFilterTest.java
+++ b/hawkbit-ddi/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DosFilterTest.java
@@ -23,7 +23,7 @@ import io.qameta.allure.Story;
import org.eclipse.hawkbit.repository.model.Action;
import org.eclipse.hawkbit.repository.model.DistributionSet;
import org.eclipse.hawkbit.repository.model.Target;
-import org.eclipse.hawkbit.security.DosFilter;
+import org.eclipse.hawkbit.rest.security.DosFilter;
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
import org.junit.jupiter.api.Test;
import org.springframework.http.HttpStatus;
diff --git a/hawkbit-ddi/hawkbit-ddi-server/src/main/java/org/eclipse/hawkbit/app/ddi/DDIStart.java b/hawkbit-ddi/hawkbit-ddi-server/src/main/java/org/eclipse/hawkbit/app/ddi/DDIStart.java
index 6f46b5471..029e45848 100644
--- a/hawkbit-ddi/hawkbit-ddi-server/src/main/java/org/eclipse/hawkbit/app/ddi/DDIStart.java
+++ b/hawkbit-ddi/hawkbit-ddi-server/src/main/java/org/eclipse/hawkbit/app/ddi/DDIStart.java
@@ -9,7 +9,6 @@
*/
package org.eclipse.hawkbit.app.ddi;
-import org.eclipse.hawkbit.autoconfigure.security.EnableHawkbitManagedSecurityConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
@@ -24,7 +23,6 @@ import org.springframework.web.servlet.view.RedirectView;
* The minimal configuration for the stand alone hawkBit DDI server.
*/
@SpringBootApplication(scanBasePackages = "org.eclipse.hawkbit")
-@EnableHawkbitManagedSecurityConfiguration
public class DDIStart {
/**
diff --git a/hawkbit-ddi/hawkbit-ddi-starter/pom.xml b/hawkbit-ddi/hawkbit-ddi-starter/pom.xml
index 4b820fa92..d8f002f65 100644
--- a/hawkbit-ddi/hawkbit-ddi-starter/pom.xml
+++ b/hawkbit-ddi/hawkbit-ddi-starter/pom.xml
@@ -56,11 +56,6 @@
hawkbit-security-integration
${project.version}
-
- org.eclipse.hawkbit
- hawkbit-http-security
- ${project.version}
-
org.eclipse.hawkbit
hawkbit-repository-jpa
diff --git a/hawkbit-ddi/hawkbit-ddi-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/ddi/ControllerDownloadSecurityConfiguration.java b/hawkbit-ddi/hawkbit-ddi-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/ddi/ControllerDownloadSecurityConfiguration.java
new file mode 100644
index 000000000..5c0be056e
--- /dev/null
+++ b/hawkbit-ddi/hawkbit-ddi-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/ddi/ControllerDownloadSecurityConfiguration.java
@@ -0,0 +1,164 @@
+/**
+ * Copyright (c) 2024 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.autoconfigure.ddi;
+
+import java.util.List;
+
+import lombok.extern.slf4j.Slf4j;
+import org.eclipse.hawkbit.autoconfigure.ddi.security.ControllerTenantAwareAuthenticationDetailsSource;
+import org.eclipse.hawkbit.autoconfigure.ddi.security.HttpControllerPreAuthenticateAnonymousDownloadFilter;
+import org.eclipse.hawkbit.autoconfigure.ddi.security.HttpControllerPreAuthenticateSecurityTokenFilter;
+import org.eclipse.hawkbit.autoconfigure.ddi.security.HttpControllerPreAuthenticatedGatewaySecurityTokenFilter;
+import org.eclipse.hawkbit.autoconfigure.ddi.security.HttpControllerPreAuthenticatedSecurityHeaderFilter;
+import org.eclipse.hawkbit.ddi.rest.api.DdiRestConstants;
+import org.eclipse.hawkbit.im.authentication.SpPermission;
+import org.eclipse.hawkbit.repository.ControllerManagement;
+import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
+import org.eclipse.hawkbit.rest.SecurityManagedConfiguration;
+import org.eclipse.hawkbit.rest.security.DosFilter;
+import org.eclipse.hawkbit.security.DdiSecurityProperties;
+import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
+import org.eclipse.hawkbit.security.MdcHandler;
+import org.eclipse.hawkbit.security.SystemSecurityContext;
+import org.eclipse.hawkbit.tenancy.TenantAware;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+import org.springframework.http.HttpStatus;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.web.SecurityFilterChain;
+import org.springframework.security.web.authentication.AnonymousAuthenticationFilter;
+
+/**
+ * Security configuration for the hawkBit server DDI download interface.
+ */
+@Slf4j
+@Configuration
+class ControllerDownloadSecurityConfiguration {
+
+ private static final String DDI_DL_ANT_MATCHER = DdiRestConstants.BASE_V1_REQUEST_MAPPING +
+ "/{controllerId}/softwaremodules/{softwareModuleId}/artifacts/*";
+
+ private final ControllerManagement controllerManagement;
+ private final TenantConfigurationManagement tenantConfigurationManagement;
+ private final TenantAware tenantAware;
+ private final DdiSecurityProperties ddiSecurityConfiguration;
+ private final HawkbitSecurityProperties securityProperties;
+ private final SystemSecurityContext systemSecurityContext;
+
+ @Autowired
+ ControllerDownloadSecurityConfiguration(final ControllerManagement controllerManagement,
+ final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware,
+ final DdiSecurityProperties ddiSecurityConfiguration,
+ final HawkbitSecurityProperties securityProperties, final SystemSecurityContext systemSecurityContext) {
+ this.controllerManagement = controllerManagement;
+ this.tenantConfigurationManagement = tenantConfigurationManagement;
+ this.tenantAware = tenantAware;
+ this.ddiSecurityConfiguration = ddiSecurityConfiguration;
+ this.securityProperties = securityProperties;
+ this.systemSecurityContext = systemSecurityContext;
+ }
+
+ /**
+ * Filter to protect the hawkBit server DDI download interface against too many requests.
+ *
+ * @param securityProperties for filter configuration
+ * @return the spring filter registration bean for registering a denial of service protection filter in the filter chain
+ */
+ @Bean
+ @ConditionalOnProperty(prefix = "hawkbit.server.security.dos.filter", name = "enabled", matchIfMissing = true)
+ public FilterRegistrationBean dosFilterDDIDL(final HawkbitSecurityProperties securityProperties) {
+ final FilterRegistrationBean filterRegBean = SecurityManagedConfiguration.dosFilter(List.of(DDI_DL_ANT_MATCHER),
+ securityProperties.getDos().getFilter(), securityProperties.getClients());
+ filterRegBean.setOrder(SecurityManagedConfiguration.DOS_FILTER_ORDER);
+ filterRegBean.setName("dosDDiDlFilter");
+
+ return filterRegBean;
+ }
+
+ @Bean
+ @Order(301)
+ protected SecurityFilterChain filterChainDDIDL(final HttpSecurity http) throws Exception {
+ final AuthenticationManager authenticationManager = ControllerSecurityConfiguration.setAuthenticationManager(
+ http, ddiSecurityConfiguration);
+
+ http
+ .securityMatcher(DDI_DL_ANT_MATCHER)
+ .csrf(AbstractHttpConfigurer::disable);
+
+ if (securityProperties.isRequireSsl()) {
+ http.requiresChannel(crmRegistry -> crmRegistry.anyRequest().requiresSecure());
+ }
+
+ final ControllerTenantAwareAuthenticationDetailsSource authenticationDetailsSource = new ControllerTenantAwareAuthenticationDetailsSource();
+
+ if (ddiSecurityConfiguration.getAuthentication().getAnonymous().isEnabled()) {
+ log.warn(
+ SecurityManagedConfiguration.ANONYMOUS_CONTROLLER_SECURITY_ENABLED_SHOULD_ONLY_BE_USED_FOR_DEVELOPMENT_PURPOSES);
+
+ final AnonymousAuthenticationFilter anonymousFilter = new AnonymousAuthenticationFilter(
+ "controllerAnonymousFilter", "anonymous",
+ List.of(new SimpleGrantedAuthority(SpPermission.SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS)));
+ anonymousFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
+ http
+ .securityContext(AbstractHttpConfigurer::disable)
+ .anonymous(configurer -> configurer.authenticationFilter(anonymousFilter));
+ } else {
+ final HttpControllerPreAuthenticatedSecurityHeaderFilter securityHeaderFilter = new HttpControllerPreAuthenticatedSecurityHeaderFilter(
+ ddiSecurityConfiguration.getRp().getCnHeader(),
+ ddiSecurityConfiguration.getRp().getSslIssuerHashHeader(), tenantConfigurationManagement,
+ tenantAware, systemSecurityContext);
+ securityHeaderFilter.setAuthenticationManager(authenticationManager);
+ securityHeaderFilter.setCheckForPrincipalChanges(true);
+ securityHeaderFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
+
+ final HttpControllerPreAuthenticateSecurityTokenFilter securityTokenFilter = new HttpControllerPreAuthenticateSecurityTokenFilter(
+ tenantConfigurationManagement, tenantAware, controllerManagement, systemSecurityContext);
+ securityTokenFilter.setAuthenticationManager(authenticationManager);
+ securityTokenFilter.setCheckForPrincipalChanges(true);
+ securityTokenFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
+
+ final HttpControllerPreAuthenticatedGatewaySecurityTokenFilter gatewaySecurityTokenFilter = new HttpControllerPreAuthenticatedGatewaySecurityTokenFilter(
+ tenantConfigurationManagement, tenantAware, systemSecurityContext);
+ gatewaySecurityTokenFilter.setAuthenticationManager(authenticationManager);
+ gatewaySecurityTokenFilter.setCheckForPrincipalChanges(true);
+ gatewaySecurityTokenFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
+
+ final HttpControllerPreAuthenticateAnonymousDownloadFilter controllerAnonymousDownloadFilter = new HttpControllerPreAuthenticateAnonymousDownloadFilter(
+ tenantConfigurationManagement, tenantAware, systemSecurityContext);
+ controllerAnonymousDownloadFilter.setAuthenticationManager(authenticationManager);
+ controllerAnonymousDownloadFilter.setCheckForPrincipalChanges(true);
+ controllerAnonymousDownloadFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
+
+ http
+ .authorizeHttpRequests(amrmRegistry -> amrmRegistry.anyRequest().authenticated())
+ .anonymous(AbstractHttpConfigurer::disable)
+ .addFilter(securityHeaderFilter)
+ .addFilter(securityTokenFilter)
+ .addFilter(gatewaySecurityTokenFilter)
+ .addFilter(controllerAnonymousDownloadFilter)
+ .exceptionHandling(configurer -> configurer.authenticationEntryPoint(
+ (request, response, authException) -> response.setStatus(HttpStatus.UNAUTHORIZED.value())))
+ .sessionManagement(configurer -> configurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
+ }
+
+ MdcHandler.Filter.addMdcFilter(http);
+
+ return http.build();
+ }
+}
\ No newline at end of file
diff --git a/hawkbit-ddi/hawkbit-ddi-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/ddi/ControllerSecurityConfiguration.java b/hawkbit-ddi/hawkbit-ddi-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/ddi/ControllerSecurityConfiguration.java
new file mode 100644
index 000000000..6e8ba5c45
--- /dev/null
+++ b/hawkbit-ddi/hawkbit-ddi-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/ddi/ControllerSecurityConfiguration.java
@@ -0,0 +1,178 @@
+/**
+ * Copyright (c) 2024 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.autoconfigure.ddi;
+
+import java.util.List;
+
+import lombok.extern.slf4j.Slf4j;
+import org.eclipse.hawkbit.autoconfigure.ddi.security.ControllerTenantAwareAuthenticationDetailsSource;
+import org.eclipse.hawkbit.autoconfigure.ddi.security.HttpControllerPreAuthenticateSecurityTokenFilter;
+import org.eclipse.hawkbit.autoconfigure.ddi.security.HttpControllerPreAuthenticatedGatewaySecurityTokenFilter;
+import org.eclipse.hawkbit.autoconfigure.ddi.security.HttpControllerPreAuthenticatedSecurityHeaderFilter;
+import org.eclipse.hawkbit.ddi.rest.api.DdiRestConstants;
+import org.eclipse.hawkbit.im.authentication.SpPermission;
+import org.eclipse.hawkbit.repository.ControllerManagement;
+import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
+import org.eclipse.hawkbit.rest.SecurityManagedConfiguration;
+import org.eclipse.hawkbit.rest.security.DosFilter;
+import org.eclipse.hawkbit.security.DdiSecurityProperties;
+import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
+import org.eclipse.hawkbit.security.MdcHandler;
+import org.eclipse.hawkbit.security.PreAuthTokenSourceTrustAuthenticationProvider;
+import org.eclipse.hawkbit.security.SystemSecurityContext;
+import org.eclipse.hawkbit.tenancy.TenantAware;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+import org.springframework.http.HttpStatus;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.core.authority.SimpleGrantedAuthority;
+import org.springframework.security.web.SecurityFilterChain;
+import org.springframework.security.web.authentication.AnonymousAuthenticationFilter;
+
+/**
+ * Security configuration for the hawkBit server DDI interface.
+ */
+@Slf4j
+@Configuration
+@EnableWebSecurity
+class ControllerSecurityConfiguration {
+
+ private static final String[] DDI_ANT_MATCHERS = {
+ DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}",
+ DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/confirmationBase/**",
+ DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/deploymentBase/**",
+ DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/installedBase/**",
+ DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/cancelAction/**",
+ DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/configData",
+ DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/softwaremodules/{softwareModuleId}/artifacts" };
+
+ private final ControllerManagement controllerManagement;
+ private final TenantConfigurationManagement tenantConfigurationManagement;
+ private final TenantAware tenantAware;
+ private final DdiSecurityProperties ddiSecurityConfiguration;
+ private final HawkbitSecurityProperties securityProperties;
+ private final SystemSecurityContext systemSecurityContext;
+
+ @Autowired
+ ControllerSecurityConfiguration(final ControllerManagement controllerManagement,
+ final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware,
+ final DdiSecurityProperties ddiSecurityConfiguration,
+ final HawkbitSecurityProperties securityProperties, final SystemSecurityContext systemSecurityContext) {
+ this.controllerManagement = controllerManagement;
+ this.tenantConfigurationManagement = tenantConfigurationManagement;
+ this.tenantAware = tenantAware;
+ this.ddiSecurityConfiguration = ddiSecurityConfiguration;
+ this.securityProperties = securityProperties;
+ this.systemSecurityContext = systemSecurityContext;
+ }
+
+ /**
+ * Filter to protect the hawkBit server DDI interface against too many requests.
+ *
+ * @param securityProperties for filter configuration
+ * @return the spring filter registration bean for registering a denial of service protection filter in the filter chain
+ */
+ @Bean
+ @ConditionalOnProperty(prefix = "hawkbit.server.security.dos.filter", name = "enabled", matchIfMissing = true)
+ protected FilterRegistrationBean dosFilterDDI(final HawkbitSecurityProperties securityProperties) {
+ final FilterRegistrationBean filterRegBean =
+ SecurityManagedConfiguration.dosFilter(List.of(DDI_ANT_MATCHERS),
+ securityProperties.getDos().getFilter(), securityProperties.getClients());
+ filterRegBean.setOrder(SecurityManagedConfiguration.DOS_FILTER_ORDER);
+ filterRegBean.setName("dosDDiFilter");
+
+ return filterRegBean;
+ }
+
+ @Bean
+ @Order(300)
+ protected SecurityFilterChain filterChainDDI(final HttpSecurity http) throws Exception {
+ final AuthenticationManager authenticationManager = setAuthenticationManager(http, ddiSecurityConfiguration);
+
+ http
+ .securityMatcher(DDI_ANT_MATCHERS)
+ .csrf(AbstractHttpConfigurer::disable);
+
+ if (securityProperties.isRequireSsl()) {
+ http.requiresChannel(crmRegistry -> crmRegistry.anyRequest().requiresSecure());
+ }
+
+ final ControllerTenantAwareAuthenticationDetailsSource authenticationDetailsSource = new ControllerTenantAwareAuthenticationDetailsSource();
+ if (ddiSecurityConfiguration.getAuthentication().getAnonymous().isEnabled()) {
+ log.warn(SecurityManagedConfiguration.ANONYMOUS_CONTROLLER_SECURITY_ENABLED_SHOULD_ONLY_BE_USED_FOR_DEVELOPMENT_PURPOSES);
+
+ final AnonymousAuthenticationFilter anonymousFilter = new AnonymousAuthenticationFilter(
+ "controllerAnonymousFilter", "anonymous",
+ List.of(new SimpleGrantedAuthority(SpPermission.SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS)));
+ anonymousFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
+ http
+ .securityContext(AbstractHttpConfigurer::disable)
+ .anonymous(configurer -> configurer.authenticationFilter(anonymousFilter));
+ } else {
+ final HttpControllerPreAuthenticatedSecurityHeaderFilter securityHeaderFilter = new HttpControllerPreAuthenticatedSecurityHeaderFilter(
+ ddiSecurityConfiguration.getRp().getCnHeader(),
+ ddiSecurityConfiguration.getRp().getSslIssuerHashHeader(), tenantConfigurationManagement,
+ tenantAware, systemSecurityContext);
+ securityHeaderFilter.setAuthenticationManager(authenticationManager);
+ securityHeaderFilter.setCheckForPrincipalChanges(true);
+ securityHeaderFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
+
+ final HttpControllerPreAuthenticateSecurityTokenFilter securityTokenFilter = new HttpControllerPreAuthenticateSecurityTokenFilter(
+ tenantConfigurationManagement, tenantAware, controllerManagement, systemSecurityContext);
+ securityTokenFilter.setAuthenticationManager(authenticationManager);
+ securityTokenFilter.setCheckForPrincipalChanges(true);
+ securityTokenFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
+
+ final HttpControllerPreAuthenticatedGatewaySecurityTokenFilter gatewaySecurityTokenFilter = new HttpControllerPreAuthenticatedGatewaySecurityTokenFilter(
+ tenantConfigurationManagement, tenantAware, systemSecurityContext);
+ gatewaySecurityTokenFilter.setAuthenticationManager(authenticationManager);
+ gatewaySecurityTokenFilter.setCheckForPrincipalChanges(true);
+ gatewaySecurityTokenFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
+
+ http
+ .authorizeHttpRequests(amrmRegistry ->
+ amrmRegistry.anyRequest().authenticated())
+ .anonymous(AbstractHttpConfigurer::disable)
+ .addFilter(securityHeaderFilter)
+ .addFilter(securityTokenFilter)
+ .addFilter(gatewaySecurityTokenFilter)
+ .exceptionHandling(configurer -> configurer.authenticationEntryPoint(
+ (request, response, authException) ->
+ response.setStatus(HttpStatus.UNAUTHORIZED.value())))
+ .sessionManagement(configurer -> configurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
+ }
+
+ MdcHandler.Filter.addMdcFilter(http);
+
+ return http.build();
+ }
+
+ static AuthenticationManager setAuthenticationManager(final HttpSecurity http, final DdiSecurityProperties ddiSecurityConfiguration)
+ throws Exception {
+ // configure authentication manager
+ final AuthenticationManager authenticationManager =
+ http
+ .getSharedObject(AuthenticationManagerBuilder.class)
+ .authenticationProvider(
+ new PreAuthTokenSourceTrustAuthenticationProvider(ddiSecurityConfiguration.getRp().getTrustedIPs()))
+ .build();
+ http.authenticationManager(authenticationManager);
+ return authenticationManager;
+ }
+}
diff --git a/hawkbit-ddi/hawkbit-ddi-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/ddi/DDiApiAutoConfiguration.java b/hawkbit-ddi/hawkbit-ddi-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/ddi/DdiApiAutoConfiguration.java
similarity index 95%
rename from hawkbit-ddi/hawkbit-ddi-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/ddi/DDiApiAutoConfiguration.java
rename to hawkbit-ddi/hawkbit-ddi-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/ddi/DdiApiAutoConfiguration.java
index e8780a802..5cef6428b 100644
--- a/hawkbit-ddi/hawkbit-ddi-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/ddi/DDiApiAutoConfiguration.java
+++ b/hawkbit-ddi/hawkbit-ddi-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/ddi/DdiApiAutoConfiguration.java
@@ -20,6 +20,6 @@ import org.springframework.context.annotation.Import;
@Configuration
@ConditionalOnClass(DdiApiConfiguration.class)
@Import(DdiApiConfiguration.class)
-public class DDiApiAutoConfiguration {
+public class DdiApiAutoConfiguration {
}
diff --git a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/AbstractHttpControllerAuthenticationFilter.java b/hawkbit-ddi/hawkbit-ddi-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/ddi/security/AbstractHttpControllerAuthenticationFilter.java
similarity index 97%
rename from hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/AbstractHttpControllerAuthenticationFilter.java
rename to hawkbit-ddi/hawkbit-ddi-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/ddi/security/AbstractHttpControllerAuthenticationFilter.java
index 6f344fca3..52d36963e 100644
--- a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/AbstractHttpControllerAuthenticationFilter.java
+++ b/hawkbit-ddi/hawkbit-ddi-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/ddi/security/AbstractHttpControllerAuthenticationFilter.java
@@ -7,7 +7,7 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
-package org.eclipse.hawkbit.security;
+package org.eclipse.hawkbit.autoconfigure.ddi.security;
import java.io.IOException;
import java.util.ArrayList;
@@ -23,6 +23,9 @@ import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
+import org.eclipse.hawkbit.security.DmfTenantSecurityToken;
+import org.eclipse.hawkbit.security.PreAuthenticationFilter;
+import org.eclipse.hawkbit.security.SystemSecurityContext;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.eclipse.hawkbit.util.UrlUtils;
import org.slf4j.Logger;
diff --git a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/ControllerTenantAwareAuthenticationDetailsSource.java b/hawkbit-ddi/hawkbit-ddi-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/ddi/security/ControllerTenantAwareAuthenticationDetailsSource.java
similarity index 95%
rename from hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/ControllerTenantAwareAuthenticationDetailsSource.java
rename to hawkbit-ddi/hawkbit-ddi-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/ddi/security/ControllerTenantAwareAuthenticationDetailsSource.java
index 4cbf4fa01..6dda977a3 100644
--- a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/ControllerTenantAwareAuthenticationDetailsSource.java
+++ b/hawkbit-ddi/hawkbit-ddi-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/ddi/security/ControllerTenantAwareAuthenticationDetailsSource.java
@@ -7,13 +7,14 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
-package org.eclipse.hawkbit.security;
+package org.eclipse.hawkbit.autoconfigure.ddi.security;
import java.util.Map;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
+import org.eclipse.hawkbit.security.TenantAwareWebAuthenticationDetails;
import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails;
import org.eclipse.hawkbit.util.UrlUtils;
import org.springframework.security.authentication.AuthenticationDetailsSource;
diff --git a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticateAnonymousDownloadFilter.java b/hawkbit-ddi/hawkbit-ddi-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/ddi/security/HttpControllerPreAuthenticateAnonymousDownloadFilter.java
similarity index 84%
rename from hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticateAnonymousDownloadFilter.java
rename to hawkbit-ddi/hawkbit-ddi-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/ddi/security/HttpControllerPreAuthenticateAnonymousDownloadFilter.java
index a61c104b5..9d207d0b8 100644
--- a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticateAnonymousDownloadFilter.java
+++ b/hawkbit-ddi/hawkbit-ddi-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/ddi/security/HttpControllerPreAuthenticateAnonymousDownloadFilter.java
@@ -7,11 +7,14 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
-package org.eclipse.hawkbit.security;
+package org.eclipse.hawkbit.autoconfigure.ddi.security;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
+import org.eclipse.hawkbit.security.ControllerPreAuthenticatedAnonymousDownload;
+import org.eclipse.hawkbit.security.PreAuthenticationFilter;
+import org.eclipse.hawkbit.security.SystemSecurityContext;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.slf4j.Logger;
@@ -39,8 +42,7 @@ public class HttpControllerPreAuthenticateAnonymousDownloadFilter extends Abstra
@Override
protected PreAuthenticationFilter createControllerAuthenticationFilter() {
- return new ControllerPreAuthenticatedAnonymousDownload(tenantConfigurationManagement, tenantAware,
- systemSecurityContext);
+ return new ControllerPreAuthenticatedAnonymousDownload(tenantConfigurationManagement, tenantAware, systemSecurityContext);
}
@Override
diff --git a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticateSecurityTokenFilter.java b/hawkbit-ddi/hawkbit-ddi-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/ddi/security/HttpControllerPreAuthenticateSecurityTokenFilter.java
similarity index 91%
rename from hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticateSecurityTokenFilter.java
rename to hawkbit-ddi/hawkbit-ddi-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/ddi/security/HttpControllerPreAuthenticateSecurityTokenFilter.java
index 563e148a5..16378de37 100644
--- a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticateSecurityTokenFilter.java
+++ b/hawkbit-ddi/hawkbit-ddi-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/ddi/security/HttpControllerPreAuthenticateSecurityTokenFilter.java
@@ -7,11 +7,14 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
-package org.eclipse.hawkbit.security;
+package org.eclipse.hawkbit.autoconfigure.ddi.security;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.hawkbit.repository.ControllerManagement;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
+import org.eclipse.hawkbit.security.ControllerPreAuthenticateSecurityTokenFilter;
+import org.eclipse.hawkbit.security.PreAuthenticationFilter;
+import org.eclipse.hawkbit.security.SystemSecurityContext;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.slf4j.Logger;
diff --git a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedGatewaySecurityTokenFilter.java b/hawkbit-ddi/hawkbit-ddi-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/ddi/security/HttpControllerPreAuthenticatedGatewaySecurityTokenFilter.java
similarity index 88%
rename from hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedGatewaySecurityTokenFilter.java
rename to hawkbit-ddi/hawkbit-ddi-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/ddi/security/HttpControllerPreAuthenticatedGatewaySecurityTokenFilter.java
index 23d681a58..84fb3c2a5 100644
--- a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedGatewaySecurityTokenFilter.java
+++ b/hawkbit-ddi/hawkbit-ddi-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/ddi/security/HttpControllerPreAuthenticatedGatewaySecurityTokenFilter.java
@@ -7,10 +7,13 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
-package org.eclipse.hawkbit.security;
+package org.eclipse.hawkbit.autoconfigure.ddi.security;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
+import org.eclipse.hawkbit.security.ControllerPreAuthenticatedGatewaySecurityTokenFilter;
+import org.eclipse.hawkbit.security.PreAuthenticationFilter;
+import org.eclipse.hawkbit.security.SystemSecurityContext;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.slf4j.Logger;
diff --git a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedSecurityHeaderFilter.java b/hawkbit-ddi/hawkbit-ddi-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/ddi/security/HttpControllerPreAuthenticatedSecurityHeaderFilter.java
similarity index 85%
rename from hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedSecurityHeaderFilter.java
rename to hawkbit-ddi/hawkbit-ddi-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/ddi/security/HttpControllerPreAuthenticatedSecurityHeaderFilter.java
index 541dd63cf..06184a58b 100644
--- a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedSecurityHeaderFilter.java
+++ b/hawkbit-ddi/hawkbit-ddi-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/ddi/security/HttpControllerPreAuthenticatedSecurityHeaderFilter.java
@@ -7,10 +7,13 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
-package org.eclipse.hawkbit.security;
+package org.eclipse.hawkbit.autoconfigure.ddi.security;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
+import org.eclipse.hawkbit.security.ControllerPreAuthenticatedSecurityHeaderFilter;
+import org.eclipse.hawkbit.security.PreAuthenticationFilter;
+import org.eclipse.hawkbit.security.SystemSecurityContext;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.slf4j.Logger;
@@ -25,7 +28,7 @@ public class HttpControllerPreAuthenticatedSecurityHeaderFilter extends Abstract
private final String caAuthorityNameHeader;
/**
- * Creates a new {@link ControllerPreAuthenticatedSecurityHeaderFilter}, in
+ * Creates a new {@link org.eclipse.hawkbit.security.ControllerPreAuthenticatedSecurityHeaderFilter}, in
* case the HTTP request matches the given pattern the principal is parsed
* from the HTTP request with the given URI pattern, in case the URI pattern
* does not match the current request then only the existence of the
@@ -51,7 +54,8 @@ public class HttpControllerPreAuthenticatedSecurityHeaderFilter extends Abstract
@Override
protected PreAuthenticationFilter createControllerAuthenticationFilter() {
- return new ControllerPreAuthenticatedSecurityHeaderFilter(caCommonNameHeader, caAuthorityNameHeader,
+ return new ControllerPreAuthenticatedSecurityHeaderFilter(
+ caCommonNameHeader, caAuthorityNameHeader,
tenantConfigurationManagement, tenantAware, systemSecurityContext);
}
diff --git a/hawkbit-ddi/hawkbit-ddi-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/hawkbit-ddi/hawkbit-ddi-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index 2213d66ee..772f92438 100644
--- a/hawkbit-ddi/hawkbit-ddi-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/hawkbit-ddi/hawkbit-ddi-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1 +1,4 @@
-org.eclipse.hawkbit.autoconfigure.ddi.DDiApiAutoConfiguration
+org.eclipse.hawkbit.autoconfigure.ddi.DdiApiAutoConfiguration
+org.eclipse.hawkbit.rest.SecurityManagedConfiguration
+org.eclipse.hawkbit.autoconfigure.ddi.ControllerSecurityConfiguration
+org.eclipse.hawkbit.autoconfigure.ddi.ControllerDownloadSecurityConfiguration
diff --git a/hawkbit-http-security/src/test/java/org/eclipse/hawkbit/security/PreAuthTokenSourceTrustAuthenticationProviderTest.java b/hawkbit-ddi/hawkbit-ddi-starter/src/test/java/org/eclipse/hawkbit/autoconfigure/ddi/security/PreAuthTokenSourceTrustAuthenticationProviderTest.java
similarity index 94%
rename from hawkbit-http-security/src/test/java/org/eclipse/hawkbit/security/PreAuthTokenSourceTrustAuthenticationProviderTest.java
rename to hawkbit-ddi/hawkbit-ddi-starter/src/test/java/org/eclipse/hawkbit/autoconfigure/ddi/security/PreAuthTokenSourceTrustAuthenticationProviderTest.java
index ff2cd1cb8..45e08f714 100644
--- a/hawkbit-http-security/src/test/java/org/eclipse/hawkbit/security/PreAuthTokenSourceTrustAuthenticationProviderTest.java
+++ b/hawkbit-ddi/hawkbit-ddi-starter/src/test/java/org/eclipse/hawkbit/autoconfigure/ddi/security/PreAuthTokenSourceTrustAuthenticationProviderTest.java
@@ -7,7 +7,7 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
-package org.eclipse.hawkbit.security;
+package org.eclipse.hawkbit.autoconfigure.ddi.security;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@@ -18,6 +18,8 @@ import java.util.Collections;
import io.qameta.allure.Description;
import io.qameta.allure.Feature;
import io.qameta.allure.Story;
+import org.eclipse.hawkbit.security.PreAuthTokenSourceTrustAuthenticationProvider;
+import org.eclipse.hawkbit.security.TenantAwareWebAuthenticationDetails;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
@@ -34,9 +36,10 @@ public class PreAuthTokenSourceTrustAuthenticationProviderTest {
private static final String REQUEST_SOURCE_IP = "127.0.0.1";
- private final PreAuthTokenSourceTrustAuthenticationProvider underTestWithoutSourceIpCheck = new PreAuthTokenSourceTrustAuthenticationProvider();
- private final PreAuthTokenSourceTrustAuthenticationProvider underTestWithSourceIpCheck = new PreAuthTokenSourceTrustAuthenticationProvider(
- REQUEST_SOURCE_IP);
+ private final PreAuthTokenSourceTrustAuthenticationProvider underTestWithoutSourceIpCheck =
+ new PreAuthTokenSourceTrustAuthenticationProvider();
+ private final PreAuthTokenSourceTrustAuthenticationProvider underTestWithSourceIpCheck =
+ new PreAuthTokenSourceTrustAuthenticationProvider(REQUEST_SOURCE_IP);
@Mock
private TenantAwareWebAuthenticationDetails webAuthenticationDetailsMock;
diff --git a/hawkbit-dmf/hawkbit-dmf-server/src/main/java/org/eclipse/hawkbit/app/dmf/DMFStart.java b/hawkbit-dmf/hawkbit-dmf-server/src/main/java/org/eclipse/hawkbit/app/dmf/DMFStart.java
index d8621e659..c532beb4e 100644
--- a/hawkbit-dmf/hawkbit-dmf-server/src/main/java/org/eclipse/hawkbit/app/dmf/DMFStart.java
+++ b/hawkbit-dmf/hawkbit-dmf-server/src/main/java/org/eclipse/hawkbit/app/dmf/DMFStart.java
@@ -9,7 +9,6 @@
*/
package org.eclipse.hawkbit.app.dmf;
-import org.eclipse.hawkbit.autoconfigure.security.EnableHawkbitManagedSecurityConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -18,7 +17,6 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
* The minimal configuration for the stand alone hawkBit DMF server.
*/
@SpringBootApplication(scanBasePackages = "org.eclipse.hawkbit")
-@EnableHawkbitManagedSecurityConfiguration
public class DMFStart {
/**
diff --git a/hawkbit-http-security/pom.xml b/hawkbit-http-security/pom.xml
deleted file mode 100644
index 1bafe1181..000000000
--- a/hawkbit-http-security/pom.xml
+++ /dev/null
@@ -1,51 +0,0 @@
-
-
- 4.0.0
-
- hawkbit-parent
- ${revision}
- org.eclipse.hawkbit
-
- hawkbit-http-security
- hawkBit :: HTTP Security
-
-
-
-
- org.eclipse.hawkbit
- hawkbit-repository-api
- ${project.version}
-
-
- org.eclipse.hawkbit
- hawkbit-security-core
- ${project.version}
-
-
- org.eclipse.hawkbit
- hawkbit-security-integration
- ${project.version}
-
-
- jakarta.servlet
- jakarta.servlet-api
- provided
-
-
- com.github.ben-manes.caffeine
- caffeine
-
-
-
-
\ No newline at end of file
diff --git a/hawkbit-mgmt/hawkbit-mgmt-resource/pom.xml b/hawkbit-mgmt/hawkbit-mgmt-resource/pom.xml
index bbf9efed5..2325466f7 100644
--- a/hawkbit-mgmt/hawkbit-mgmt-resource/pom.xml
+++ b/hawkbit-mgmt/hawkbit-mgmt-resource/pom.xml
@@ -83,12 +83,6 @@
spring-security-config
test
-
- org.eclipse.hawkbit
- hawkbit-http-security
- ${project.version}
- test
-
org.springframework.boot
spring-boot-starter-json
diff --git a/hawkbit-mgmt/hawkbit-mgmt-server/src/main/java/org/eclipse/hawkbit/app/mgmt/MgmtServerStart.java b/hawkbit-mgmt/hawkbit-mgmt-server/src/main/java/org/eclipse/hawkbit/app/mgmt/MgmtServerStart.java
index 3c8a11e3d..58a328efb 100644
--- a/hawkbit-mgmt/hawkbit-mgmt-server/src/main/java/org/eclipse/hawkbit/app/mgmt/MgmtServerStart.java
+++ b/hawkbit-mgmt/hawkbit-mgmt-server/src/main/java/org/eclipse/hawkbit/app/mgmt/MgmtServerStart.java
@@ -9,7 +9,6 @@
*/
package org.eclipse.hawkbit.app.mgmt;
-import org.eclipse.hawkbit.autoconfigure.security.EnableHawkbitManagedSecurityConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
@@ -24,7 +23,6 @@ import org.springframework.web.servlet.view.RedirectView;
* The minimal configuration for the stand alone hawkBit server.
*/
@SpringBootApplication(scanBasePackages = "org.eclipse.hawkbit")
-@EnableHawkbitManagedSecurityConfiguration
public class MgmtServerStart {
/**
diff --git a/hawkbit-mgmt/hawkbit-mgmt-starter/pom.xml b/hawkbit-mgmt/hawkbit-mgmt-starter/pom.xml
index 642f7e001..f356b5051 100644
--- a/hawkbit-mgmt/hawkbit-mgmt-starter/pom.xml
+++ b/hawkbit-mgmt/hawkbit-mgmt-starter/pom.xml
@@ -33,11 +33,6 @@
hawkbit-security-integration
${project.version}
-
- org.eclipse.hawkbit
- hawkbit-http-security
- ${project.version}
-
org.eclipse.hawkbit
hawkbit-repository-jpa
diff --git a/hawkbit-mgmt/hawkbit-mgmt-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/mgmt/MgmtSecurityConfiguration.java b/hawkbit-mgmt/hawkbit-mgmt-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/mgmt/MgmtSecurityConfiguration.java
new file mode 100644
index 000000000..6b4787f2c
--- /dev/null
+++ b/hawkbit-mgmt/hawkbit-mgmt-starter/src/main/java/org/eclipse/hawkbit/autoconfigure/mgmt/MgmtSecurityConfiguration.java
@@ -0,0 +1,151 @@
+/**
+ * Copyright (c) 2024 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.autoconfigure.mgmt;
+
+import java.util.List;
+
+import org.eclipse.hawkbit.rest.SecurityManagedConfiguration;
+import org.eclipse.hawkbit.im.authentication.SpPermission;
+import org.eclipse.hawkbit.mgmt.rest.api.MgmtRestConstants;
+import org.eclipse.hawkbit.repository.SystemManagement;
+import org.eclipse.hawkbit.rest.security.DosFilter;
+import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
+import org.eclipse.hawkbit.security.MdcHandler;
+import org.eclipse.hawkbit.security.SystemSecurityContext;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.annotation.Order;
+import org.springframework.security.config.Customizer;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
+import org.springframework.security.config.annotation.web.configurers.oauth2.server.resource.OAuth2ResourceServerConfigurer;
+import org.springframework.security.config.http.SessionCreationPolicy;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.web.SecurityFilterChain;
+import org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint;
+import org.springframework.security.web.session.SessionManagementFilter;
+import org.springframework.web.cors.CorsConfiguration;
+import org.springframework.web.cors.CorsConfigurationSource;
+
+/**
+ * Security configuration for the REST management API.
+ */
+@Configuration
+@EnableWebSecurity
+public class MgmtSecurityConfiguration {
+
+ private final HawkbitSecurityProperties securityProperties;
+
+ public MgmtSecurityConfiguration(final HawkbitSecurityProperties securityProperties) {
+ this.securityProperties = securityProperties;
+ }
+
+ /**
+ * Filter to protect the hawkBit server Management interface against to many requests.
+ *
+ * @return the spring filter registration bean for registering a denial of service protection filter in the filter chain
+ */
+ @Bean
+ @ConditionalOnProperty(prefix = "hawkbit.server.security.dos.filter", name = "enabled", matchIfMissing = true)
+ public FilterRegistrationBean dosFilterREST() {
+ final FilterRegistrationBean filterRegBean = SecurityManagedConfiguration.dosFilter(null,
+ securityProperties.getDos().getFilter(), securityProperties.getClients());
+ filterRegBean.setUrlPatterns(List.of(
+ MgmtRestConstants.BASE_REST_MAPPING + "/*",
+ MgmtRestConstants.BASE_SYSTEM_MAPPING + "/admin/*"));
+ filterRegBean.setOrder(SecurityManagedConfiguration.DOS_FILTER_ORDER);
+ filterRegBean.setName("dosMgmtFilter");
+
+ return filterRegBean;
+ }
+
+ @Bean
+ @Order(350)
+ SecurityFilterChain filterChainREST(
+ final HttpSecurity http,
+ @Autowired(required = false)
+ @Qualifier("hawkbitOAuth2ResourceServerCustomizer") final Customizer> oauth2ResourceServerCustomizer,
+ // called just before build of the SecurityFilterChain.
+ // could be used for instance to set authentication provider
+ // Note: implementation of the customizer shall always take in account what is the already set by the
+ // hawkBit
+ @Autowired(required = false)
+ @Qualifier("hawkbitHttpSecurityCustomizer") final Customizer httpSecurityCustomizer,
+ final SystemManagement systemManagement,
+ final SystemSecurityContext systemSecurityContext) throws Exception {
+ http
+ .securityMatcher(MgmtRestConstants.BASE_REST_MAPPING + "/**", MgmtRestConstants.BASE_SYSTEM_MAPPING + "/admin/**")
+ .authorizeHttpRequests(amrmRegistry ->
+ amrmRegistry
+ .requestMatchers(MgmtRestConstants.BASE_SYSTEM_MAPPING + "/admin/**")
+ .hasAnyAuthority(SpPermission.SYSTEM_ADMIN)
+ .anyRequest()
+ .authenticated())
+ .anonymous(AbstractHttpConfigurer::disable)
+ .csrf(AbstractHttpConfigurer::disable)
+ .requestCache(AbstractHttpConfigurer::disable)
+ .exceptionHandling(Customizer.withDefaults())
+ .sessionManagement(configurer -> configurer.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
+ .addFilterAfter(
+ // Servlet filter to create metadata after successful authentication over RESTful.
+ (request, response, chain) -> {
+ final Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
+ if (authentication != null && authentication.isAuthenticated()) {
+ systemSecurityContext.runAsSystem(systemManagement::getTenantMetadata);
+ }
+ chain.doFilter(request, response);
+ },
+ SessionManagementFilter.class);
+
+ if (securityProperties.getCors().isEnabled()) {
+ http.cors(configurer -> configurer.configurationSource(corsConfigurationSource()));
+ }
+
+ if (securityProperties.isRequireSsl()) {
+ http.requiresChannel(crmRegistry -> crmRegistry.anyRequest().requiresSecure());
+ }
+
+ if (oauth2ResourceServerCustomizer != null) {
+ http.oauth2ResourceServer(oauth2ResourceServerCustomizer);
+ }
+ if (oauth2ResourceServerCustomizer == null || securityProperties.isAllowHttpBasicOnOAuthEnabled()) {
+ http.httpBasic(configurer -> {
+ final BasicAuthenticationEntryPoint basicAuthEntryPoint = new BasicAuthenticationEntryPoint();
+ basicAuthEntryPoint.setRealmName(securityProperties.getBasicRealm());
+ configurer.authenticationEntryPoint(basicAuthEntryPoint);
+ });
+ }
+
+ if (httpSecurityCustomizer != null) {
+ httpSecurityCustomizer.customize(http);
+ }
+
+ MdcHandler.Filter.addMdcFilter(http);
+
+ return http.build();
+ }
+
+ private CorsConfigurationSource corsConfigurationSource() {
+ final CorsConfiguration corsConfiguration = new CorsConfiguration();
+
+ corsConfiguration.setAllowedOrigins(securityProperties.getCors().getAllowedOrigins());
+ corsConfiguration.setAllowCredentials(true);
+ corsConfiguration.setAllowedHeaders(securityProperties.getCors().getAllowedHeaders());
+ corsConfiguration.setAllowedMethods(securityProperties.getCors().getAllowedMethods());
+ corsConfiguration.setExposedHeaders(securityProperties.getCors().getExposedHeaders());
+ return request -> corsConfiguration;
+ }
+}
diff --git a/hawkbit-mgmt/hawkbit-mgmt-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/hawkbit-mgmt/hawkbit-mgmt-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
index 702a23a39..c7d0a02bb 100644
--- a/hawkbit-mgmt/hawkbit-mgmt-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
+++ b/hawkbit-mgmt/hawkbit-mgmt-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -1 +1,3 @@
org.eclipse.hawkbit.autoconfigure.mgmt.MgmtApiAutoConfiguration
+org.eclipse.hawkbit.rest.SecurityManagedConfiguration
+org.eclipse.hawkbit.autoconfigure.mgmt.MgmtSecurityConfiguration
diff --git a/hawkbit-monolith/hawkbit-update-server/src/main/java/org/eclipse/hawkbit/app/Start.java b/hawkbit-monolith/hawkbit-update-server/src/main/java/org/eclipse/hawkbit/app/Start.java
index a93b67064..12fed2d39 100644
--- a/hawkbit-monolith/hawkbit-update-server/src/main/java/org/eclipse/hawkbit/app/Start.java
+++ b/hawkbit-monolith/hawkbit-update-server/src/main/java/org/eclipse/hawkbit/app/Start.java
@@ -9,7 +9,6 @@
*/
package org.eclipse.hawkbit.app;
-import org.eclipse.hawkbit.autoconfigure.security.EnableHawkbitManagedSecurityConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
@@ -24,7 +23,6 @@ import org.springframework.web.servlet.view.RedirectView;
* The minimal configuration for the stand alone hawkBit server.
*/
@SpringBootApplication(scanBasePackages = "org.eclipse.hawkbit")
-@EnableHawkbitManagedSecurityConfiguration
// Exception squid:S1118 - Spring boot standard behavior
@SuppressWarnings({ "squid:S1118" })
public class Start {
diff --git a/hawkbit-rest-core/pom.xml b/hawkbit-rest-core/pom.xml
index 4500c82e3..73c8b69ca 100644
--- a/hawkbit-rest-core/pom.xml
+++ b/hawkbit-rest-core/pom.xml
@@ -29,18 +29,15 @@
org.eclipse.hawkbit
- hawkbit-artifact-api
+ hawkbit-security-integration
${project.version}
- org.apache.commons
- commons-lang3
-
-
- commons-io
- commons-io
- ${commons-io.version}
+ org.eclipse.hawkbit
+ hawkbit-artifact-api
+ ${project.version}
+
org.springframework.boot
spring-boot-starter-web
@@ -61,12 +58,27 @@
org.springdoc
springdoc-openapi-starter-webmvc-ui
+
jakarta.servlet
jakarta.servlet-api
provided
+
+ org.apache.commons
+ commons-lang3
+
+
+ commons-io
+ commons-io
+ ${commons-io.version}
+
+
+ com.github.ben-manes.caffeine
+ caffeine
+
+
org.eclipse.hawkbit
diff --git a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/SecurityManagedConfiguration.java b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/SecurityManagedConfiguration.java
new file mode 100644
index 000000000..312459164
--- /dev/null
+++ b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/SecurityManagedConfiguration.java
@@ -0,0 +1,131 @@
+/**
+ * Copyright (c) 2015 Bosch Software Innovations GmbH and others
+ *
+ * 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.rest;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import jakarta.servlet.http.HttpServletRequest;
+
+import lombok.extern.slf4j.Slf4j;
+import org.eclipse.hawkbit.security.DdiSecurityProperties;
+import org.eclipse.hawkbit.rest.security.DosFilter;
+import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
+import org.eclipse.hawkbit.security.PreAuthTokenSourceTrustAuthenticationProvider;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.AdviceMode;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.core.Ordered;
+import org.springframework.core.annotation.Order;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
+import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
+import org.springframework.security.config.annotation.web.builders.HttpSecurity;
+import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
+import org.springframework.security.web.firewall.FirewalledRequest;
+import org.springframework.security.web.firewall.HttpFirewall;
+import org.springframework.security.web.firewall.StrictHttpFirewall;
+import org.springframework.util.CollectionUtils;
+
+/**
+ * All configurations related to HawkBit's authentication and authorization layer.
+ */
+@Slf4j
+@Configuration
+@EnableWebSecurity
+@EnableGlobalMethodSecurity(prePostEnabled = true, mode = AdviceMode.ASPECTJ, proxyTargetClass = true, securedEnabled = true)
+@Order(Ordered.HIGHEST_PRECEDENCE)
+@PropertySource("classpath:hawkbit-security-defaults.properties")
+public class SecurityManagedConfiguration {
+
+ public static final String ANONYMOUS_CONTROLLER_SECURITY_ENABLED_SHOULD_ONLY_BE_USED_FOR_DEVELOPMENT_PURPOSES = """
+ ******************
+ ** Anonymous controller security enabled, should only be used for development purposes **
+ ******************""";
+ public static final int DOS_FILTER_ORDER = -200;
+
+ /**
+ * Filter to protect the hawkBit server system management interface against too many requests.
+ *
+ * @param securityProperties for filter configuration
+ * @return the spring filter registration bean for registering a denial of service protection filter in the filter chain
+ */
+ @Bean
+ @ConditionalOnProperty(prefix = "hawkbit.server.security.dos.filter", name = "enabled", matchIfMissing = true)
+ public FilterRegistrationBean dosSystemFilter(final HawkbitSecurityProperties securityProperties) {
+ final FilterRegistrationBean filterRegBean = dosFilter(Collections.emptyList(),
+ securityProperties.getDos().getFilter(), securityProperties.getClients());
+ filterRegBean.setUrlPatterns(List.of("/system/*"));
+ filterRegBean.setOrder(DOS_FILTER_ORDER);
+ filterRegBean.setName("dosSystemFilter");
+
+ return filterRegBean;
+ }
+
+ /**
+ * HttpFirewall which enables to define a list of allowed host names.
+ *
+ * @return the http firewall.
+ */
+ @Bean
+ public HttpFirewall httpFirewall(final HawkbitSecurityProperties hawkbitSecurityProperties) {
+ final List allowedHostNames = hawkbitSecurityProperties.getAllowedHostNames();
+ final IgnorePathsStrictHttpFirewall firewall = new IgnorePathsStrictHttpFirewall(
+ hawkbitSecurityProperties.getHttpFirewallIgnoredPaths());
+
+ if (!CollectionUtils.isEmpty(allowedHostNames)) {
+ firewall.setAllowedHostnames(hostName -> {
+ log.debug("Firewall check host: {}, allowed: {}", hostName, allowedHostNames.contains(hostName));
+ return allowedHostNames.contains(hostName);
+ });
+ }
+ return firewall;
+ }
+
+ public static FilterRegistrationBean dosFilter(final Collection includeAntPaths,
+ final HawkbitSecurityProperties.Dos.Filter filterProperties,
+ final HawkbitSecurityProperties.Clients clientProperties) {
+ final FilterRegistrationBean filterRegBean = new FilterRegistrationBean<>();
+
+ filterRegBean.setFilter(new DosFilter(includeAntPaths, filterProperties.getMaxRead(),
+ filterProperties.getMaxWrite(), filterProperties.getWhitelist(), clientProperties.getBlacklist(),
+ clientProperties.getRemoteIpHeader()));
+
+ return filterRegBean;
+ }
+
+ private static class IgnorePathsStrictHttpFirewall extends StrictHttpFirewall {
+
+ private final Collection pathsToIgnore;
+
+ public IgnorePathsStrictHttpFirewall(final Collection pathsToIgnore) {
+ super();
+ this.pathsToIgnore = pathsToIgnore;
+ }
+
+ @Override
+ public FirewalledRequest getFirewalledRequest(final HttpServletRequest request) {
+ if (pathsToIgnore != null && pathsToIgnore.contains(request.getRequestURI())) {
+ return new FirewalledRequest(request) {
+
+ @Override
+ public void reset() {
+ // nothing to do
+ }
+ };
+ }
+ return super.getFirewalledRequest(request);
+ }
+ }
+}
diff --git a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/DosFilter.java b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/security/DosFilter.java
similarity index 98%
rename from hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/DosFilter.java
rename to hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/security/DosFilter.java
index 11e8dfc8d..2bfa2dc04 100644
--- a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/DosFilter.java
+++ b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/security/DosFilter.java
@@ -7,7 +7,7 @@
*
* SPDX-License-Identifier: EPL-2.0
*/
-package org.eclipse.hawkbit.security;
+package org.eclipse.hawkbit.rest.security;
import java.io.IOException;
import java.util.Collection;
@@ -23,6 +23,7 @@ import jakarta.servlet.http.HttpServletResponse;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import lombok.extern.slf4j.Slf4j;
+import org.eclipse.hawkbit.security.SecurityConstants;
import org.eclipse.hawkbit.util.IpUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
diff --git a/hawkbit-test-report/pom.xml b/hawkbit-test-report/pom.xml
index 4af2916cc..39b24e678 100644
--- a/hawkbit-test-report/pom.xml
+++ b/hawkbit-test-report/pom.xml
@@ -36,11 +36,6 @@
hawkbit-security-integration
${project.version}
-
- org.eclipse.hawkbit
- hawkbit-http-security
- ${project.version}
-
org.eclipse.hawkbit
hawkbit-repository-api
diff --git a/pom.xml b/pom.xml
index 5566dc145..2a42368e5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -135,7 +135,6 @@
hawkbit-core
hawkbit-security-core
hawkbit-security-integration
- hawkbit-http-security
hawkbit-artifact
hawkbit-repository
hawkbit-autoconfigure
diff --git a/site/content/guides/clustering.md b/site/content/guides/clustering.md
index d031d4c2a..548a9916d 100644
--- a/site/content/guides/clustering.md
+++ b/site/content/guides/clustering.md
@@ -46,7 +46,7 @@ This has to be kept in mind e.g. if the scheduler executes critical code which h
### Denial-of-Service (DoS) filter
hawkBit owns the feature of guarding itself from DoS attacks,
-a [DoS filter](https://github.com/eclipse-hawkbit/hawkbit/blob/master/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/DosFilter.java).
+a [DoS filter](https://github.com/eclipse-hawkbit/hawkbit/blob/master/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/security/DosFilter.java).
It reduces the maximum number of requests per seconds which can be configured for read and write requests.
This mechanism is only working for every node separately, i.e. in a cluster environment the worst-case behaviour would
be that the maximum number of requests per seconds will be increased to its product if every request is handled by a
diff --git a/site/src/main/java/org/eclipse/hawkbit/doc/Start.java b/site/src/main/java/org/eclipse/hawkbit/doc/Start.java
index b5d684a7a..7054b615d 100644
--- a/site/src/main/java/org/eclipse/hawkbit/doc/Start.java
+++ b/site/src/main/java/org/eclipse/hawkbit/doc/Start.java
@@ -9,7 +9,6 @@
*/
package org.eclipse.hawkbit.doc;
-import org.eclipse.hawkbit.autoconfigure.security.EnableHawkbitManagedSecurityConfiguration;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -18,7 +17,6 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
* The minimal configuration for the stand alone hawkBit server.
*/
@SpringBootApplication
-@EnableHawkbitManagedSecurityConfiguration
// Exception squid:S1118 - Spring boot standard behavior
@SuppressWarnings({ "squid:S1118" })
public class Start {