From 7a281a8236d2440984ebf7c71e40a787cd19ac3e Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Fri, 13 May 2016 15:38:52 +0200 Subject: [PATCH] allow the getTargetSecurityToken can be called as system code Signed-off-by: Michael Hirsch --- .../repository/DeploymentManagement.java | 9 ++++++- .../hawkbit/repository/model/Target.java | 9 +++++-- .../security/SystemSecurityContext.java | 26 +++++++++++++++++++ 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java index 805b66d75..1e58ea938 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java @@ -54,6 +54,7 @@ import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetInfo; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; import org.eclipse.hawkbit.repository.specifications.TargetSpecifications; +import org.eclipse.hawkbit.security.SystemSecurityContext; import org.hibernate.validator.constraints.NotEmpty; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -118,6 +119,9 @@ public class DeploymentManagement { @Autowired private AfterTransactionCommitExecutor afterCommit; + @Autowired + private SystemSecurityContext systemSecurityContext; + /** * method assigns the {@link DistributionSet} to all {@link Target}s. * @@ -422,11 +426,14 @@ public class DeploymentManagement { private void assignDistributionSetEvent(final Target target, final Long actionId, final List softwareModules) { target.getTargetInfo().setUpdateStatus(TargetUpdateStatus.PENDING); + final String targetSecurityToken = systemSecurityContext.runAsSystem(() -> { + return target.getSecurityToken(); + }); afterCommit.afterCommit(() -> { eventBus.post(new TargetInfoUpdateEvent(target.getTargetInfo())); eventBus.post(new TargetAssignDistributionSetEvent(target.getOptLockRevision(), target.getTenant(), target.getControllerId(), actionId, softwareModules, target.getTargetInfo().getAddress(), - target.getSecurityToken())); + targetSecurityToken)); }); } diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Target.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Target.java index 5f37fb653..8947ea6c3 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Target.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/repository/model/Target.java @@ -38,6 +38,7 @@ import javax.validation.constraints.Size; import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.repository.model.helper.SecurityChecker; import org.eclipse.hawkbit.repository.model.helper.SecurityTokenGeneratorHolder; +import org.eclipse.hawkbit.repository.model.helper.SystemSecurityContextHolder; import org.eclipse.persistence.annotations.CascadeOnDelete; import org.springframework.data.domain.Persistable; @@ -193,10 +194,14 @@ public class Target extends NamedEntity implements Persistable { } /** - * @return the securityToken + * @return the securityToken if the current security context contains the + * necessary permission {@link SpPermission#READ_TARGET_SEC_TOKEN} + * or the current context is executed as system code, otherwise + * {@code null}. */ public String getSecurityToken() { - if (SecurityChecker.hasPermission(SpPermission.READ_TARGET_SEC_TOKEN)) { + if (SystemSecurityContextHolder.getInstance().getSystemSecurityContext().isCurrentThreadSystemCode() + || SecurityChecker.hasPermission(SpPermission.READ_TARGET_SEC_TOKEN)) { return securityToken; } return null; diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java index b22b54e39..409e714a0 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java @@ -49,6 +49,21 @@ public class SystemSecurityContext { this.tenantAware = tenantAware; } + /** + * Runs a given {@link Callable} within a system security context, which is + * permitted to call secured system code. Often the system needs to call + * secured methods by it's own without relying on the current security + * context e.g. if the current security context does not contain the + * necessary permission it's necessary to execute code as system code to + * execute necessary methods and functionality. + * + * The security context will be switched to the system code and back after + * the callable is called. + * + * @param callable + * the callable to call within the system security context + * @return the return value of the {@link Callable#call()} method. + */ public T runAsSystem(final Callable callable) { final SecurityContext oldContext = SecurityContextHolder.getContext(); try { @@ -68,6 +83,17 @@ public class SystemSecurityContext { } } + /** + * @return {@code true} if the current running code is running as system + * code block. + */ + public boolean isCurrentThreadSystemCode() { + if (SecurityContextHolder.getContext().getAuthentication() instanceof SystemCodeAuthentication) { + return true; + } + return false; + } + private static void setSystemContext() { final SecurityContextImpl securityContextImpl = new SecurityContextImpl(); securityContextImpl.setAuthentication(new SystemCodeAuthentication());