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 index 5c75f2730..fedb17a55 100644 --- 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 @@ -22,6 +22,7 @@ import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import org.eclipse.hawkbit.cache.DownloadIdCache; +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; @@ -134,32 +135,39 @@ public class SecurityManagedConfiguration { } /** - * {@link WebSecurityConfigurer} for the internal SP controller API. + * {@link WebSecurityConfigurer} for the hawkBit server DDI interface. */ @Configuration @Order(300) @ConditionalOnClass(DdiApiConfiguration.class) static class ControllerSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { - private static final String DDI_ANT_MATCHER = "/{tenant}/controller/**"; + private static final String[] DDI_ANT_MATCHERS = { DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}", + DdiRestConstants.BASE_V1_REQUEST_MAPPING + "/{controllerId}/deploymentBase/**", + 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 SecurityProperties springSecurityProperties; + private final SystemSecurityContext systemSecurityContext; @Autowired - private ControllerManagement controllerManagement; - - @Autowired - private TenantConfigurationManagement tenantConfigurationManagement; - - @Autowired - private TenantAware tenantAware; - - @Autowired - private DdiSecurityProperties ddiSecurityConfiguration; - - @Autowired - private SecurityProperties springSecurityProperties; - - @Autowired - private SystemSecurityContext systemSecurityContext; + ControllerSecurityConfigurationAdapter(final ControllerManagement controllerManagement, + final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware, + final DdiSecurityProperties ddiSecurityConfiguration, final SecurityProperties springSecurityProperties, + final SystemSecurityContext systemSecurityContext) { + this.controllerManagement = controllerManagement; + this.tenantConfigurationManagement = tenantConfigurationManagement; + this.tenantAware = tenantAware; + this.ddiSecurityConfiguration = ddiSecurityConfiguration; + this.springSecurityProperties = springSecurityProperties; + this.systemSecurityContext = systemSecurityContext; + } /** * Filter to protect the hawkBit server DDI interface against to many @@ -175,7 +183,7 @@ public class SecurityManagedConfiguration { @ConditionalOnProperty(prefix = "hawkbit.server.security.dos.filter", name = "enabled", matchIfMissing = true) public FilterRegistrationBean dosDDiFilter(final HawkbitSecurityProperties securityProperties) { - final FilterRegistrationBean filterRegBean = dosFilter(Arrays.asList(DDI_ANT_MATCHER), + final FilterRegistrationBean filterRegBean = dosFilter(Arrays.asList(DDI_ANT_MATCHERS), securityProperties.getDos().getFilter(), securityProperties.getClients()); filterRegBean.setOrder(DOS_FILTER_ORDER); filterRegBean.setName("dosDDiFilter"); @@ -183,6 +191,122 @@ public class SecurityManagedConfiguration { return filterRegBean; } + @Override + protected void configure(final HttpSecurity http) throws Exception { + + final ControllerTenantAwareAuthenticationDetailsSource authenticationDetailsSource = new ControllerTenantAwareAuthenticationDetailsSource(); + + 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); + + HttpSecurity httpSec = http.csrf().disable(); + + if (springSecurityProperties.isRequireSsl()) { + httpSec = httpSec.requiresChannel().anyRequest().requiresSecure().and(); + } + + if (ddiSecurityConfiguration.getAuthentication().getAnonymous().isEnabled()) { + + LOG.info( + "******************\n** Anonymous controller security enabled, should only be used for developing purposes **\n******************"); + + final AnonymousAuthenticationFilter anoymousFilter = new AnonymousAuthenticationFilter( + "controllerAnonymousFilter", "anonymous", + Arrays.asList(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS))); + anoymousFilter.setAuthenticationDetailsSource(authenticationDetailsSource); + httpSec.requestMatchers().antMatchers(DDI_ANT_MATCHERS).and().securityContext().disable().anonymous() + .authenticationFilter(anoymousFilter); + } else { + + httpSec.addFilter(securityHeaderFilter).addFilter(securityTokenFilter) + .addFilter(gatewaySecurityTokenFilter).requestMatchers().antMatchers(DDI_ANT_MATCHERS).and() + .anonymous().disable().authorizeRequests().anyRequest().authenticated().and() + .exceptionHandling() + .authenticationEntryPoint((request, response, authException) -> response + .setStatus(HttpStatus.UNAUTHORIZED.value())) + .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); + } + } + + @Override + protected void configure(final AuthenticationManagerBuilder auth) throws Exception { + + auth.authenticationProvider(new PreAuthTokenSourceTrustAuthenticationProvider( + ddiSecurityConfiguration.getRp().getTrustedIPs())); + } + } + + /** + * {@link WebSecurityConfigurer} for the hawkBit server DDI download + * interface. + */ + @Configuration + @Order(301) + @ConditionalOnClass(DdiApiConfiguration.class) + static class ControllerDownloadSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter { + + 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 SecurityProperties springSecurityProperties; + private final SystemSecurityContext systemSecurityContext; + + @Autowired + ControllerDownloadSecurityConfigurationAdapter(final ControllerManagement controllerManagement, + final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware, + final DdiSecurityProperties ddiSecurityConfiguration, final SecurityProperties springSecurityProperties, + final SystemSecurityContext systemSecurityContext) { + this.controllerManagement = controllerManagement; + this.tenantConfigurationManagement = tenantConfigurationManagement; + this.tenantAware = tenantAware; + this.ddiSecurityConfiguration = ddiSecurityConfiguration; + this.springSecurityProperties = springSecurityProperties; + this.systemSecurityContext = systemSecurityContext; + } + + /** + * Filter to protect the hawkBit server DDI download interface against + * to 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 dosDDiDlFilter(final HawkbitSecurityProperties securityProperties) { + + final FilterRegistrationBean filterRegBean = dosFilter(Arrays.asList(DDI_DL_ANT_MATCHER), + securityProperties.getDos().getFilter(), securityProperties.getClients()); + filterRegBean.setOrder(DOS_FILTER_ORDER); + filterRegBean.setName("dosDDiDlFilter"); + + return filterRegBean; + } + @Override protected void configure(final HttpSecurity http) throws Exception { @@ -227,17 +351,16 @@ public class SecurityManagedConfiguration { final AnonymousAuthenticationFilter anoymousFilter = new AnonymousAuthenticationFilter( "controllerAnonymousFilter", "anonymous", - Arrays.asList(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS), - new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_DOWNLOAD_ROLE))); + Arrays.asList(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS))); anoymousFilter.setAuthenticationDetailsSource(authenticationDetailsSource); - httpSec.requestMatchers().antMatchers(DDI_ANT_MATCHER).and().securityContext().disable().anonymous() + httpSec.requestMatchers().antMatchers(DDI_DL_ANT_MATCHER).and().securityContext().disable().anonymous() .authenticationFilter(anoymousFilter); } else { httpSec.addFilter(securityHeaderFilter).addFilter(securityTokenFilter) .addFilter(gatewaySecurityTokenFilter).addFilter(controllerAnonymousDownloadFilter) - .antMatcher(DDI_ANT_MATCHER).anonymous().disable().authorizeRequests().anyRequest() - .authenticated().and().exceptionHandling() + .requestMatchers().antMatchers(DDI_DL_ANT_MATCHER).and().anonymous().disable() + .authorizeRequests().anyRequest().authenticated().and().exceptionHandling() .authenticationEntryPoint((request, response, authException) -> response .setStatus(HttpStatus.UNAUTHORIZED.value())) .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); diff --git a/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentication.java b/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentication.java index 91c089f78..41372562c 100644 --- a/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentication.java +++ b/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentication.java @@ -22,10 +22,10 @@ import org.eclipse.hawkbit.security.ControllerPreAuthenticatedAnonymousFilter; import org.eclipse.hawkbit.security.ControllerPreAuthenticatedGatewaySecurityTokenFilter; import org.eclipse.hawkbit.security.ControllerPreAuthenticatedSecurityHeaderFilter; import org.eclipse.hawkbit.security.DdiSecurityProperties; -import org.eclipse.hawkbit.security.DmfTenantSecurityToken; import org.eclipse.hawkbit.security.PreAuthTokenSourceTrustAuthenticationProvider; -import org.eclipse.hawkbit.security.PreAuthentificationFilter; +import org.eclipse.hawkbit.security.PreAuthenticationFilter; import org.eclipse.hawkbit.security.SystemSecurityContext; +import org.eclipse.hawkbit.security.DmfTenantSecurityToken; import org.eclipse.hawkbit.tenancy.TenantAware; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -44,7 +44,7 @@ public class AmqpControllerAuthentication { private final PreAuthTokenSourceTrustAuthenticationProvider preAuthenticatedAuthenticationProvider = new PreAuthTokenSourceTrustAuthenticationProvider(); - private List filterChain; + private List filterChain; private final ControllerManagement controllerManagement; @@ -124,7 +124,7 @@ public class AmqpControllerAuthentication { public Authentication doAuthenticate(final DmfTenantSecurityToken securityToken) { resolveTenant(securityToken); PreAuthenticatedAuthenticationToken authentication = new PreAuthenticatedAuthenticationToken(null, null); - for (final PreAuthentificationFilter filter : filterChain) { + for (final PreAuthenticationFilter filter : filterChain) { final PreAuthenticatedAuthenticationToken authenticationRest = createAuthentication(filter, securityToken); if (authenticationRest != null) { authentication = authenticationRest; @@ -144,7 +144,7 @@ public class AmqpControllerAuthentication { } - private static PreAuthenticatedAuthenticationToken createAuthentication(final PreAuthentificationFilter filter, + private static PreAuthenticatedAuthenticationToken createAuthentication(final PreAuthenticationFilter filter, final DmfTenantSecurityToken secruityToken) { if (!filter.isEnable(secruityToken)) { @@ -161,7 +161,8 @@ public class AmqpControllerAuthentication { LOGGER.debug("preAuthenticatedPrincipal = {} trying to authenticate", principal); - return new PreAuthenticatedAuthenticationToken(principal, credentials); + return new PreAuthenticatedAuthenticationToken(principal, credentials, + filter.getSuccessfulAuthenticationAuthorities()); } } diff --git a/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/integration/AmqpAuthenticationMessageHandlerIntegrationTest.java b/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/integration/AmqpAuthenticationMessageHandlerIntegrationTest.java index ef7749a76..27dbfc75e 100644 --- a/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/integration/AmqpAuthenticationMessageHandlerIntegrationTest.java +++ b/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/integration/AmqpAuthenticationMessageHandlerIntegrationTest.java @@ -92,7 +92,7 @@ public class AmqpAuthenticationMessageHandlerIntegrationTest extends AbstractAmq @Test @Description("Target in the message is null.This message is invalid and should not requeued. Additional the receive message is null") public void securityTokenFileResourceIsNull() { - enableAnonymousAuthentification(); + enableAnonymousAuthentication(); final DmfTenantSecurityToken securityToken = createTenantSecurityToken(TENANT_EXIST, TARGET, null); final Message returnMessage = sendAndReceiveAuthenticationMessage(securityToken); verifyResult(returnMessage, HttpStatus.NOT_FOUND, null); @@ -114,7 +114,7 @@ public class AmqpAuthenticationMessageHandlerIntegrationTest extends AbstractAmq @Test @Description("Verify that the receive message contains a 404 code,if the artifact could not found") public void fileResourceGetSha1InSecurityTokenIsNull() { - enableAnonymousAuthentification(); + enableAnonymousAuthentication(); final DmfTenantSecurityToken securityToken = createTenantSecurityToken(TENANT_EXIST, TARGET, FileResource.createFileResourceBySha1(null)); @@ -143,7 +143,7 @@ public class AmqpAuthenticationMessageHandlerIntegrationTest extends AbstractAmq @Test @Description("Verify that the receive message contains a 404 code, if there is no artifact for the given sha1") public void artifactForFileResourceSHA1NotFound() { - enableAnonymousAuthentification(); + enableAnonymousAuthentication(); final DmfTenantSecurityToken securityToken = createTenantSecurityToken(TENANT_EXIST, TARGET, FileResource.createFileResourceBySha1(TARGET_SECRUITY_TOKEN)); @@ -156,7 +156,7 @@ public class AmqpAuthenticationMessageHandlerIntegrationTest extends AbstractAmq @Test @Description("Verify that the receive message contains a 404 code, if there is no existing target for the given controller id") public void artifactForFileResourceSHA1FoundTargetNotExists() { - enableAnonymousAuthentification(); + enableAnonymousAuthentication(); final DistributionSet distributionSet = createDistributionSet(); final List artifacts = createArtifacts(distributionSet); final String sha1Hash = artifacts.get(0).getSha1Hash(); @@ -226,7 +226,7 @@ public class AmqpAuthenticationMessageHandlerIntegrationTest extends AbstractAmq @Test @Description("Verify that the receive message contains a 200 code and a artifact without a controller id (anonymous enabled)") public void anonymousAuthentification() { - enableAnonymousAuthentification(); + enableAnonymousAuthentication(); final DistributionSet distributionSet = createDistributionSet(); final List artifacts = createArtifacts(distributionSet); final Artifact artifact = artifacts.get(0); @@ -260,7 +260,7 @@ public class AmqpAuthenticationMessageHandlerIntegrationTest extends AbstractAmq @Test @Description("Verify that the receive message contains a 404, if there is no artifact to the given filename") public void artifactForFileResourceFileNameNotFound() { - enableAnonymousAuthentification(); + enableAnonymousAuthentication(); final DmfTenantSecurityToken securityToken = createTenantSecurityToken(TENANT_EXIST, TARGET, FileResource.createFileResourceByFilename("Test.txt")); @@ -289,7 +289,7 @@ public class AmqpAuthenticationMessageHandlerIntegrationTest extends AbstractAmq @Test @Description("Verify that the receive message contains a 404, if there is no exisiting target") public void artifactForFileResourceArtifactIdFoundTargetNotExists() { - enableAnonymousAuthentification(); + enableAnonymousAuthentication(); final DistributionSet distributionSet = createDistributionSet(); final List artifacts = createArtifacts(distributionSet); final FileResource fileResource = FileResource.createFileResourceByArtifactId(artifacts.get(0).getId()); @@ -323,7 +323,7 @@ public class AmqpAuthenticationMessageHandlerIntegrationTest extends AbstractAmq @Test @Description("Verify that the receive message contains a 404, if there is no artifact to the given softwareModuleFilename") public void artifactForFileResourceSoftwareModuleFilenameNotFound() { - enableAnonymousAuthentification(); + enableAnonymousAuthentication(); final DmfTenantSecurityToken securityToken = createTenantSecurityToken(TENANT_EXIST, TARGET, FileResource.softwareModuleFilename(1L, "Test.txt")); @@ -336,7 +336,7 @@ public class AmqpAuthenticationMessageHandlerIntegrationTest extends AbstractAmq @Test @Description("Verify that the receive message contains a 404, if there is no existing target for the file resource") public void artifactForFileResourceSoftwareModuleFilenameFoundTargetNotExists() { - enableAnonymousAuthentification(); + enableAnonymousAuthentication(); final DistributionSet distributionSet = createDistributionSet(); final List artifacts = createArtifacts(distributionSet); @@ -376,7 +376,7 @@ public class AmqpAuthenticationMessageHandlerIntegrationTest extends AbstractAmq } - private void verifyOkResult(Message returnMessage, Artifact artifact) { + private void verifyOkResult(final Message returnMessage, final Artifact artifact) { final DmfDownloadResponse convertedMessage = verifyResult(returnMessage, HttpStatus.OK, null); assertThat(convertedMessage.getDownloadUrl()).isNotNull(); assertThat(convertedMessage.getArtifact()).isNotNull(); @@ -384,7 +384,7 @@ public class AmqpAuthenticationMessageHandlerIntegrationTest extends AbstractAmq } - private void enableAnonymousAuthentification() { + private void enableAnonymousAuthentication() { tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.ANONYMOUS_DOWNLOAD_MODE_ENABLED, true); tenantConfigurationManagement.addOrUpdateConfiguration( @@ -405,15 +405,16 @@ public class AmqpAuthenticationMessageHandlerIntegrationTest extends AbstractAmq private DmfTenantSecurityToken createTenantSecurityToken(final String tenant, final String controllerId, final FileResource fileResource) { - final DmfTenantSecurityToken tenantSecurityToken = new DmfTenantSecurityToken(tenant, controllerId, fileResource); + final DmfTenantSecurityToken tenantSecurityToken = new DmfTenantSecurityToken(tenant, controllerId, + fileResource); tenantSecurityToken.putHeader(DmfTenantSecurityToken.AUTHORIZATION_HEADER, TARGET_TOKEN_HEADER); return tenantSecurityToken; } private DmfTenantSecurityToken createTenantSecurityToken(final String tenant, final Long targetId, final String controllerId, final FileResource fileResource) { - final DmfTenantSecurityToken tenantSecurityToken = new DmfTenantSecurityToken(tenant, null, controllerId, targetId, - fileResource); + final DmfTenantSecurityToken tenantSecurityToken = new DmfTenantSecurityToken(tenant, null, controllerId, + targetId, fileResource); tenantSecurityToken.putHeader(DmfTenantSecurityToken.AUTHORIZATION_HEADER, TARGET_TOKEN_HEADER); return tenantSecurityToken; } diff --git a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/AbstractHttpControllerAuthenticationFilter.java b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/AbstractHttpControllerAuthenticationFilter.java index f81b4a393..aa1be8fb5 100644 --- a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/AbstractHttpControllerAuthenticationFilter.java +++ b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/AbstractHttpControllerAuthenticationFilter.java @@ -65,7 +65,7 @@ public abstract class AbstractHttpControllerAuthenticationFilter extends Abstrac private final AntPathMatcher pathExtractor; - private PreAuthentificationFilter abstractControllerAuthenticationFilter; + private PreAuthenticationFilter abstractControllerAuthenticationFilter; /** * Constructor for sub-classes. @@ -108,7 +108,7 @@ public abstract class AbstractHttpControllerAuthenticationFilter extends Abstrac } } - protected abstract PreAuthentificationFilter createControllerAuthenticationFilter(); + protected abstract PreAuthenticationFilter createControllerAuthenticationFilter(); @Override protected void successfulAuthentication(final HttpServletRequest request, final HttpServletResponse response, diff --git a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticateAnonymousDownloadFilter.java b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticateAnonymousDownloadFilter.java index 7eb338e31..532f581f4 100644 --- a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticateAnonymousDownloadFilter.java +++ b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticateAnonymousDownloadFilter.java @@ -39,7 +39,7 @@ public class HttpControllerPreAuthenticateAnonymousDownloadFilter extends Abstra } @Override - protected PreAuthentificationFilter createControllerAuthenticationFilter() { + protected PreAuthenticationFilter createControllerAuthenticationFilter() { return new ControllerPreAuthenticatedAnonymousDownload(tenantConfigurationManagement, tenantAware, systemSecurityContext); } diff --git a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticateSecurityTokenFilter.java b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticateSecurityTokenFilter.java index 8926506e1..1c5ce0a60 100644 --- a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticateSecurityTokenFilter.java +++ b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticateSecurityTokenFilter.java @@ -55,7 +55,7 @@ public class HttpControllerPreAuthenticateSecurityTokenFilter extends AbstractHt } @Override - protected PreAuthentificationFilter createControllerAuthenticationFilter() { + protected PreAuthenticationFilter createControllerAuthenticationFilter() { return new ControllerPreAuthenticateSecurityTokenFilter(tenantConfigurationManagement, controllerManagement, tenantAware, systemSecurityContext); } diff --git a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedGatewaySecurityTokenFilter.java b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedGatewaySecurityTokenFilter.java index 985c04f34..4af1a0140 100644 --- a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedGatewaySecurityTokenFilter.java +++ b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedGatewaySecurityTokenFilter.java @@ -34,7 +34,7 @@ public class HttpControllerPreAuthenticatedGatewaySecurityTokenFilter * the tenant aware service to get configuration for the specific * tenant * @param systemSecurityContext - * * @param systemSecurityContext the system security context + * the system security context */ public HttpControllerPreAuthenticatedGatewaySecurityTokenFilter( final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware, @@ -43,7 +43,7 @@ public class HttpControllerPreAuthenticatedGatewaySecurityTokenFilter } @Override - protected PreAuthentificationFilter createControllerAuthenticationFilter() { + protected PreAuthenticationFilter createControllerAuthenticationFilter() { return new ControllerPreAuthenticatedGatewaySecurityTokenFilter(tenantConfigurationManagement, tenantAware, systemSecurityContext); } diff --git a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedSecurityHeaderFilter.java b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedSecurityHeaderFilter.java index d4221a2ca..20f60d98b 100644 --- a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedSecurityHeaderFilter.java +++ b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpControllerPreAuthenticatedSecurityHeaderFilter.java @@ -54,7 +54,7 @@ public class HttpControllerPreAuthenticatedSecurityHeaderFilter extends Abstract } @Override - protected PreAuthentificationFilter createControllerAuthenticationFilter() { + protected PreAuthenticationFilter createControllerAuthenticationFilter() { return new ControllerPreAuthenticatedSecurityHeaderFilter(caCommonNameHeader, caAuthorityNameHeader, tenantConfigurationManagement, tenantAware, systemSecurityContext); } diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ArtifactManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ArtifactManagement.java index 65790d882..f59b6896e 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ArtifactManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ArtifactManagement.java @@ -204,7 +204,7 @@ public interface ArtifactManagement { * */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DOWNLOAD_ARTIFACT + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.HAS_CONTROLLER_DOWNLOAD) + + SpringEvalExpressions.IS_CONTROLLER) Optional loadArtifactBinary(@NotEmpty String sha1Hash); } diff --git a/hawkbit-runtime/hawkbit-update-server/src/main/resources/application.properties b/hawkbit-runtime/hawkbit-update-server/src/main/resources/application.properties index de1c14324..306a72b07 100644 --- a/hawkbit-runtime/hawkbit-update-server/src/main/resources/application.properties +++ b/hawkbit-runtime/hawkbit-update-server/src/main/resources/application.properties @@ -12,7 +12,7 @@ security.user.name=admin security.user.password=admin # DDI authentication configuration -hawkbit.server.ddi.security.authentication.anonymous.enabled=true +hawkbit.server.ddi.security.authentication.anonymous.enabled=false hawkbit.server.ddi.security.authentication.targettoken.enabled=true hawkbit.server.ddi.security.authentication.gatewaytoken.enabled=true diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java index 376fe70b4..41c8184f8 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java @@ -246,12 +246,6 @@ public final class SpPermission { */ public static final String CONTROLLER_ROLE_ANONYMOUS = "ROLE_CONTROLLER_ANONYMOUS"; - /** - * The role which contains in the spring security context in case an - * controller is authenticated to download artifacts. - */ - public static final String CONTROLLER_DOWNLOAD_ROLE = "ROLE_CONTROLLER_DOWNLOAD"; - /** * The role which contains the spring security context in case the * system is executing code which is necessary to be privileged. @@ -384,14 +378,6 @@ public final class SpPermission { public static final String IS_CONTROLLER = "hasAnyRole('" + CONTROLLER_ROLE_ANONYMOUS + "', '" + CONTROLLER_ROLE + "')"; - /** - * Spring security eval hasAuthority expression to check if the spring - * context contains the role to allow controllers to download specific - * role {@link SpringEvalExpressions#CONTROLLER_DOWNLOAD_ROLE} - */ - public static final String HAS_CONTROLLER_DOWNLOAD = HAS_AUTH_PREFIX + CONTROLLER_DOWNLOAD_ROLE - + HAS_AUTH_SUFFIX; - /** * Spring security eval hasAuthority expression to check if spring * context contains {@link SpPermission#CREATE_REPOSITORY} and diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/AbstractControllerAuthenticationFilter.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/AbstractControllerAuthenticationFilter.java index 66a3b814c..43e75126f 100644 --- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/AbstractControllerAuthenticationFilter.java +++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/AbstractControllerAuthenticationFilter.java @@ -8,19 +8,22 @@ */ package org.eclipse.hawkbit.security; +import java.util.Arrays; +import java.util.Collection; + +import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.tenancy.TenantAware; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; /** * An abstraction for all controller based security. Check if the tenant * configuration is enabled. - * - * - * */ -public abstract class AbstractControllerAuthenticationFilter implements PreAuthentificationFilter { +public abstract class AbstractControllerAuthenticationFilter implements PreAuthenticationFilter { private static final Logger LOGGER = LoggerFactory.getLogger(AbstractControllerAuthenticationFilter.class); @@ -54,4 +57,9 @@ public abstract class AbstractControllerAuthenticationFilter implements PreAuthe } } + + @Override + public Collection getSuccessfulAuthenticationAuthorities() { + return Arrays.asList(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE)); + } } diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedAnonymousDownload.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedAnonymousDownload.java index a9564810f..572bdb561 100644 --- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedAnonymousDownload.java +++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedAnonymousDownload.java @@ -8,15 +8,10 @@ */ package org.eclipse.hawkbit.security; -import java.util.Arrays; -import java.util.Collection; - import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; /** * An pre-authenticated processing filter which add the @@ -59,9 +54,4 @@ public class ControllerPreAuthenticatedAnonymousDownload extends AbstractControl protected String getTenantConfigurationKey() { return TenantConfigurationKey.ANONYMOUS_DOWNLOAD_MODE_ENABLED; } - - @Override - public Collection getSuccessfulAuthenticationAuthorities() { - return Arrays.asList(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_DOWNLOAD_ROLE)); - } } diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedAnonymousFilter.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedAnonymousFilter.java index 8f21a0ba5..3555a32d0 100644 --- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedAnonymousFilter.java +++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedAnonymousFilter.java @@ -14,7 +14,7 @@ package org.eclipse.hawkbit.security; * * @see DdiSecurityProperties */ -public class ControllerPreAuthenticatedAnonymousFilter implements PreAuthentificationFilter { +public class ControllerPreAuthenticatedAnonymousFilter implements PreAuthenticationFilter { private final DdiSecurityProperties ddiSecurityConfiguration; diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/PreAuthTokenSourceTrustAuthenticationProvider.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/PreAuthTokenSourceTrustAuthenticationProvider.java index ffe1b7377..d7dddb4f6 100644 --- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/PreAuthTokenSourceTrustAuthenticationProvider.java +++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/PreAuthTokenSourceTrustAuthenticationProvider.java @@ -12,7 +12,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.List; -import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.authentication.AuthenticationProvider; @@ -20,7 +19,6 @@ import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.InsufficientAuthenticationException; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken; /** @@ -91,19 +89,17 @@ public class PreAuthTokenSourceTrustAuthenticationProvider implements Authentica final Object credentials = token.getCredentials(); final Object principal = token.getPrincipal(); final Object tokenDetails = token.getDetails(); + final Collection authorities = token.getAuthorities(); if (principal == null) { throw new BadCredentialsException("The provided principal and credentials are not match"); } - boolean successAuthentication = calculateAuthenticationSuccess(principal, credentials, tokenDetails); + final boolean successAuthentication = calculateAuthenticationSuccess(principal, credentials, tokenDetails); if (successAuthentication) { - final Collection controllerAuthorities = new ArrayList<>(); - controllerAuthorities.add(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE)); - controllerAuthorities.add(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_DOWNLOAD_ROLE)); final PreAuthenticatedAuthenticationToken successToken = new PreAuthenticatedAuthenticationToken(principal, - credentials, controllerAuthorities); + credentials, authorities); successToken.setDetails(tokenDetails); return successToken; } @@ -132,7 +128,8 @@ public class PreAuthTokenSourceTrustAuthenticationProvider implements Authentica * @return true if authentication succeeded, otherwise * false */ - private boolean calculateAuthenticationSuccess(Object principal, Object credentials, Object tokenDetails) { + private boolean calculateAuthenticationSuccess(final Object principal, final Object credentials, + final Object tokenDetails) { boolean successAuthentication = false; if (credentials instanceof Collection) { final Collection multiValueCredentials = (Collection) credentials; diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/PreAuthentificationFilter.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/PreAuthenticationFilter.java similarity index 95% rename from hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/PreAuthentificationFilter.java rename to hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/PreAuthenticationFilter.java index 17e70e069..fe8b6da95 100644 --- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/PreAuthentificationFilter.java +++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/PreAuthenticationFilter.java @@ -15,9 +15,9 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; /** - * Interface for Pre Authentification. + * Interface for Pre Authentication. */ -public interface PreAuthentificationFilter { +public interface PreAuthenticationFilter { /** * Check if the filter is enabled. diff --git a/hawkbit-security-integration/src/test/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedAnonymousDownloadTest.java b/hawkbit-security-integration/src/test/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedAnonymousDownloadTest.java index c2ad66a93..2f8187a96 100644 --- a/hawkbit-security-integration/src/test/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedAnonymousDownloadTest.java +++ b/hawkbit-security-integration/src/test/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedAnonymousDownloadTest.java @@ -56,6 +56,6 @@ public class ControllerPreAuthenticatedAnonymousDownloadTest { public void successfulAuthenticationAdditionalAuthoritiesForDownload() { assertThat(underTest.getSuccessfulAuthenticationAuthorities()) .as("Additional authorities should be containing the download anonymous role") - .contains(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_DOWNLOAD_ROLE)); + .contains(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE)); } }