SDK: Improve authentication setup (#2272)

Signed-off-by: Avgustin Marinov <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2025-02-13 09:05:02 +02:00
committed by GitHub
parent 97027de9a8
commit 91bf70626c
4 changed files with 82 additions and 80 deletions

View File

@@ -35,6 +35,7 @@ import org.eclipse.hawkbit.sdk.Certificate;
public class CA {
public static final String DEFAULT_CA_DN = "CN=CA, O=hawkBit, L=Sofia, C=BG";
public static final String DEFAULT_INTERMEDIATE_CA_DN = "CN=Intermediate, O=hawkBit, L=Sofia, C=BG";
public static final long DEFAULT_NOT_BEFORE_DAYS_OFFSET = 1;
public static final long DEFAULT_NOT_AFTER_DAYS_OFFSET = 30;

View File

@@ -12,7 +12,6 @@ package org.eclipse.hawkbit.sdk.demo.device;
import java.util.Optional;
import java.util.concurrent.Executors;
import feign.Client;
import feign.Contract;
import feign.codec.Decoder;
import feign.codec.Encoder;
@@ -87,7 +86,7 @@ public class DeviceApp {
@ShellMethod(key = "setup")
public void setup() {
mgmtApi.setupTargetAuthentication();
mgmtApi.setupTargetToken(device.getController().getControllerId(), device.getTargetSecurityToken());
mgmtApi.setupTargetSecureToken(device.getController().getControllerId(), device.getTargetSecurityToken());
}
@ShellMethod(key = "start")

View File

@@ -12,7 +12,6 @@ package org.eclipse.hawkbit.sdk.demo.multidevice;
import java.util.Optional;
import java.util.concurrent.Executors;
import feign.Client;
import feign.Contract;
import feign.codec.Decoder;
import feign.codec.Encoder;
@@ -85,7 +84,7 @@ public class MultiDeviceApp {
public void startOne(@ShellOption("--id") final String controllerId) {
final String securityTargetToken;
if (setup) {
securityTargetToken = mgmtApi.setupTargetToken(controllerId, null);
securityTargetToken = mgmtApi.setupTargetSecureToken(controllerId, null);
} else {
securityTargetToken = null;
}

View File

@@ -10,6 +10,7 @@
package org.eclipse.hawkbit.sdk.mgmt;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.util.Base64;
import java.util.List;
import java.util.Map;
@@ -55,100 +56,102 @@ public class AuthenticationSetupHelper {
return Base64.getEncoder().encodeToString(rnd);
}
// if gateway token is configured then the gateway auth is enabled key is set
// so all devices use gateway token authentication
// otherwise target token authentication is enabled. Then all devices shall be registered
// and the target token shall be set to the one from the DDI controller instance
public void setupTargetAuthentication() {
// sets up a certificate authentication, if DdiCA is null - generate self signed CA
public void setupCertificateAuthentication() throws CertificateException {
final MgmtTenantManagementRestApi mgmtTenantManagementRestApi = hawkbitClient.mgmtService(MgmtTenantManagementRestApi.class, tenant);
final String gatewayToken = tenant.getGatewayToken();
if (ObjectUtils.isEmpty(gatewayToken)) {
if (!(Boolean.TRUE.equals(Objects.requireNonNull(mgmtTenantManagementRestApi
.getTenantConfigurationValue(AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED)
.getBody()).getValue()))) {
mgmtTenantManagementRestApi.updateTenantConfiguration(Map.of(AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED, true));
}
} else {
if (!(Boolean.TRUE.equals(Objects.requireNonNull(mgmtTenantManagementRestApi
.getTenantConfigurationValue(AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED)
.getBody()).getValue()))) {
mgmtTenantManagementRestApi.updateTenantConfiguration(Map.of(AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED, true));
}
if (!gatewayToken.equals(
Objects.requireNonNull(mgmtTenantManagementRestApi
.getTenantConfigurationValue(AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY)
.getBody()).getValue())) {
mgmtTenantManagementRestApi.updateTenantConfiguration(Map.of(AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY, gatewayToken));
}
CA ddiCA = tenant.getDdiCA();
if (ddiCA == null) {
final CA ddiRootCA = new CA();
ddiCA = new CA(ddiRootCA.issue(CA.DEFAULT_INTERMEDIATE_CA_DN, null, null));
tenant.setDdiCA(ddiCA);
}
if (!Boolean.TRUE.equals(Objects.requireNonNull(mgmtTenantManagementRestApi
.getTenantConfigurationValue(AUTHENTICATION_MODE_HEADER_ENABLED)
.getBody()).getValue())) {
mgmtTenantManagementRestApi.updateTenantConfiguration(Map.of(AUTHENTICATION_MODE_HEADER_ENABLED, true));
}
final String fingerprint = ddiCA.getFingerprint();
if (!fingerprint.equals(
Objects.requireNonNull(mgmtTenantManagementRestApi
.getTenantConfigurationValue(AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME)
.getBody()).getValue())) {
mgmtTenantManagementRestApi.updateTenantConfiguration(Map.of(AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME, fingerprint));
}
}
// enables secure token authentication
public void setupSecureTokenAuthentication() {
final MgmtTenantManagementRestApi mgmtTenantManagementRestApi = hawkbitClient.mgmtService(MgmtTenantManagementRestApi.class, tenant);
if (!(Boolean.TRUE.equals(Objects.requireNonNull(mgmtTenantManagementRestApi
.getTenantConfigurationValue(AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED)
.getBody()).getValue()))) {
mgmtTenantManagementRestApi.updateTenantConfiguration(Map.of(AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED, true));
}
}
// set gateway token authentication (generate and sets gateway token to tenant, if not set up)
// return the gateway token
public String setupGatewayToken() {
public void setupGatewayTokenAuthentication() {
String gatewayToken = tenant.getGatewayToken();
if (ObjectUtils.isEmpty(gatewayToken)) {
gatewayToken = randomToken();
tenant.setGatewayToken(gatewayToken);
}
setupTargetAuthentication();
return gatewayToken;
final MgmtTenantManagementRestApi mgmtTenantManagementRestApi = hawkbitClient.mgmtService(MgmtTenantManagementRestApi.class, tenant);
if (!(Boolean.TRUE.equals(Objects.requireNonNull(mgmtTenantManagementRestApi
.getTenantConfigurationValue(AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED)
.getBody()).getValue()))) {
mgmtTenantManagementRestApi.updateTenantConfiguration(Map.of(AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED, true));
}
if (!gatewayToken.equals(
Objects.requireNonNull(mgmtTenantManagementRestApi
.getTenantConfigurationValue(AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY)
.getBody()).getValue())) {
mgmtTenantManagementRestApi.updateTenantConfiguration(Map.of(AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY, gatewayToken));
}
}
// sets up a target token and returns it
public String setupTargetToken(final String controllerId, String securityTargetToken) {
if (ObjectUtils.isEmpty(tenant.getGatewayToken())) {
final MgmtTargetRestApi mgmtTargetRestApi = hawkbitClient.mgmtService(MgmtTargetRestApi.class, tenant);
try {
// test if target exist, if not - throws 404
final MgmtTarget target = Objects.requireNonNull(mgmtTargetRestApi.getTarget(controllerId).getBody());
if (ObjectUtils.isEmpty(securityTargetToken)) {
if (ObjectUtils.isEmpty(target.getSecurityToken())) {
// generate random to set to tha existing target without configured security token
securityTargetToken = randomToken();
mgmtTargetRestApi.updateTarget(controllerId, new MgmtTargetRequestBody().setSecurityToken(securityTargetToken));
} else {
securityTargetToken = target.getSecurityToken();
}
} else if (!securityTargetToken.equals(target.getSecurityToken())) {
// update target's with the security token (since it doesn't match)
mgmtTargetRestApi.updateTarget(controllerId, new MgmtTargetRequestBody().setSecurityToken(securityTargetToken));
}
} catch (final FeignException.NotFound e) {
if (ObjectUtils.isEmpty(securityTargetToken)) {
// if gateway token is configured then the gateway auth is enabled key is set
// so all devices use gateway token authentication
// otherwise target token authentication is enabled. Then all devices shall be registered
// and the target token shall be set to the one from the DDI controller instance
public void setupTargetAuthentication() {
final String gatewayToken = tenant.getGatewayToken();
if (ObjectUtils.isEmpty(gatewayToken)) {
setupSecureTokenAuthentication();
} else {
setupGatewayTokenAuthentication();
}
}
// sets up a target token and returns it. If target has not already been created - creates it
public String setupTargetSecureToken(final String controllerId, String securityTargetToken) {
final MgmtTargetRestApi mgmtTargetRestApi = hawkbitClient.mgmtService(MgmtTargetRestApi.class, tenant);
try {
// test if target exist, if not - throws 404
final MgmtTarget target = Objects.requireNonNull(mgmtTargetRestApi.getTarget(controllerId).getBody());
if (ObjectUtils.isEmpty(securityTargetToken)) {
if (ObjectUtils.isEmpty(target.getSecurityToken())) {
// generate random to set to tha existing target without configured security token
securityTargetToken = randomToken();
mgmtTargetRestApi.updateTarget(controllerId, new MgmtTargetRequestBody().setSecurityToken(securityTargetToken));
} else {
securityTargetToken = target.getSecurityToken();
}
// create target with the security token
mgmtTargetRestApi.createTargets(List.of(
new MgmtTargetRequestBody().setControllerId(controllerId).setSecurityToken(securityTargetToken)));
} else if (!securityTargetToken.equals(target.getSecurityToken())) {
// update target's with the security token (since it doesn't match)
mgmtTargetRestApi.updateTarget(controllerId, new MgmtTargetRequestBody().setSecurityToken(securityTargetToken));
}
} catch (final FeignException.NotFound e) {
if (ObjectUtils.isEmpty(securityTargetToken)) {
securityTargetToken = randomToken();
}
// create target with the security token
mgmtTargetRestApi.createTargets(List.of(
new MgmtTargetRequestBody().setControllerId(controllerId).setSecurityToken(securityTargetToken)));
}
return securityTargetToken;
}
// sets up a target token and returns it
public void setupCertificateFingerprint() {
final MgmtTenantManagementRestApi mgmtTenantManagementRestApi = hawkbitClient.mgmtService(MgmtTenantManagementRestApi.class, tenant);
final CA ddiCA = tenant.getDdiCA();
final Object enabled = Objects.requireNonNull(mgmtTenantManagementRestApi
.getTenantConfigurationValue(AUTHENTICATION_MODE_HEADER_ENABLED)
.getBody()).getValue();
if (ddiCA == null) {
if (Boolean.TRUE.equals(enabled)) {
mgmtTenantManagementRestApi.updateTenantConfiguration(Map.of(AUTHENTICATION_MODE_HEADER_ENABLED, false));
}
} else {
if (!Boolean.TRUE.equals(enabled)) {
mgmtTenantManagementRestApi.updateTenantConfiguration(Map.of(AUTHENTICATION_MODE_HEADER_ENABLED, true));
}
final String fingerprint = ddiCA.getFingerprint();
if (!fingerprint.equals(
Objects.requireNonNull(mgmtTenantManagementRestApi
.getTenantConfigurationValue(AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME)
.getBody()).getValue())) {
mgmtTenantManagementRestApi.updateTenantConfiguration(Map.of(AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME, fingerprint));
}
}
}
}