diff --git a/docs/authentication.md b/docs/authentication.md index ba17d04b5..fdb6ba1f5 100644 --- a/docs/authentication.md +++ b/docs/authentication.md @@ -118,8 +118,8 @@ server.forward-headers-strategy=NATIVE ``` 2. In Hawkbit's UI section, under system configuration, make sure to select *Allow targets to authenticate via a - certificate authenticated by a reverse proxy* and input the fixed issuer hash as "Hawkbit". This can be whetever you - have configured in the nginx configuration in `proxy_set_header X-Ssl-Issuer-Hash-1` below. + certificate authenticated by a reverse proxy* and input the fixed issuer hash as "Hawkbit". This can be whenever you + have configured in the nginx configuration in `proxy_set_header X-Authority-1` below. 3. After placing your certificates and keys, you need to deploy your proxy server and apply the provided configurations. You can apply mutual TLS specifically to the URL given below to implement the process only for devices using the @@ -184,8 +184,8 @@ server { # Client certificate Common Name and Issuer Hash is required # for auth in hawkbit. - proxy_set_header X-Ssl-Client-Cn $ssl_client_s_dn_cn; - proxy_set_header X-Ssl-Issuer-Hash-1 Hawkbit; + proxy_set_header X-Controller-Id $ssl_client_s_dn_cn; + proxy_set_header X-Authority-1 Hawkbit; # These are required for clients to upload and download software. proxy_request_buffering off; diff --git a/hawkbit-ddi/hawkbit-ddi-security/src/main/java/org/eclipse/hawkbit/security/controller/DdiSecurityProperties.java b/hawkbit-ddi/hawkbit-ddi-security/src/main/java/org/eclipse/hawkbit/security/controller/DdiSecurityProperties.java index 5913170f0..e2021801e 100644 --- a/hawkbit-ddi/hawkbit-ddi-security/src/main/java/org/eclipse/hawkbit/security/controller/DdiSecurityProperties.java +++ b/hawkbit-ddi/hawkbit-ddi-security/src/main/java/org/eclipse/hawkbit/security/controller/DdiSecurityProperties.java @@ -29,14 +29,6 @@ public class DdiSecurityProperties { private final Rp rp = new Rp(); private final Authentication authentication = new Authentication(); - public Authentication getAuthentication() { - return authentication; - } - - public Rp getRp() { - return rp; - } - /** * Reverse proxy configuration. Defines the security properties for * authenticating controllers behind a reverse proxy which terminates the @@ -47,16 +39,19 @@ public class DdiSecurityProperties { public static class Rp { /** - * HTTP header field for common name of a DDI target client certificate. + * HTTP header field for controller ID (e.g. CN of the controller certificate) of a DDI target client certificate. */ - private String cnHeader = "X-Ssl-Client-Cn"; + private String controllerIdHeader = "X-Controller-Id"; /** - * HTTP header field for issuer hash of a DDI target client certificate. + * HTTP header field for authority(ies) (e.g. SHA-256 fingerprints of issuer certificates) of a DDI target client certificate. */ - private String sslIssuerHashHeader = "X-Ssl-Issuer-Hash-%d"; + private String authorityHeader = "X-Authority"; /** - * List of trusted (reverse proxy) IP addresses for performing DDI - * client certificate auth. + * Regular expression for authorities list separator + */ + private String authoritiesSeparatorRegex = "[;,]"; + /** + * List of trusted (reverse proxy) IP addresses for performing DDI client certificate auth. */ private List trustedIPs; } @@ -67,14 +62,14 @@ public class DdiSecurityProperties { @Data public static class Authentication { - private final Targettoken targettoken = new Targettoken(); - private final Gatewaytoken gatewaytoken = new Gatewaytoken(); + private final TargetToken targettoken = new TargetToken(); + private final GatewayToken gatewaytoken = new GatewayToken(); /** * Target token auth. Tokens are defined per target. */ @Data - public static class Targettoken { + public static class TargetToken { /** * Set to true to enable target token auth. @@ -86,7 +81,7 @@ public class DdiSecurityProperties { * Gateway token auth. Tokens are defined per tenant. Use with care! */ @Data - public static class Gatewaytoken { + public static class GatewayToken { /** * Gateway token based authentication enabled. diff --git a/hawkbit-ddi/hawkbit-ddi-security/src/main/java/org/eclipse/hawkbit/security/controller/SecurityHeaderAuthenticator.java b/hawkbit-ddi/hawkbit-ddi-security/src/main/java/org/eclipse/hawkbit/security/controller/SecurityHeaderAuthenticator.java index a90ef9bff..7bc2d154b 100644 --- a/hawkbit-ddi/hawkbit-ddi-security/src/main/java/org/eclipse/hawkbit/security/controller/SecurityHeaderAuthenticator.java +++ b/hawkbit-ddi/hawkbit-ddi-security/src/main/java/org/eclipse/hawkbit/security/controller/SecurityHeaderAuthenticator.java @@ -9,17 +9,17 @@ */ package org.eclipse.hawkbit.security.controller; +import static org.eclipse.hawkbit.audit.SecurityLogger.LOGGER; import static org.eclipse.hawkbit.context.AccessContext.asTenant; -import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.AUTHENTICATION_HEADER_AUTHORITY_NAME; +import static org.eclipse.hawkbit.repository.helper.TenantConfigHelper.getAsSystem; +import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.AUTHENTICATION_HEADER_AUTHORITY; import java.util.Arrays; import java.util.List; import lombok.extern.slf4j.Slf4j; -import org.eclipse.hawkbit.repository.helper.TenantConfigHelper; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey; import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.security.core.Authentication; /** @@ -29,62 +29,46 @@ import org.springframework.security.core.Authentication; @Slf4j public class SecurityHeaderAuthenticator extends Authenticator.AbstractAuthenticator { - private static final Logger LOG_SECURITY_AUTH = LoggerFactory.getLogger("server-security.auth"); + // e.g: X-Controller-Id: controller-1 or X-Subject-CN: controller-1 + private final String controllerIdHeader; + // e.g.: X-Authority: X,Y or X-CA-Fingerprint-0: + // could be used with one or multiple authorities that has confirmed the controller id: + // 1. =X,Y,Z -> comma separated list of authorities (could be single authority) + // 2. -0=X, -1=Y, .. ... until we get a null header + private final String authorityHeader; + private final String authoritiesSeparatorRegex; - // Example Headers with Cert Information - // Clientip: 217.24.201.180 - // X-Forwarded-Proto: https - // X-Ssl-Client-Cn: my.name - // X-Ssl-Client-Dn: CN=my.name,CN=O,CN=R,CN=DE,CN=BOSCH,CN=pki,DC=bosch,DC=com - // X-Ssl-Client-Hash: 7f:87:cb:b5:9c:e0:c5:0a:1a:a6:57:69:0f:ca:0a:95 - // X-Ssl-Client-Notafter: Dec 18 08:02:45 2017 GMT - // X-Ssl-Client-Notbefore: Dec 18 07:32:45 2014 GMT - // X-Ssl-Client-Verify: ok - // X-Ssl-Issuer: CN=Bosch-CA1-DE,CN=PKI,DC=Bosch,DC=com - // X-Ssl-Issuer-Dn-1: CN=Bosch-CA-DE,CN=PKI,DC=Bosch,DC=com - // X-Ssl-Issuer-Hash-1: ae:11:f5:6a:0a:e8:74:50:81:0e:0c:37:ec:c5:22:fc - private final String caCommonNameHeader; - // the X-Ssl-Issuer-Hash basic header: Contains the x509 fingerprint hash, this - // header exists multiple times in the request for all trusted chains. - private final String sslIssuerHashBasicHeader; - - public SecurityHeaderAuthenticator(final String caCommonNameHeader, final String caAuthorityNameHeader) { - this.caCommonNameHeader = caCommonNameHeader; - this.sslIssuerHashBasicHeader = caAuthorityNameHeader; + public SecurityHeaderAuthenticator(final DdiSecurityProperties.Rp rp) { + this.controllerIdHeader = rp.getControllerIdHeader(); + this.authorityHeader = rp.getAuthorityHeader(); + this.authoritiesSeparatorRegex = rp.getAuthoritiesSeparatorRegex(); } @Override public Authentication authenticate(final ControllerSecurityToken controllerSecurityToken) { // retrieve the common name header and the authority name header from the http request and combine them together - final String commonNameValue = controllerSecurityToken.getHeader(caCommonNameHeader); - if (commonNameValue == null) { - log.debug("The request doesn't contain the 'common name' header"); + final String verifiedControllerId = controllerSecurityToken.getHeader(controllerIdHeader); + if (verifiedControllerId == null) { + log.debug("The request doesn't contain the '{}' header", controllerIdHeader); return null; } - if (!commonNameValue.equals(controllerSecurityToken.getControllerId())) { - log.debug("The request contains the 'common name' header but it doesn't match the controller id"); + if (!verifiedControllerId.equals(controllerSecurityToken.getControllerId())) { + log.debug("The request contains the '{}' header but it doesn't match the controller id", controllerIdHeader); return null; } - if (!isEnabled(controllerSecurityToken)) { + if (!isEnabled(controllerSecurityToken)) { // in order to do not do calls to db - check after previous header checks log.debug("The gateway header authentication is disabled"); return null; } - final String sslIssuerHashValue = getIssuerHashHeader( - controllerSecurityToken, - asTenant( - controllerSecurityToken.getTenant(), - () -> TenantConfigHelper.getAsSystem(AUTHENTICATION_HEADER_AUTHORITY_NAME, String.class))); - if (sslIssuerHashValue == null) { - log.debug("The request contains the 'common name' header but trusted hash is not found"); + final String tenant = controllerSecurityToken.getTenant(); + if (verify(controllerSecurityToken, asTenant(tenant, () -> getAsSystem(AUTHENTICATION_HEADER_AUTHORITY, String.class)))) { + log.trace("Found trusted authority ****, using as credentials (tenant: {})", tenant); + return authenticatedController(tenant, verifiedControllerId); + } else { return null; } - if (log.isTraceEnabled()) { - log.debug("Found sslIssuerHash ****, using as credentials for tenant {}", controllerSecurityToken.getTenant()); - } - - return authenticatedController(controllerSecurityToken.getTenant(), commonNameValue); } @Override @@ -98,28 +82,52 @@ public class SecurityHeaderAuthenticator extends Authenticator.AbstractAuthentic } /** - * Iterates over the {@link #sslIssuerHashBasicHeader} basic header {@code X-Ssl-Issuer-Hash-%d} and try to find the same hash as known. - * It's ok if we find the hash in any the trusted CA chain to accept this request for this tenant. + * Check {@link #authorityHeader} basic header or iterates over {@link #authorityHeader}-%d and try to find the same authority as trusted. + * It's ok if we find any authority (in headers, authenticated the controller) to accept this request for this tenant. */ - @SuppressWarnings("java:S2629") // check if debug is enabled is maybe heavier then evaluation - private String getIssuerHashHeader(final ControllerSecurityToken controllerSecurityToken, final String knownIssuerHashes) { - // there may be several knownIssuerHashes configured for the tenant - final List knownHashes = Arrays.stream(knownIssuerHashes.split("[;,]")).map(String::toLowerCase).toList(); + @SuppressWarnings({ "java:S2629", "java:S135", "java:S3776" }) // check if debug is enabled is maybe heavier than evaluation, rest - fine + private boolean verify(final ControllerSecurityToken controllerSecurityToken, final String headerAuthority) { + // there may be several trusted authorities (headerAuthority config value) configured for the tenant + final List trustedAuthorities = Arrays.stream(headerAuthority.split(authoritiesSeparatorRegex)) + .map(String::toLowerCase).map(String::trim).toList(); - // iterate over the headers until we get a null header. - String foundHash; - for (int iHeader = 1; (foundHash = controllerSecurityToken.getHeader( - String.format(sslIssuerHashBasicHeader, iHeader))) != null; iHeader++) { - if (knownHashes.contains(foundHash.toLowerCase())) { - if (log.isTraceEnabled()) { - log.trace("Found matching ssl issuer hash at position {}", iHeader); + boolean hasAuthorityHeader = false; + String matchingAuthority = null; + + final String authorityHeaderValue = controllerSecurityToken.getHeader(authorityHeader); + if (authorityHeaderValue == null) { + // go for authority header prefixed iteration. iterate over the headers until we get a null header. Start from index 0 or 1 + for (int i = 0; ; i++) { + final String authority = controllerSecurityToken.getHeader(authorityHeader + "-" + i); + if (authority == null) { + if (i != 0) { + break; // end of index iteration + } // if 0, try if start from 1 + } else { + hasAuthorityHeader = true; + final String authorityLower = authority.toLowerCase(); + if (trustedAuthorities.contains(authorityLower)) { + matchingAuthority = authorityLower; + break; + } } - return foundHash.toLowerCase(); } + } else { + hasAuthorityHeader = true; + matchingAuthority = Arrays.stream(authorityHeaderValue.split(authoritiesSeparatorRegex)) + .map(String::toLowerCase).map(String::trim) + .filter(trustedAuthorities::contains) + .findFirst().orElse(null); } - LOG_SECURITY_AUTH.debug( - "Certificate request but no matching hash found in headers {} for common name {} in request", - sslIssuerHashBasicHeader, controllerSecurityToken.getHeader(caCommonNameHeader)); - return null; + + if (matchingAuthority == null) { + if (hasAuthorityHeader) { + LOGGER.debug("[SEC_HEADER_AUTH] Request has an authority header(s) but it doesn't match any trusted authority"); + } + } else if (log.isTraceEnabled()) { + log.trace("Found matching authority {}", matchingAuthority); + } + + return matchingAuthority != null; } } \ No newline at end of file diff --git a/hawkbit-ddi/hawkbit-ddi-security/src/test/java/org/eclipse/hawkbit/security/controller/SecurityHeaderAuthenticatorTest.java b/hawkbit-ddi/hawkbit-ddi-security/src/test/java/org/eclipse/hawkbit/security/controller/SecurityHeaderAuthenticatorTest.java index d77b64d53..79fde36c7 100644 --- a/hawkbit-ddi/hawkbit-ddi-security/src/test/java/org/eclipse/hawkbit/security/controller/SecurityHeaderAuthenticatorTest.java +++ b/hawkbit-ddi/hawkbit-ddi-security/src/test/java/org/eclipse/hawkbit/security/controller/SecurityHeaderAuthenticatorTest.java @@ -10,7 +10,7 @@ package org.eclipse.hawkbit.security.controller; import static org.assertj.core.api.Assertions.assertThat; -import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.AUTHENTICATION_HEADER_AUTHORITY_NAME; +import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.AUTHENTICATION_HEADER_AUTHORITY; import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.AUTHENTICATION_HEADER_ENABLED; import static org.mockito.Mockito.when; @@ -33,23 +33,23 @@ class SecurityHeaderAuthenticatorTest { private static final String CA_COMMON_NAME = "ca-cn"; private static final String CA_COMMON_NAME_VALUE = "box1"; - private static final String X_SSL_ISSUER_HASH_1 = "X-Ssl-Issuer-Hash-1"; + private static final String X_AUTHORITY_1 = "X-Authority-1"; - private static final String SINGLE_HASH = "hash1"; - private static final String SECOND_HASH = "hash2"; - private static final String THIRD_HASH = "hash3"; - private static final String UNKNOWN_HASH = "unknown"; + private static final String SINGLE_AUTHORITY = "hash1"; + private static final String SECOND_AUTHORITY = "hash2"; + private static final String THIRD_AUTHORITY = "hash3"; + private static final String UNKNOWN_AUTHORITY = "unknown"; - private static final String MULTI_HASH = "HASH1;hash2,HASH3,HASH1"; + private static final String MULTI_AUTHORITY = "HASH1;hash2,HASH3,HASH1"; - private static final TenantConfigurationValue CONFIG_VALUE_SINGLE_HASH = TenantConfigurationValue - . builder().value(SINGLE_HASH).build(); - private static final TenantConfigurationValue CONFIG_VALUE_MULTI_HASH = TenantConfigurationValue - . builder().value(MULTI_HASH).build(); - private static final TenantConfigurationValue CONFIG_VALUE_ENABLED = TenantConfigurationValue - . builder().value(true).build(); - private static final TenantConfigurationValue CONFIG_VALUE_DISABLED = TenantConfigurationValue - . builder().value(false).build(); + private static final TenantConfigurationValue CONFIG_VALUE_SINGLE_AUTHORITY = TenantConfigurationValue. builder() + .value(SINGLE_AUTHORITY).build(); + private static final TenantConfigurationValue CONFIG_VALUE_MULTI_AUTHORITY = TenantConfigurationValue. builder() + .value(MULTI_AUTHORITY).build(); + private static final TenantConfigurationValue CONFIG_VALUE_ENABLED = TenantConfigurationValue. builder() + .value(true).build(); + private static final TenantConfigurationValue CONFIG_VALUE_DISABLED = TenantConfigurationValue. builder() + .value(false).build(); private Authenticator authenticator; @@ -59,17 +59,19 @@ class SecurityHeaderAuthenticatorTest { @BeforeEach void before() { TenantConfigHelper.setTenantConfigurationManagement(tenantConfigurationManagementMock); - authenticator = new SecurityHeaderAuthenticator(CA_COMMON_NAME, "X-Ssl-Issuer-Hash-%d"); + final DdiSecurityProperties.Rp rp = new DdiSecurityProperties.Rp(); + rp.setControllerIdHeader(CA_COMMON_NAME); + authenticator = new SecurityHeaderAuthenticator(rp); } /** * Tests successful authentication with multiple a single hashes */ @Test - void testWithSingleKnownHash() { - final ControllerSecurityToken securityToken = prepareSecurityToken(SINGLE_HASH); - when(tenantConfigurationManagementMock.getConfigurationValue(AUTHENTICATION_HEADER_AUTHORITY_NAME, String.class)) - .thenReturn(CONFIG_VALUE_SINGLE_HASH); + void testWithSingleTrustedAuthority() { + final ControllerSecurityToken securityToken = prepareSecurityToken(SINGLE_AUTHORITY); + when(tenantConfigurationManagementMock.getConfigurationValue(AUTHENTICATION_HEADER_AUTHORITY, String.class)) + .thenReturn(CONFIG_VALUE_SINGLE_AUTHORITY); when(tenantConfigurationManagementMock.getConfigurationValue(AUTHENTICATION_HEADER_ENABLED, Boolean.class)) .thenReturn(CONFIG_VALUE_ENABLED); @@ -82,19 +84,19 @@ class SecurityHeaderAuthenticatorTest { * Tests successful authentication with multiple hashes */ @Test - void testWithMultipleKnownHashes() { - when(tenantConfigurationManagementMock.getConfigurationValue(AUTHENTICATION_HEADER_AUTHORITY_NAME, String.class)) - .thenReturn(CONFIG_VALUE_MULTI_HASH); + void testWithMultipleTrustedAuthority() { + when(tenantConfigurationManagementMock.getConfigurationValue(AUTHENTICATION_HEADER_AUTHORITY, String.class)) + .thenReturn(CONFIG_VALUE_MULTI_AUTHORITY); when(tenantConfigurationManagementMock.getConfigurationValue(AUTHENTICATION_HEADER_ENABLED, Boolean.class)) .thenReturn(CONFIG_VALUE_ENABLED); - assertThat(authenticator.authenticate(prepareSecurityToken(SINGLE_HASH))) + assertThat(authenticator.authenticate(prepareSecurityToken(SINGLE_AUTHORITY))) .isNotNull() .hasFieldOrPropertyWithValue("principal", CA_COMMON_NAME_VALUE); - assertThat(authenticator.authenticate(prepareSecurityToken(SECOND_HASH))) + assertThat(authenticator.authenticate(prepareSecurityToken(SECOND_AUTHORITY))) .isNotNull() .hasFieldOrPropertyWithValue("principal", CA_COMMON_NAME_VALUE); - assertThat(authenticator.authenticate(prepareSecurityToken(THIRD_HASH))) + assertThat(authenticator.authenticate(prepareSecurityToken(THIRD_AUTHORITY))) .isNotNull() .hasFieldOrPropertyWithValue("principal", CA_COMMON_NAME_VALUE); } @@ -103,10 +105,10 @@ class SecurityHeaderAuthenticatorTest { * Tests that if the hash is unknown, the authentication fails */ @Test - void testWithUnknownHash() { - final ControllerSecurityToken securityToken = prepareSecurityToken(UNKNOWN_HASH); - when(tenantConfigurationManagementMock.getConfigurationValue(AUTHENTICATION_HEADER_AUTHORITY_NAME, String.class)) - .thenReturn(CONFIG_VALUE_MULTI_HASH); + void testWithUnTrustedAuthority() { + final ControllerSecurityToken securityToken = prepareSecurityToken(UNKNOWN_AUTHORITY); + when(tenantConfigurationManagementMock.getConfigurationValue(AUTHENTICATION_HEADER_AUTHORITY, String.class)) + .thenReturn(CONFIG_VALUE_MULTI_AUTHORITY); when(tenantConfigurationManagementMock.getConfigurationValue(AUTHENTICATION_HEADER_ENABLED, Boolean.class)) .thenReturn(CONFIG_VALUE_ENABLED); @@ -120,7 +122,7 @@ class SecurityHeaderAuthenticatorTest { void testWithNonMatchingCN() { final ControllerSecurityToken securityToken = new ControllerSecurityToken("DEFAULT", "otherControllerID"); securityToken.putHeader(CA_COMMON_NAME, CA_COMMON_NAME_VALUE); - securityToken.putHeader(X_SSL_ISSUER_HASH_1, SINGLE_HASH); + securityToken.putHeader(X_AUTHORITY_1, SINGLE_AUTHORITY); assertThat(authenticator.authenticate(securityToken)).isNull(); } @@ -137,10 +139,9 @@ class SecurityHeaderAuthenticatorTest { * Tests that if disabled, the authentication fails */ @Test - void testWithSingleKnownHashButDisabled() { - final ControllerSecurityToken securityToken = prepareSecurityToken(SINGLE_HASH); - when(tenantConfigurationManagementMock.getConfigurationValue(AUTHENTICATION_HEADER_ENABLED, Boolean.class)) - .thenReturn(CONFIG_VALUE_DISABLED); + void testWithSingleTrustedAuthorityButDisabled() { + final ControllerSecurityToken securityToken = prepareSecurityToken(SINGLE_AUTHORITY); + when(tenantConfigurationManagementMock.getConfigurationValue(AUTHENTICATION_HEADER_ENABLED, Boolean.class)).thenReturn(CONFIG_VALUE_DISABLED); assertThat(authenticator.authenticate(securityToken)).isNull(); } @@ -148,7 +149,7 @@ class SecurityHeaderAuthenticatorTest { private static ControllerSecurityToken prepareSecurityToken(final String issuerHashHeaderValue) { final ControllerSecurityToken securityToken = new ControllerSecurityToken("DEFAULT", CA_COMMON_NAME_VALUE); securityToken.putHeader(CA_COMMON_NAME, CA_COMMON_NAME_VALUE); - securityToken.putHeader(X_SSL_ISSUER_HASH_1, issuerHashHeaderValue); + securityToken.putHeader(X_AUTHORITY_1, issuerHashHeaderValue); return securityToken; } } \ No newline at end of file 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 index 92c93b799..1ec0ab29d 100644 --- 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 @@ -83,8 +83,7 @@ class ControllerDownloadSecurityConfiguration { .anonymous(AbstractHttpConfigurer::disable) .csrf(AbstractHttpConfigurer::disable) .addFilterBefore(new AuthenticationFilters.SecurityHeaderAuthenticationFilter( - new SecurityHeaderAuthenticator( - ddiSecurityConfiguration.getRp().getCnHeader(), ddiSecurityConfiguration.getRp().getSslIssuerHashHeader()), + new SecurityHeaderAuthenticator(ddiSecurityConfiguration.getRp()), ddiSecurityConfiguration), AuthorizationFilter.class) .addFilterBefore(new AuthenticationFilters.SecurityTokenAuthenticationFilter( new SecurityTokenAuthenticator(controllerManagement), 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 index 80b20d2b2..67892b9d0 100644 --- 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 @@ -91,9 +91,7 @@ class ControllerSecurityConfiguration { .csrf(AbstractHttpConfigurer::disable) .addFilterBefore( new AuthenticationFilters.SecurityHeaderAuthenticationFilter( - new SecurityHeaderAuthenticator( - ddiSecurityConfiguration.getRp().getCnHeader(), - ddiSecurityConfiguration.getRp().getSslIssuerHashHeader()), ddiSecurityConfiguration), + new SecurityHeaderAuthenticator(ddiSecurityConfiguration.getRp()), ddiSecurityConfiguration), AuthorizationFilter.class) .addFilterBefore( new AuthenticationFilters.SecurityTokenAuthenticationFilter( diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationProperties.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationProperties.java index db9697920..4c20ee588 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationProperties.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationProperties.java @@ -69,9 +69,9 @@ public class TenantConfigurationProperties { */ public static final String AUTHENTICATION_HEADER_ENABLED = "authentication.header.enabled"; /** - * Header based authentication authority name. + * Header based authentication authority(-ies, could be list). */ - public static final String AUTHENTICATION_HEADER_AUTHORITY_NAME = "authentication.header.authority"; + public static final String AUTHENTICATION_HEADER_AUTHORITY = "authentication.header.authority"; /** * Target token based authentication enabled. */ diff --git a/hawkbit-repository/hawkbit-repository-jpa-init/src/main/java/org/eclipse/hawkbit/repository/jpa/init/HawkbitFlywayDbInit.java b/hawkbit-repository/hawkbit-repository-jpa-init/src/main/java/org/eclipse/hawkbit/repository/jpa/init/HawkbitFlywayDbInit.java index f1b9c2b15..b9b87b433 100644 --- a/hawkbit-repository/hawkbit-repository-jpa-init/src/main/java/org/eclipse/hawkbit/repository/jpa/init/HawkbitFlywayDbInit.java +++ b/hawkbit-repository/hawkbit-repository-jpa-init/src/main/java/org/eclipse/hawkbit/repository/jpa/init/HawkbitFlywayDbInit.java @@ -90,7 +90,7 @@ public class HawkbitFlywayDbInit { log.info("Start ({}): {}@{}, table: {}, locations: {}, sql-migration-suffixes: {}", MODE, USER, URL, TABLE, LOCATIONS, SQL_MIGRATION_SUFFIXES); - // configured via system properties callbacks are with prority. If not confiured - try to load via service loader + // configured via system properties callbacks are with priority. If not configured - try to load via service loader final Callback[] callbackViaServiceLoader = CALLBACKS.length == 0 ? ServiceLoader.load(Callback.class).stream() .map(ServiceLoader.Provider::get) .toArray(Callback[]::new) : new Callback[0];