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,100 +56,102 @@ 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
// and the target token shall be set to the one from the DDI controller instance
public void setupTargetAuthentication() {
final MgmtTenantManagementRestApi mgmtTenantManagementRestApi = hawkbitClient.mgmtService(MgmtTenantManagementRestApi.class, tenant); final MgmtTenantManagementRestApi mgmtTenantManagementRestApi = hawkbitClient.mgmtService(MgmtTenantManagementRestApi.class, tenant);
final String gatewayToken = tenant.getGatewayToken(); CA ddiCA = tenant.getDdiCA();
if (ObjectUtils.isEmpty(gatewayToken)) { if (ddiCA == null) {
if (!(Boolean.TRUE.equals(Objects.requireNonNull(mgmtTenantManagementRestApi final CA ddiRootCA = new CA();
.getTenantConfigurationValue(AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED) ddiCA = new CA(ddiRootCA.issue(CA.DEFAULT_INTERMEDIATE_CA_DN, null, null));
.getBody()).getValue()))) { tenant.setDdiCA(ddiCA);
mgmtTenantManagementRestApi.updateTenantConfiguration(Map.of(AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED, true)); }
} if (!Boolean.TRUE.equals(Objects.requireNonNull(mgmtTenantManagementRestApi
} else { .getTenantConfigurationValue(AUTHENTICATION_MODE_HEADER_ENABLED)
if (!(Boolean.TRUE.equals(Objects.requireNonNull(mgmtTenantManagementRestApi .getBody()).getValue())) {
.getTenantConfigurationValue(AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED) mgmtTenantManagementRestApi.updateTenantConfiguration(Map.of(AUTHENTICATION_MODE_HEADER_ENABLED, true));
.getBody()).getValue()))) { }
mgmtTenantManagementRestApi.updateTenantConfiguration(Map.of(AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED, true)); final String fingerprint = ddiCA.getFingerprint();
} if (!fingerprint.equals(
if (!gatewayToken.equals( Objects.requireNonNull(mgmtTenantManagementRestApi
Objects.requireNonNull(mgmtTenantManagementRestApi .getTenantConfigurationValue(AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME)
.getTenantConfigurationValue(AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY) .getBody()).getValue())) {
.getBody()).getValue())) { mgmtTenantManagementRestApi.updateTenantConfiguration(Map.of(AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME, fingerprint));
mgmtTenantManagementRestApi.updateTenantConfiguration(Map.of(AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY, gatewayToken)); }
} }
// 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) // set gateway token authentication (generate and sets gateway token to tenant, if not set up)
// return the gateway token // return the gateway token
public String setupGatewayToken() { public void setupGatewayTokenAuthentication() {
String gatewayToken = tenant.getGatewayToken(); String gatewayToken = tenant.getGatewayToken();
if (ObjectUtils.isEmpty(gatewayToken)) { if (ObjectUtils.isEmpty(gatewayToken)) {
gatewayToken = randomToken(); gatewayToken = randomToken();
tenant.setGatewayToken(gatewayToken); 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 // if gateway token is configured then the gateway auth is enabled key is set
public String setupTargetToken(final String controllerId, String securityTargetToken) { // so all devices use gateway token authentication
if (ObjectUtils.isEmpty(tenant.getGatewayToken())) { // otherwise target token authentication is enabled. Then all devices shall be registered
final MgmtTargetRestApi mgmtTargetRestApi = hawkbitClient.mgmtService(MgmtTargetRestApi.class, tenant); // and the target token shall be set to the one from the DDI controller instance
try { public void setupTargetAuthentication() {
// test if target exist, if not - throws 404 final String gatewayToken = tenant.getGatewayToken();
final MgmtTarget target = Objects.requireNonNull(mgmtTargetRestApi.getTarget(controllerId).getBody()); if (ObjectUtils.isEmpty(gatewayToken)) {
if (ObjectUtils.isEmpty(securityTargetToken)) { setupSecureTokenAuthentication();
if (ObjectUtils.isEmpty(target.getSecurityToken())) { } else {
// generate random to set to tha existing target without configured security token setupGatewayTokenAuthentication();
securityTargetToken = randomToken(); }
mgmtTargetRestApi.updateTarget(controllerId, new MgmtTargetRequestBody().setSecurityToken(securityTargetToken)); }
} else {
securityTargetToken = target.getSecurityToken(); // 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) {
} else if (!securityTargetToken.equals(target.getSecurityToken())) { final MgmtTargetRestApi mgmtTargetRestApi = hawkbitClient.mgmtService(MgmtTargetRestApi.class, tenant);
// update target's with the security token (since it doesn't match) try {
mgmtTargetRestApi.updateTarget(controllerId, new MgmtTargetRequestBody().setSecurityToken(securityTargetToken)); // test if target exist, if not - throws 404
} final MgmtTarget target = Objects.requireNonNull(mgmtTargetRestApi.getTarget(controllerId).getBody());
} catch (final FeignException.NotFound e) { if (ObjectUtils.isEmpty(securityTargetToken)) {
if (ObjectUtils.isEmpty(securityTargetToken)) { if (ObjectUtils.isEmpty(target.getSecurityToken())) {
// generate random to set to tha existing target without configured security token
securityTargetToken = randomToken(); securityTargetToken = randomToken();
mgmtTargetRestApi.updateTarget(controllerId, new MgmtTargetRequestBody().setSecurityToken(securityTargetToken));
} else {
securityTargetToken = target.getSecurityToken();
} }
// create target with the security token } else if (!securityTargetToken.equals(target.getSecurityToken())) {
mgmtTargetRestApi.createTargets(List.of( // update target's with the security token (since it doesn't match)
new MgmtTargetRequestBody().setControllerId(controllerId).setSecurityToken(securityTargetToken))); 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; 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));
}
}
}
} }