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 class CA {
public static final String DEFAULT_CA_DN = "CN=CA, O=hawkBit, L=Sofia, C=BG"; 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_BEFORE_DAYS_OFFSET = 1;
public static final long DEFAULT_NOT_AFTER_DAYS_OFFSET = 30; 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.Optional;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import feign.Client;
import feign.Contract; import feign.Contract;
import feign.codec.Decoder; import feign.codec.Decoder;
import feign.codec.Encoder; import feign.codec.Encoder;
@@ -87,7 +86,7 @@ public class DeviceApp {
@ShellMethod(key = "setup") @ShellMethod(key = "setup")
public void setup() { public void setup() {
mgmtApi.setupTargetAuthentication(); mgmtApi.setupTargetAuthentication();
mgmtApi.setupTargetToken(device.getController().getControllerId(), device.getTargetSecurityToken()); mgmtApi.setupTargetSecureToken(device.getController().getControllerId(), device.getTargetSecurityToken());
} }
@ShellMethod(key = "start") @ShellMethod(key = "start")

View File

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

View File

@@ -10,6 +10,7 @@
package org.eclipse.hawkbit.sdk.mgmt; package org.eclipse.hawkbit.sdk.mgmt;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.util.Base64; import java.util.Base64;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -55,20 +56,49 @@ public class AuthenticationSetupHelper {
return Base64.getEncoder().encodeToString(rnd); return Base64.getEncoder().encodeToString(rnd);
} }
// if gateway token is configured then the gateway auth is enabled key is set // sets up a certificate authentication, if DdiCA is null - generate self signed CA
// so all devices use gateway token authentication public void setupCertificateAuthentication() throws CertificateException {
// otherwise target token authentication is enabled. Then all devices shall be registered final MgmtTenantManagementRestApi mgmtTenantManagementRestApi = hawkbitClient.mgmtService(MgmtTenantManagementRestApi.class, tenant);
// and the target token shall be set to the one from the DDI controller instance CA ddiCA = tenant.getDdiCA();
public void setupTargetAuthentication() { 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); final MgmtTenantManagementRestApi mgmtTenantManagementRestApi = hawkbitClient.mgmtService(MgmtTenantManagementRestApi.class, tenant);
final String gatewayToken = tenant.getGatewayToken();
if (ObjectUtils.isEmpty(gatewayToken)) {
if (!(Boolean.TRUE.equals(Objects.requireNonNull(mgmtTenantManagementRestApi if (!(Boolean.TRUE.equals(Objects.requireNonNull(mgmtTenantManagementRestApi
.getTenantConfigurationValue(AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED) .getTenantConfigurationValue(AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED)
.getBody()).getValue()))) { .getBody()).getValue()))) {
mgmtTenantManagementRestApi.updateTenantConfiguration(Map.of(AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED, true)); mgmtTenantManagementRestApi.updateTenantConfiguration(Map.of(AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED, true));
} }
} else { }
// set gateway token authentication (generate and sets gateway token to tenant, if not set up)
// return the gateway token
public void setupGatewayTokenAuthentication() {
String gatewayToken = tenant.getGatewayToken();
if (ObjectUtils.isEmpty(gatewayToken)) {
gatewayToken = randomToken();
tenant.setGatewayToken(gatewayToken);
}
final MgmtTenantManagementRestApi mgmtTenantManagementRestApi = hawkbitClient.mgmtService(MgmtTenantManagementRestApi.class, tenant);
if (!(Boolean.TRUE.equals(Objects.requireNonNull(mgmtTenantManagementRestApi if (!(Boolean.TRUE.equals(Objects.requireNonNull(mgmtTenantManagementRestApi
.getTenantConfigurationValue(AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED) .getTenantConfigurationValue(AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED)
.getBody()).getValue()))) { .getBody()).getValue()))) {
@@ -81,23 +111,22 @@ public class AuthenticationSetupHelper {
mgmtTenantManagementRestApi.updateTenantConfiguration(Map.of(AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY, gatewayToken)); mgmtTenantManagementRestApi.updateTenantConfiguration(Map.of(AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY, gatewayToken));
} }
} }
}
// set gateway token authentication (generate and sets gateway token to tenant, if not set up) // if gateway token is configured then the gateway auth is enabled key is set
// return the gateway token // so all devices use gateway token authentication
public String setupGatewayToken() { // otherwise target token authentication is enabled. Then all devices shall be registered
String gatewayToken = tenant.getGatewayToken(); // 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)) { if (ObjectUtils.isEmpty(gatewayToken)) {
gatewayToken = randomToken(); setupSecureTokenAuthentication();
tenant.setGatewayToken(gatewayToken); } else {
setupGatewayTokenAuthentication();
} }
setupTargetAuthentication();
return gatewayToken;
} }
// sets up a target token and returns it // sets up a target token and returns it. If target has not already been created - creates it
public String setupTargetToken(final String controllerId, String securityTargetToken) { public String setupTargetSecureToken(final String controllerId, String securityTargetToken) {
if (ObjectUtils.isEmpty(tenant.getGatewayToken())) {
final MgmtTargetRestApi mgmtTargetRestApi = hawkbitClient.mgmtService(MgmtTargetRestApi.class, tenant); final MgmtTargetRestApi mgmtTargetRestApi = hawkbitClient.mgmtService(MgmtTargetRestApi.class, tenant);
try { try {
// test if target exist, if not - throws 404 // test if target exist, if not - throws 404
@@ -122,33 +151,7 @@ public class AuthenticationSetupHelper {
mgmtTargetRestApi.createTargets(List.of( mgmtTargetRestApi.createTargets(List.of(
new MgmtTargetRequestBody().setControllerId(controllerId).setSecurityToken(securityTargetToken))); new MgmtTargetRequestBody().setControllerId(controllerId).setSecurityToken(securityTargetToken)));
} }
}
return 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));
}
}
}
} }