From 83b30381a469394fbb7df87feae89f1ebc5a54cd Mon Sep 17 00:00:00 2001 From: Avgustin Marinov Date: Thu, 13 Feb 2025 09:04:48 +0200 Subject: [PATCH] SDK: Improve authentication setup Signed-off-by: Avgustin Marinov --- .../java/org/eclipse/hawkbit/sdk/ca/CA.java | 1 + .../hawkbit/sdk/demo/device/DeviceApp.java | 3 +- .../sdk/demo/multidevice/MultiDeviceApp.java | 3 +- .../sdk/mgmt/AuthenticationSetupHelper.java | 155 +++++++++--------- 4 files changed, 82 insertions(+), 80 deletions(-) diff --git a/hawkbit-sdk/hawkbit-sdk-commons/src/main/java/org/eclipse/hawkbit/sdk/ca/CA.java b/hawkbit-sdk/hawkbit-sdk-commons/src/main/java/org/eclipse/hawkbit/sdk/ca/CA.java index 57fadcc0a4..79b37000ed 100644 --- a/hawkbit-sdk/hawkbit-sdk-commons/src/main/java/org/eclipse/hawkbit/sdk/ca/CA.java +++ b/hawkbit-sdk/hawkbit-sdk-commons/src/main/java/org/eclipse/hawkbit/sdk/ca/CA.java @@ -35,6 +35,7 @@ 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; diff --git a/hawkbit-sdk/hawkbit-sdk-demo/src/main/java/org/eclipse/hawkbit/sdk/demo/device/DeviceApp.java b/hawkbit-sdk/hawkbit-sdk-demo/src/main/java/org/eclipse/hawkbit/sdk/demo/device/DeviceApp.java index 734b731cd7..33826e9902 100644 --- a/hawkbit-sdk/hawkbit-sdk-demo/src/main/java/org/eclipse/hawkbit/sdk/demo/device/DeviceApp.java +++ b/hawkbit-sdk/hawkbit-sdk-demo/src/main/java/org/eclipse/hawkbit/sdk/demo/device/DeviceApp.java @@ -12,7 +12,6 @@ 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 static class Shell { @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") diff --git a/hawkbit-sdk/hawkbit-sdk-demo/src/main/java/org/eclipse/hawkbit/sdk/demo/multidevice/MultiDeviceApp.java b/hawkbit-sdk/hawkbit-sdk-demo/src/main/java/org/eclipse/hawkbit/sdk/demo/multidevice/MultiDeviceApp.java index d5f7f6299d..7a50095c14 100644 --- a/hawkbit-sdk/hawkbit-sdk-demo/src/main/java/org/eclipse/hawkbit/sdk/demo/multidevice/MultiDeviceApp.java +++ b/hawkbit-sdk/hawkbit-sdk-demo/src/main/java/org/eclipse/hawkbit/sdk/demo/multidevice/MultiDeviceApp.java @@ -12,7 +12,6 @@ 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 void setup() { 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; } diff --git a/hawkbit-sdk/hawkbit-sdk-mgmt/src/main/java/org/eclipse/hawkbit/sdk/mgmt/AuthenticationSetupHelper.java b/hawkbit-sdk/hawkbit-sdk-mgmt/src/main/java/org/eclipse/hawkbit/sdk/mgmt/AuthenticationSetupHelper.java index 8be4252b0c..5e2fffd7f8 100644 --- a/hawkbit-sdk/hawkbit-sdk-mgmt/src/main/java/org/eclipse/hawkbit/sdk/mgmt/AuthenticationSetupHelper.java +++ b/hawkbit-sdk/hawkbit-sdk-mgmt/src/main/java/org/eclipse/hawkbit/sdk/mgmt/AuthenticationSetupHelper.java @@ -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 static String randomToken() { 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; - } - // 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)) { - securityTargetToken = randomToken(); - } - // create target with the security token - mgmtTargetRestApi.createTargets(List.of( - new MgmtTargetRequestBody().setControllerId(controllerId).setSecurityToken(securityTargetToken))); - } + 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)); } - - 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)); - } + // 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 { - if (!Boolean.TRUE.equals(enabled)) { - mgmtTenantManagementRestApi.updateTenantConfiguration(Map.of(AUTHENTICATION_MODE_HEADER_ENABLED, true)); + 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(); + } + } 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)); } - 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)); + } 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; } } \ No newline at end of file