@@ -23,8 +23,7 @@ import org.springframework.security.core.GrantedAuthority;
|
||||
* The Permissions cover CRUD for two data areas of SP:<br/>
|
||||
* <br/>
|
||||
* XX_Target_CRUD which covers the following entities: {@link Target} entities
|
||||
* including metadata, {@link TargetTag}s, {@link Action}s,
|
||||
* {@link TargetRegistrationRule}s<br/>
|
||||
* including metadata, {@link TargetTag}s, {@link TargetRegistrationRule}s<br/>
|
||||
* XX_Repository CRUD which covers: {@link DistributionSet}s,
|
||||
* {@link SoftwareModule}s, DS Tags<br/>
|
||||
* </p>
|
||||
@@ -131,6 +130,11 @@ public final class SpPermission {
|
||||
*/
|
||||
public static final String TENANT_CONFIGURATION = "TENANT_CONFIGURATION";
|
||||
|
||||
/**
|
||||
* Permission to administrate a rollout management.
|
||||
*/
|
||||
public static final String ROLLOUT_MANAGEMENT = "ROLLOUT_MANAGEMENT";
|
||||
|
||||
private SpPermission() {
|
||||
// Constants only
|
||||
}
|
||||
@@ -178,6 +182,12 @@ public final class SpPermission {
|
||||
*/
|
||||
public static final String CONTROLLER_ROLE_ANONYMOUS = "ROLE_CONTROLLER_ANONYMOUS";
|
||||
|
||||
/**
|
||||
* The role which contains the spring security context in case the
|
||||
* system is executing code which is necessary to be privileged.
|
||||
*/
|
||||
public static final String SYSTEM_ROLE = "ROLE_SYSTEM_CODE";
|
||||
|
||||
/**
|
||||
* The spring security eval expression operator {@code or}.
|
||||
*/
|
||||
@@ -265,8 +275,15 @@ public final class SpPermission {
|
||||
* context contains the anoynmous role or the controller specific role
|
||||
* {@link SpPermission#CONTROLLER_ROLE}.
|
||||
*/
|
||||
public static final String IS_CONTROLLER = "hasAnyRole('" + CONTROLLER_ROLE_ANONYMOUS + "', '" + CONTROLLER_ROLE
|
||||
+ "')";
|
||||
public static final String IS_CONTROLLER = "hasAnyRole('" + CONTROLLER_ROLE_ANONYMOUS + "', '"
|
||||
+ CONTROLLER_ROLE + "')";
|
||||
|
||||
/**
|
||||
* Spring security eval hasAnyRole expression to check if the spring
|
||||
* context contains system code role
|
||||
* {@link SpringEvalExpressions#SYSTEM_ROLE}.
|
||||
*/
|
||||
public static final String IS_SYSTEM_CODE = HAS_AUTH_PREFIX + SYSTEM_ROLE + HAS_AUTH_SUFFIX;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
@@ -276,6 +293,21 @@ public final class SpPermission {
|
||||
public static final String HAS_AUTH_CREATE_REPOSITORY_AND_CREATE_TARGET = HAS_AUTH_PREFIX + CREATE_REPOSITORY
|
||||
+ HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + CREATE_TARGET + HAS_AUTH_SUFFIX;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#ROLLOUT_MANAGEMENT}
|
||||
*/
|
||||
public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_READ = HAS_AUTH_PREFIX + ROLLOUT_MANAGEMENT
|
||||
+ HAS_AUTH_SUFFIX;
|
||||
|
||||
/**
|
||||
* Spring security eval hasAuthority expression to check if spring
|
||||
* context contains {@link SpPermission#ROLLOUT_MANAGEMENT} and
|
||||
* {@link SpPermission#UPDATE_TARGET}.
|
||||
*/
|
||||
public static final String HAS_AUTH_ROLLOUT_MANAGEMENT_WRITE = HAS_AUTH_PREFIX + ROLLOUT_MANAGEMENT
|
||||
+ HAS_AUTH_SUFFIX + HAS_AUTH_AND + HAS_AUTH_PREFIX + UPDATE_TARGET + HAS_AUTH_SUFFIX;
|
||||
|
||||
private SpringEvalExpressions() {
|
||||
// utility class
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
*/
|
||||
package org.eclipse.hawkbit.security;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
|
||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||
import org.springframework.security.core.Authentication;
|
||||
@@ -27,6 +29,7 @@ import org.springframework.security.core.context.SecurityContextHolder;
|
||||
public class SecurityContextTenantAware implements TenantAware {
|
||||
|
||||
private static final ThreadLocal<String> TENANT_THREAD_LOCAL = new ThreadLocal<>();
|
||||
private static final ThreadLocal<AtomicInteger> RUN_AS_DEPTH = new ThreadLocal<>();
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
@@ -56,11 +59,21 @@ public class SecurityContextTenantAware implements TenantAware {
|
||||
*/
|
||||
@Override
|
||||
public <T> T runAsTenant(final String tenant, final TenantRunner<T> callable) {
|
||||
AtomicInteger runAsDepth = RUN_AS_DEPTH.get();
|
||||
if (runAsDepth == null) {
|
||||
runAsDepth = new AtomicInteger(1);
|
||||
RUN_AS_DEPTH.set(runAsDepth);
|
||||
} else {
|
||||
runAsDepth.incrementAndGet();
|
||||
}
|
||||
TENANT_THREAD_LOCAL.set(tenant);
|
||||
try {
|
||||
return callable.run();
|
||||
} finally {
|
||||
TENANT_THREAD_LOCAL.remove();
|
||||
if (runAsDepth.decrementAndGet() <= 0) {
|
||||
RUN_AS_DEPTH.remove();
|
||||
TENANT_THREAD_LOCAL.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
/**
|
||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||
*
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*/
|
||||
package org.eclipse.hawkbit.security;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
|
||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||
import org.eclipse.hawkbit.tenancy.TenantAware.TenantRunner;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.context.SecurityContextImpl;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
|
||||
/**
|
||||
* @author Michael Hirsch
|
||||
*
|
||||
*/
|
||||
@Service
|
||||
public class SystemSecurityContext {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(SystemSecurityContext.class);
|
||||
|
||||
@Autowired
|
||||
private TenantAware tenantAware;
|
||||
|
||||
public <T> T runAsSystem(final Callable<T> callable) {
|
||||
final SecurityContext oldContext = SecurityContextHolder.getContext();
|
||||
try {
|
||||
logger.debug("entering system code execution");
|
||||
return tenantAware.runAsTenant(tenantAware.getCurrentTenant(), new TenantRunner<T>() {
|
||||
@Override
|
||||
public T run() {
|
||||
try {
|
||||
setSystemContext();
|
||||
return callable.call();
|
||||
} catch (final Exception e) {
|
||||
throw Throwables.propagate(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
} finally {
|
||||
SecurityContextHolder.setContext(oldContext);
|
||||
logger.debug("leaving system code execution");
|
||||
}
|
||||
}
|
||||
|
||||
private static void setSystemContext() {
|
||||
final SecurityContextImpl securityContextImpl = new SecurityContextImpl();
|
||||
securityContextImpl.setAuthentication(new SystemCodeAuthentication());
|
||||
SecurityContextHolder.setContext(securityContextImpl);
|
||||
}
|
||||
|
||||
public static class SystemCodeAuthentication implements Authentication {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private static final List<SimpleGrantedAuthority> AUTHORITIES = Collections
|
||||
.singletonList(new SimpleGrantedAuthority(SpringEvalExpressions.SYSTEM_ROLE));
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
||||
return AUTHORITIES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getCredentials() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getDetails() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPrincipal() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAuthenticated() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAuthenticated(final boolean isAuthenticated) throws IllegalArgumentException {
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user