Anonymous download activated does not result in general DDI anonymous (#616)
* Fix unintended anonymous access in DDI API. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Fix test. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com> * Fix ant matcher. Signed-off-by: kaizimmerm <kai.zimmermann@bosch-si.com>
This commit is contained in:
@@ -22,6 +22,7 @@ import javax.servlet.ServletRequest;
|
|||||||
import javax.servlet.ServletResponse;
|
import javax.servlet.ServletResponse;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.cache.DownloadIdCache;
|
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.ddi.rest.resource.DdiApiConfiguration;
|
||||||
import org.eclipse.hawkbit.im.authentication.SpPermission;
|
import org.eclipse.hawkbit.im.authentication.SpPermission;
|
||||||
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
|
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
|
@Configuration
|
||||||
@Order(300)
|
@Order(300)
|
||||||
@ConditionalOnClass(DdiApiConfiguration.class)
|
@ConditionalOnClass(DdiApiConfiguration.class)
|
||||||
static class ControllerSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
|
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
|
@Autowired
|
||||||
private ControllerManagement controllerManagement;
|
ControllerSecurityConfigurationAdapter(final ControllerManagement controllerManagement,
|
||||||
|
final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware,
|
||||||
@Autowired
|
final DdiSecurityProperties ddiSecurityConfiguration, final SecurityProperties springSecurityProperties,
|
||||||
private TenantConfigurationManagement tenantConfigurationManagement;
|
final SystemSecurityContext systemSecurityContext) {
|
||||||
|
this.controllerManagement = controllerManagement;
|
||||||
@Autowired
|
this.tenantConfigurationManagement = tenantConfigurationManagement;
|
||||||
private TenantAware tenantAware;
|
this.tenantAware = tenantAware;
|
||||||
|
this.ddiSecurityConfiguration = ddiSecurityConfiguration;
|
||||||
@Autowired
|
this.springSecurityProperties = springSecurityProperties;
|
||||||
private DdiSecurityProperties ddiSecurityConfiguration;
|
this.systemSecurityContext = systemSecurityContext;
|
||||||
|
}
|
||||||
@Autowired
|
|
||||||
private SecurityProperties springSecurityProperties;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private SystemSecurityContext systemSecurityContext;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filter to protect the hawkBit server DDI interface against to many
|
* 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)
|
@ConditionalOnProperty(prefix = "hawkbit.server.security.dos.filter", name = "enabled", matchIfMissing = true)
|
||||||
public FilterRegistrationBean dosDDiFilter(final HawkbitSecurityProperties securityProperties) {
|
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());
|
securityProperties.getDos().getFilter(), securityProperties.getClients());
|
||||||
filterRegBean.setOrder(DOS_FILTER_ORDER);
|
filterRegBean.setOrder(DOS_FILTER_ORDER);
|
||||||
filterRegBean.setName("dosDDiFilter");
|
filterRegBean.setName("dosDDiFilter");
|
||||||
@@ -183,6 +191,122 @@ public class SecurityManagedConfiguration {
|
|||||||
return filterRegBean;
|
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
|
@Override
|
||||||
protected void configure(final HttpSecurity http) throws Exception {
|
protected void configure(final HttpSecurity http) throws Exception {
|
||||||
|
|
||||||
@@ -227,17 +351,16 @@ public class SecurityManagedConfiguration {
|
|||||||
|
|
||||||
final AnonymousAuthenticationFilter anoymousFilter = new AnonymousAuthenticationFilter(
|
final AnonymousAuthenticationFilter anoymousFilter = new AnonymousAuthenticationFilter(
|
||||||
"controllerAnonymousFilter", "anonymous",
|
"controllerAnonymousFilter", "anonymous",
|
||||||
Arrays.asList(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS),
|
Arrays.asList(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS)));
|
||||||
new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_DOWNLOAD_ROLE)));
|
|
||||||
anoymousFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
|
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);
|
.authenticationFilter(anoymousFilter);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
httpSec.addFilter(securityHeaderFilter).addFilter(securityTokenFilter)
|
httpSec.addFilter(securityHeaderFilter).addFilter(securityTokenFilter)
|
||||||
.addFilter(gatewaySecurityTokenFilter).addFilter(controllerAnonymousDownloadFilter)
|
.addFilter(gatewaySecurityTokenFilter).addFilter(controllerAnonymousDownloadFilter)
|
||||||
.antMatcher(DDI_ANT_MATCHER).anonymous().disable().authorizeRequests().anyRequest()
|
.requestMatchers().antMatchers(DDI_DL_ANT_MATCHER).and().anonymous().disable()
|
||||||
.authenticated().and().exceptionHandling()
|
.authorizeRequests().anyRequest().authenticated().and().exceptionHandling()
|
||||||
.authenticationEntryPoint((request, response, authException) -> response
|
.authenticationEntryPoint((request, response, authException) -> response
|
||||||
.setStatus(HttpStatus.UNAUTHORIZED.value()))
|
.setStatus(HttpStatus.UNAUTHORIZED.value()))
|
||||||
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
|
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
|
||||||
|
|||||||
@@ -22,10 +22,10 @@ import org.eclipse.hawkbit.security.ControllerPreAuthenticatedAnonymousFilter;
|
|||||||
import org.eclipse.hawkbit.security.ControllerPreAuthenticatedGatewaySecurityTokenFilter;
|
import org.eclipse.hawkbit.security.ControllerPreAuthenticatedGatewaySecurityTokenFilter;
|
||||||
import org.eclipse.hawkbit.security.ControllerPreAuthenticatedSecurityHeaderFilter;
|
import org.eclipse.hawkbit.security.ControllerPreAuthenticatedSecurityHeaderFilter;
|
||||||
import org.eclipse.hawkbit.security.DdiSecurityProperties;
|
import org.eclipse.hawkbit.security.DdiSecurityProperties;
|
||||||
import org.eclipse.hawkbit.security.DmfTenantSecurityToken;
|
|
||||||
import org.eclipse.hawkbit.security.PreAuthTokenSourceTrustAuthenticationProvider;
|
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.SystemSecurityContext;
|
||||||
|
import org.eclipse.hawkbit.security.DmfTenantSecurityToken;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -44,7 +44,7 @@ public class AmqpControllerAuthentication {
|
|||||||
|
|
||||||
private final PreAuthTokenSourceTrustAuthenticationProvider preAuthenticatedAuthenticationProvider = new PreAuthTokenSourceTrustAuthenticationProvider();
|
private final PreAuthTokenSourceTrustAuthenticationProvider preAuthenticatedAuthenticationProvider = new PreAuthTokenSourceTrustAuthenticationProvider();
|
||||||
|
|
||||||
private List<PreAuthentificationFilter> filterChain;
|
private List<PreAuthenticationFilter> filterChain;
|
||||||
|
|
||||||
private final ControllerManagement controllerManagement;
|
private final ControllerManagement controllerManagement;
|
||||||
|
|
||||||
@@ -124,7 +124,7 @@ public class AmqpControllerAuthentication {
|
|||||||
public Authentication doAuthenticate(final DmfTenantSecurityToken securityToken) {
|
public Authentication doAuthenticate(final DmfTenantSecurityToken securityToken) {
|
||||||
resolveTenant(securityToken);
|
resolveTenant(securityToken);
|
||||||
PreAuthenticatedAuthenticationToken authentication = new PreAuthenticatedAuthenticationToken(null, null);
|
PreAuthenticatedAuthenticationToken authentication = new PreAuthenticatedAuthenticationToken(null, null);
|
||||||
for (final PreAuthentificationFilter filter : filterChain) {
|
for (final PreAuthenticationFilter filter : filterChain) {
|
||||||
final PreAuthenticatedAuthenticationToken authenticationRest = createAuthentication(filter, securityToken);
|
final PreAuthenticatedAuthenticationToken authenticationRest = createAuthentication(filter, securityToken);
|
||||||
if (authenticationRest != null) {
|
if (authenticationRest != null) {
|
||||||
authentication = authenticationRest;
|
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) {
|
final DmfTenantSecurityToken secruityToken) {
|
||||||
|
|
||||||
if (!filter.isEnable(secruityToken)) {
|
if (!filter.isEnable(secruityToken)) {
|
||||||
@@ -161,7 +161,8 @@ public class AmqpControllerAuthentication {
|
|||||||
|
|
||||||
LOGGER.debug("preAuthenticatedPrincipal = {} trying to authenticate", principal);
|
LOGGER.debug("preAuthenticatedPrincipal = {} trying to authenticate", principal);
|
||||||
|
|
||||||
return new PreAuthenticatedAuthenticationToken(principal, credentials);
|
return new PreAuthenticatedAuthenticationToken(principal, credentials,
|
||||||
|
filter.getSuccessfulAuthenticationAuthorities());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ public class AmqpAuthenticationMessageHandlerIntegrationTest extends AbstractAmq
|
|||||||
@Test
|
@Test
|
||||||
@Description("Target in the message is null.This message is invalid and should not requeued. Additional the receive message is null")
|
@Description("Target in the message is null.This message is invalid and should not requeued. Additional the receive message is null")
|
||||||
public void securityTokenFileResourceIsNull() {
|
public void securityTokenFileResourceIsNull() {
|
||||||
enableAnonymousAuthentification();
|
enableAnonymousAuthentication();
|
||||||
final DmfTenantSecurityToken securityToken = createTenantSecurityToken(TENANT_EXIST, TARGET, null);
|
final DmfTenantSecurityToken securityToken = createTenantSecurityToken(TENANT_EXIST, TARGET, null);
|
||||||
final Message returnMessage = sendAndReceiveAuthenticationMessage(securityToken);
|
final Message returnMessage = sendAndReceiveAuthenticationMessage(securityToken);
|
||||||
verifyResult(returnMessage, HttpStatus.NOT_FOUND, null);
|
verifyResult(returnMessage, HttpStatus.NOT_FOUND, null);
|
||||||
@@ -114,7 +114,7 @@ public class AmqpAuthenticationMessageHandlerIntegrationTest extends AbstractAmq
|
|||||||
@Test
|
@Test
|
||||||
@Description("Verify that the receive message contains a 404 code,if the artifact could not found")
|
@Description("Verify that the receive message contains a 404 code,if the artifact could not found")
|
||||||
public void fileResourceGetSha1InSecurityTokenIsNull() {
|
public void fileResourceGetSha1InSecurityTokenIsNull() {
|
||||||
enableAnonymousAuthentification();
|
enableAnonymousAuthentication();
|
||||||
final DmfTenantSecurityToken securityToken = createTenantSecurityToken(TENANT_EXIST, TARGET,
|
final DmfTenantSecurityToken securityToken = createTenantSecurityToken(TENANT_EXIST, TARGET,
|
||||||
FileResource.createFileResourceBySha1(null));
|
FileResource.createFileResourceBySha1(null));
|
||||||
|
|
||||||
@@ -143,7 +143,7 @@ public class AmqpAuthenticationMessageHandlerIntegrationTest extends AbstractAmq
|
|||||||
@Test
|
@Test
|
||||||
@Description("Verify that the receive message contains a 404 code, if there is no artifact for the given sha1")
|
@Description("Verify that the receive message contains a 404 code, if there is no artifact for the given sha1")
|
||||||
public void artifactForFileResourceSHA1NotFound() {
|
public void artifactForFileResourceSHA1NotFound() {
|
||||||
enableAnonymousAuthentification();
|
enableAnonymousAuthentication();
|
||||||
final DmfTenantSecurityToken securityToken = createTenantSecurityToken(TENANT_EXIST, TARGET,
|
final DmfTenantSecurityToken securityToken = createTenantSecurityToken(TENANT_EXIST, TARGET,
|
||||||
FileResource.createFileResourceBySha1(TARGET_SECRUITY_TOKEN));
|
FileResource.createFileResourceBySha1(TARGET_SECRUITY_TOKEN));
|
||||||
|
|
||||||
@@ -156,7 +156,7 @@ public class AmqpAuthenticationMessageHandlerIntegrationTest extends AbstractAmq
|
|||||||
@Test
|
@Test
|
||||||
@Description("Verify that the receive message contains a 404 code, if there is no existing target for the given controller id")
|
@Description("Verify that the receive message contains a 404 code, if there is no existing target for the given controller id")
|
||||||
public void artifactForFileResourceSHA1FoundTargetNotExists() {
|
public void artifactForFileResourceSHA1FoundTargetNotExists() {
|
||||||
enableAnonymousAuthentification();
|
enableAnonymousAuthentication();
|
||||||
final DistributionSet distributionSet = createDistributionSet();
|
final DistributionSet distributionSet = createDistributionSet();
|
||||||
final List<Artifact> artifacts = createArtifacts(distributionSet);
|
final List<Artifact> artifacts = createArtifacts(distributionSet);
|
||||||
final String sha1Hash = artifacts.get(0).getSha1Hash();
|
final String sha1Hash = artifacts.get(0).getSha1Hash();
|
||||||
@@ -226,7 +226,7 @@ public class AmqpAuthenticationMessageHandlerIntegrationTest extends AbstractAmq
|
|||||||
@Test
|
@Test
|
||||||
@Description("Verify that the receive message contains a 200 code and a artifact without a controller id (anonymous enabled)")
|
@Description("Verify that the receive message contains a 200 code and a artifact without a controller id (anonymous enabled)")
|
||||||
public void anonymousAuthentification() {
|
public void anonymousAuthentification() {
|
||||||
enableAnonymousAuthentification();
|
enableAnonymousAuthentication();
|
||||||
final DistributionSet distributionSet = createDistributionSet();
|
final DistributionSet distributionSet = createDistributionSet();
|
||||||
final List<Artifact> artifacts = createArtifacts(distributionSet);
|
final List<Artifact> artifacts = createArtifacts(distributionSet);
|
||||||
final Artifact artifact = artifacts.get(0);
|
final Artifact artifact = artifacts.get(0);
|
||||||
@@ -260,7 +260,7 @@ public class AmqpAuthenticationMessageHandlerIntegrationTest extends AbstractAmq
|
|||||||
@Test
|
@Test
|
||||||
@Description("Verify that the receive message contains a 404, if there is no artifact to the given filename")
|
@Description("Verify that the receive message contains a 404, if there is no artifact to the given filename")
|
||||||
public void artifactForFileResourceFileNameNotFound() {
|
public void artifactForFileResourceFileNameNotFound() {
|
||||||
enableAnonymousAuthentification();
|
enableAnonymousAuthentication();
|
||||||
final DmfTenantSecurityToken securityToken = createTenantSecurityToken(TENANT_EXIST, TARGET,
|
final DmfTenantSecurityToken securityToken = createTenantSecurityToken(TENANT_EXIST, TARGET,
|
||||||
FileResource.createFileResourceByFilename("Test.txt"));
|
FileResource.createFileResourceByFilename("Test.txt"));
|
||||||
|
|
||||||
@@ -289,7 +289,7 @@ public class AmqpAuthenticationMessageHandlerIntegrationTest extends AbstractAmq
|
|||||||
@Test
|
@Test
|
||||||
@Description("Verify that the receive message contains a 404, if there is no exisiting target")
|
@Description("Verify that the receive message contains a 404, if there is no exisiting target")
|
||||||
public void artifactForFileResourceArtifactIdFoundTargetNotExists() {
|
public void artifactForFileResourceArtifactIdFoundTargetNotExists() {
|
||||||
enableAnonymousAuthentification();
|
enableAnonymousAuthentication();
|
||||||
final DistributionSet distributionSet = createDistributionSet();
|
final DistributionSet distributionSet = createDistributionSet();
|
||||||
final List<Artifact> artifacts = createArtifacts(distributionSet);
|
final List<Artifact> artifacts = createArtifacts(distributionSet);
|
||||||
final FileResource fileResource = FileResource.createFileResourceByArtifactId(artifacts.get(0).getId());
|
final FileResource fileResource = FileResource.createFileResourceByArtifactId(artifacts.get(0).getId());
|
||||||
@@ -323,7 +323,7 @@ public class AmqpAuthenticationMessageHandlerIntegrationTest extends AbstractAmq
|
|||||||
@Test
|
@Test
|
||||||
@Description("Verify that the receive message contains a 404, if there is no artifact to the given softwareModuleFilename")
|
@Description("Verify that the receive message contains a 404, if there is no artifact to the given softwareModuleFilename")
|
||||||
public void artifactForFileResourceSoftwareModuleFilenameNotFound() {
|
public void artifactForFileResourceSoftwareModuleFilenameNotFound() {
|
||||||
enableAnonymousAuthentification();
|
enableAnonymousAuthentication();
|
||||||
final DmfTenantSecurityToken securityToken = createTenantSecurityToken(TENANT_EXIST, TARGET,
|
final DmfTenantSecurityToken securityToken = createTenantSecurityToken(TENANT_EXIST, TARGET,
|
||||||
FileResource.softwareModuleFilename(1L, "Test.txt"));
|
FileResource.softwareModuleFilename(1L, "Test.txt"));
|
||||||
|
|
||||||
@@ -336,7 +336,7 @@ public class AmqpAuthenticationMessageHandlerIntegrationTest extends AbstractAmq
|
|||||||
@Test
|
@Test
|
||||||
@Description("Verify that the receive message contains a 404, if there is no existing target for the file resource")
|
@Description("Verify that the receive message contains a 404, if there is no existing target for the file resource")
|
||||||
public void artifactForFileResourceSoftwareModuleFilenameFoundTargetNotExists() {
|
public void artifactForFileResourceSoftwareModuleFilenameFoundTargetNotExists() {
|
||||||
enableAnonymousAuthentification();
|
enableAnonymousAuthentication();
|
||||||
final DistributionSet distributionSet = createDistributionSet();
|
final DistributionSet distributionSet = createDistributionSet();
|
||||||
final List<Artifact> artifacts = createArtifacts(distributionSet);
|
final List<Artifact> 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);
|
final DmfDownloadResponse convertedMessage = verifyResult(returnMessage, HttpStatus.OK, null);
|
||||||
assertThat(convertedMessage.getDownloadUrl()).isNotNull();
|
assertThat(convertedMessage.getDownloadUrl()).isNotNull();
|
||||||
assertThat(convertedMessage.getArtifact()).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,
|
tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.ANONYMOUS_DOWNLOAD_MODE_ENABLED,
|
||||||
true);
|
true);
|
||||||
tenantConfigurationManagement.addOrUpdateConfiguration(
|
tenantConfigurationManagement.addOrUpdateConfiguration(
|
||||||
@@ -405,15 +405,16 @@ public class AmqpAuthenticationMessageHandlerIntegrationTest extends AbstractAmq
|
|||||||
|
|
||||||
private DmfTenantSecurityToken createTenantSecurityToken(final String tenant, final String controllerId,
|
private DmfTenantSecurityToken createTenantSecurityToken(final String tenant, final String controllerId,
|
||||||
final FileResource fileResource) {
|
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);
|
tenantSecurityToken.putHeader(DmfTenantSecurityToken.AUTHORIZATION_HEADER, TARGET_TOKEN_HEADER);
|
||||||
return tenantSecurityToken;
|
return tenantSecurityToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
private DmfTenantSecurityToken createTenantSecurityToken(final String tenant, final Long targetId,
|
private DmfTenantSecurityToken createTenantSecurityToken(final String tenant, final Long targetId,
|
||||||
final String controllerId, final FileResource fileResource) {
|
final String controllerId, final FileResource fileResource) {
|
||||||
final DmfTenantSecurityToken tenantSecurityToken = new DmfTenantSecurityToken(tenant, null, controllerId, targetId,
|
final DmfTenantSecurityToken tenantSecurityToken = new DmfTenantSecurityToken(tenant, null, controllerId,
|
||||||
fileResource);
|
targetId, fileResource);
|
||||||
tenantSecurityToken.putHeader(DmfTenantSecurityToken.AUTHORIZATION_HEADER, TARGET_TOKEN_HEADER);
|
tenantSecurityToken.putHeader(DmfTenantSecurityToken.AUTHORIZATION_HEADER, TARGET_TOKEN_HEADER);
|
||||||
return tenantSecurityToken;
|
return tenantSecurityToken;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ public abstract class AbstractHttpControllerAuthenticationFilter extends Abstrac
|
|||||||
|
|
||||||
private final AntPathMatcher pathExtractor;
|
private final AntPathMatcher pathExtractor;
|
||||||
|
|
||||||
private PreAuthentificationFilter abstractControllerAuthenticationFilter;
|
private PreAuthenticationFilter abstractControllerAuthenticationFilter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for sub-classes.
|
* Constructor for sub-classes.
|
||||||
@@ -108,7 +108,7 @@ public abstract class AbstractHttpControllerAuthenticationFilter extends Abstrac
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract PreAuthentificationFilter createControllerAuthenticationFilter();
|
protected abstract PreAuthenticationFilter createControllerAuthenticationFilter();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void successfulAuthentication(final HttpServletRequest request, final HttpServletResponse response,
|
protected void successfulAuthentication(final HttpServletRequest request, final HttpServletResponse response,
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ public class HttpControllerPreAuthenticateAnonymousDownloadFilter extends Abstra
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected PreAuthentificationFilter createControllerAuthenticationFilter() {
|
protected PreAuthenticationFilter createControllerAuthenticationFilter() {
|
||||||
return new ControllerPreAuthenticatedAnonymousDownload(tenantConfigurationManagement, tenantAware,
|
return new ControllerPreAuthenticatedAnonymousDownload(tenantConfigurationManagement, tenantAware,
|
||||||
systemSecurityContext);
|
systemSecurityContext);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ public class HttpControllerPreAuthenticateSecurityTokenFilter extends AbstractHt
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected PreAuthentificationFilter createControllerAuthenticationFilter() {
|
protected PreAuthenticationFilter createControllerAuthenticationFilter() {
|
||||||
return new ControllerPreAuthenticateSecurityTokenFilter(tenantConfigurationManagement, controllerManagement,
|
return new ControllerPreAuthenticateSecurityTokenFilter(tenantConfigurationManagement, controllerManagement,
|
||||||
tenantAware, systemSecurityContext);
|
tenantAware, systemSecurityContext);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public class HttpControllerPreAuthenticatedGatewaySecurityTokenFilter
|
|||||||
* the tenant aware service to get configuration for the specific
|
* the tenant aware service to get configuration for the specific
|
||||||
* tenant
|
* tenant
|
||||||
* @param systemSecurityContext
|
* @param systemSecurityContext
|
||||||
* * @param systemSecurityContext the system security context
|
* the system security context
|
||||||
*/
|
*/
|
||||||
public HttpControllerPreAuthenticatedGatewaySecurityTokenFilter(
|
public HttpControllerPreAuthenticatedGatewaySecurityTokenFilter(
|
||||||
final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware,
|
final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware,
|
||||||
@@ -43,7 +43,7 @@ public class HttpControllerPreAuthenticatedGatewaySecurityTokenFilter
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected PreAuthentificationFilter createControllerAuthenticationFilter() {
|
protected PreAuthenticationFilter createControllerAuthenticationFilter() {
|
||||||
return new ControllerPreAuthenticatedGatewaySecurityTokenFilter(tenantConfigurationManagement, tenantAware,
|
return new ControllerPreAuthenticatedGatewaySecurityTokenFilter(tenantConfigurationManagement, tenantAware,
|
||||||
systemSecurityContext);
|
systemSecurityContext);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public class HttpControllerPreAuthenticatedSecurityHeaderFilter extends Abstract
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected PreAuthentificationFilter createControllerAuthenticationFilter() {
|
protected PreAuthenticationFilter createControllerAuthenticationFilter() {
|
||||||
return new ControllerPreAuthenticatedSecurityHeaderFilter(caCommonNameHeader, caAuthorityNameHeader,
|
return new ControllerPreAuthenticatedSecurityHeaderFilter(caCommonNameHeader, caAuthorityNameHeader,
|
||||||
tenantConfigurationManagement, tenantAware, systemSecurityContext);
|
tenantConfigurationManagement, tenantAware, systemSecurityContext);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -204,7 +204,7 @@ public interface ArtifactManagement {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_DOWNLOAD_ARTIFACT + SpringEvalExpressions.HAS_AUTH_OR
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_DOWNLOAD_ARTIFACT + SpringEvalExpressions.HAS_AUTH_OR
|
||||||
+ SpringEvalExpressions.HAS_CONTROLLER_DOWNLOAD)
|
+ SpringEvalExpressions.IS_CONTROLLER)
|
||||||
Optional<AbstractDbArtifact> loadArtifactBinary(@NotEmpty String sha1Hash);
|
Optional<AbstractDbArtifact> loadArtifactBinary(@NotEmpty String sha1Hash);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ security.user.name=admin
|
|||||||
security.user.password=admin
|
security.user.password=admin
|
||||||
|
|
||||||
# DDI authentication configuration
|
# 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.targettoken.enabled=true
|
||||||
hawkbit.server.ddi.security.authentication.gatewaytoken.enabled=true
|
hawkbit.server.ddi.security.authentication.gatewaytoken.enabled=true
|
||||||
|
|
||||||
|
|||||||
@@ -246,12 +246,6 @@ public final class SpPermission {
|
|||||||
*/
|
*/
|
||||||
public static final String CONTROLLER_ROLE_ANONYMOUS = "ROLE_CONTROLLER_ANONYMOUS";
|
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
|
* The role which contains the spring security context in case the
|
||||||
* system is executing code which is necessary to be privileged.
|
* 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
|
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
|
* Spring security eval hasAuthority expression to check if spring
|
||||||
* context contains {@link SpPermission#CREATE_REPOSITORY} and
|
* context contains {@link SpPermission#CREATE_REPOSITORY} and
|
||||||
|
|||||||
@@ -8,19 +8,22 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.security;
|
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.repository.TenantConfigurationManagement;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
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
|
* An abstraction for all controller based security. Check if the tenant
|
||||||
* configuration is enabled.
|
* configuration is enabled.
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractControllerAuthenticationFilter implements PreAuthentificationFilter {
|
public abstract class AbstractControllerAuthenticationFilter implements PreAuthenticationFilter {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractControllerAuthenticationFilter.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(AbstractControllerAuthenticationFilter.class);
|
||||||
|
|
||||||
@@ -54,4 +57,9 @@ public abstract class AbstractControllerAuthenticationFilter implements PreAuthe
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<GrantedAuthority> getSuccessfulAuthenticationAuthorities() {
|
||||||
|
return Arrays.asList(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,15 +8,10 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.security;
|
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.im.authentication.SpPermission.SpringEvalExpressions;
|
||||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
|
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
|
* An pre-authenticated processing filter which add the
|
||||||
@@ -59,9 +54,4 @@ public class ControllerPreAuthenticatedAnonymousDownload extends AbstractControl
|
|||||||
protected String getTenantConfigurationKey() {
|
protected String getTenantConfigurationKey() {
|
||||||
return TenantConfigurationKey.ANONYMOUS_DOWNLOAD_MODE_ENABLED;
|
return TenantConfigurationKey.ANONYMOUS_DOWNLOAD_MODE_ENABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<GrantedAuthority> getSuccessfulAuthenticationAuthorities() {
|
|
||||||
return Arrays.asList(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_DOWNLOAD_ROLE));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ package org.eclipse.hawkbit.security;
|
|||||||
*
|
*
|
||||||
* @see DdiSecurityProperties
|
* @see DdiSecurityProperties
|
||||||
*/
|
*/
|
||||||
public class ControllerPreAuthenticatedAnonymousFilter implements PreAuthentificationFilter {
|
public class ControllerPreAuthenticatedAnonymousFilter implements PreAuthenticationFilter {
|
||||||
|
|
||||||
private final DdiSecurityProperties ddiSecurityConfiguration;
|
private final DdiSecurityProperties ddiSecurityConfiguration;
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.security.authentication.AuthenticationProvider;
|
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.authentication.InsufficientAuthenticationException;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
|
||||||
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
|
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -91,19 +89,17 @@ public class PreAuthTokenSourceTrustAuthenticationProvider implements Authentica
|
|||||||
final Object credentials = token.getCredentials();
|
final Object credentials = token.getCredentials();
|
||||||
final Object principal = token.getPrincipal();
|
final Object principal = token.getPrincipal();
|
||||||
final Object tokenDetails = token.getDetails();
|
final Object tokenDetails = token.getDetails();
|
||||||
|
final Collection<GrantedAuthority> authorities = token.getAuthorities();
|
||||||
|
|
||||||
if (principal == null) {
|
if (principal == null) {
|
||||||
throw new BadCredentialsException("The provided principal and credentials are not match");
|
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) {
|
if (successAuthentication) {
|
||||||
final Collection<GrantedAuthority> controllerAuthorities = new ArrayList<>();
|
|
||||||
controllerAuthorities.add(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE));
|
|
||||||
controllerAuthorities.add(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_DOWNLOAD_ROLE));
|
|
||||||
final PreAuthenticatedAuthenticationToken successToken = new PreAuthenticatedAuthenticationToken(principal,
|
final PreAuthenticatedAuthenticationToken successToken = new PreAuthenticatedAuthenticationToken(principal,
|
||||||
credentials, controllerAuthorities);
|
credentials, authorities);
|
||||||
successToken.setDetails(tokenDetails);
|
successToken.setDetails(tokenDetails);
|
||||||
return successToken;
|
return successToken;
|
||||||
}
|
}
|
||||||
@@ -132,7 +128,8 @@ public class PreAuthTokenSourceTrustAuthenticationProvider implements Authentica
|
|||||||
* @return <code>true</code> if authentication succeeded, otherwise
|
* @return <code>true</code> if authentication succeeded, otherwise
|
||||||
* <code>false</code>
|
* <code>false</code>
|
||||||
*/
|
*/
|
||||||
private boolean calculateAuthenticationSuccess(Object principal, Object credentials, Object tokenDetails) {
|
private boolean calculateAuthenticationSuccess(final Object principal, final Object credentials,
|
||||||
|
final Object tokenDetails) {
|
||||||
boolean successAuthentication = false;
|
boolean successAuthentication = false;
|
||||||
if (credentials instanceof Collection) {
|
if (credentials instanceof Collection) {
|
||||||
final Collection<?> multiValueCredentials = (Collection<?>) credentials;
|
final Collection<?> multiValueCredentials = (Collection<?>) credentials;
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ import org.springframework.security.core.Authentication;
|
|||||||
import org.springframework.security.core.GrantedAuthority;
|
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.
|
* Check if the filter is enabled.
|
||||||
@@ -56,6 +56,6 @@ public class ControllerPreAuthenticatedAnonymousDownloadTest {
|
|||||||
public void successfulAuthenticationAdditionalAuthoritiesForDownload() {
|
public void successfulAuthenticationAdditionalAuthoritiesForDownload() {
|
||||||
assertThat(underTest.getSuccessfulAuthenticationAuthorities())
|
assertThat(underTest.getSuccessfulAuthenticationAuthorities())
|
||||||
.as("Additional authorities should be containing the download anonymous role")
|
.as("Additional authorities should be containing the download anonymous role")
|
||||||
.contains(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_DOWNLOAD_ROLE));
|
.contains(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user