Add Roles and Hierarchies (#1673)
Adds Roles (SpRole -> TENANT_ADMIN, REPOSITORY_ADMIN, ...) and intuitive hierarcy rules for them Signed-off-by: Marinov Avgustin <Avgustin.Marinov@bosch.com>
This commit is contained in:
@@ -15,6 +15,7 @@ import java.util.Map;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.ContextAware;
|
import org.eclipse.hawkbit.ContextAware;
|
||||||
|
import org.eclipse.hawkbit.im.authentication.SpRole;
|
||||||
import org.eclipse.hawkbit.im.authentication.TenantAwareUserProperties;
|
import org.eclipse.hawkbit.im.authentication.TenantAwareUserProperties;
|
||||||
import org.eclipse.hawkbit.im.authentication.TenantAwareUserProperties.User;
|
import org.eclipse.hawkbit.im.authentication.TenantAwareUserProperties.User;
|
||||||
import org.eclipse.hawkbit.im.authentication.PermissionService;
|
import org.eclipse.hawkbit.im.authentication.PermissionService;
|
||||||
@@ -36,6 +37,10 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
|
|||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.data.domain.AuditorAware;
|
import org.springframework.data.domain.AuditorAware;
|
||||||
|
import org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler;
|
||||||
|
import org.springframework.security.access.expression.method.MethodSecurityExpressionHandler;
|
||||||
|
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
|
||||||
|
import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl;
|
||||||
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
|
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
|
||||||
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
|
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;
|
||||||
import org.springframework.security.web.authentication.logout.LogoutHandler;
|
import org.springframework.security.web.authentication.logout.LogoutHandler;
|
||||||
@@ -164,4 +169,20 @@ public class SecurityAutoConfiguration {
|
|||||||
return simpleUrlLogoutSuccessHandler;
|
return simpleUrlLogoutSuccessHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
static RoleHierarchy roleHierarchy() {
|
||||||
|
final RoleHierarchyImpl hierarchy = new RoleHierarchyImpl();
|
||||||
|
hierarchy.setHierarchy(SpRole.DEFAULT_ROLE_HIERARCHY);
|
||||||
|
return hierarchy;
|
||||||
|
}
|
||||||
|
|
||||||
|
// and, if using method security also add
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
static MethodSecurityExpressionHandler methodSecurityExpressionHandler(final RoleHierarchy roleHierarchy) {
|
||||||
|
final DefaultMethodSecurityExpressionHandler expressionHandler = new DefaultMethodSecurityExpressionHandler();
|
||||||
|
expressionHandler.setRoleHierarchy(roleHierarchy);
|
||||||
|
return expressionHandler;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,7 +36,7 @@ spring.rabbitmq.port=5672
|
|||||||
|
|
||||||
# Define own (my_user) users instead together default "admin" (system-wide) user:
|
# Define own (my_user) users instead together default "admin" (system-wide) user:
|
||||||
#hawkbit.security.user.my_user.password={noop}isAwesome!
|
#hawkbit.security.user.my_user.password={noop}isAwesome!
|
||||||
#hawkbit.security.user.my_user.permissions=ALL
|
#hawkbit.security.user.my_user.roles=TENANT_ADMIN
|
||||||
#hawkbit.security.user.my_user.tenant=DEFAULT
|
#hawkbit.security.user.my_user.tenant=DEFAULT
|
||||||
|
|
||||||
# Enable CORS and specify the allowed origins:
|
# Enable CORS and specify the allowed origins:
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ spring.rabbitmq.port=5672
|
|||||||
|
|
||||||
# Define own (my_user) users instead together default "admin" (system-wide) user:
|
# Define own (my_user) users instead together default "admin" (system-wide) user:
|
||||||
#hawkbit.security.user.my_user.password={noop}isAwesome!
|
#hawkbit.security.user.my_user.password={noop}isAwesome!
|
||||||
#hawkbit.security.user.my_user.permissions=ALL
|
#hawkbit.security.user.my_user.roles=TENANT_ADMIN
|
||||||
#hawkbit.security.user.my_user.tenant=DEFAULT
|
#hawkbit.security.user.my_user.tenant=DEFAULT
|
||||||
|
|
||||||
# Enable CORS and specify the allowed origins:
|
# Enable CORS and specify the allowed origins:
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2024 Contributors to the Eclipse Foundation
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made
|
||||||
|
* available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*/
|
||||||
|
package org.eclipse.hawkbit.im.authentication;
|
||||||
|
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Software provisioning roles that implies set of permissions and reflects high-level roles.
|
||||||
|
*/
|
||||||
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
@Slf4j
|
||||||
|
public final class SpRole {
|
||||||
|
|
||||||
|
private static final String IMPLIES = " > ";
|
||||||
|
private static final String LINE_BREAK = "\n";
|
||||||
|
|
||||||
|
public static final String TARGET_ADMIN = "ROLE_TARGET_ADMIN";
|
||||||
|
public static final String TARGET_ADMIN_HIERARCHY =
|
||||||
|
TARGET_ADMIN + IMPLIES + SpPermission.READ_TARGET + LINE_BREAK +
|
||||||
|
TARGET_ADMIN + IMPLIES + SpPermission.READ_TARGET_SEC_TOKEN + LINE_BREAK +
|
||||||
|
TARGET_ADMIN + IMPLIES + SpPermission.UPDATE_TARGET + LINE_BREAK +
|
||||||
|
TARGET_ADMIN + IMPLIES + SpPermission.CREATE_TARGET + LINE_BREAK +
|
||||||
|
TARGET_ADMIN + IMPLIES + SpPermission.DELETE_TARGET + LINE_BREAK;
|
||||||
|
|
||||||
|
public static final String REPOSITORY_ADMIN = "ROLE_REPOSITORY_ADMIN";
|
||||||
|
public static final String REPOSITORY_ADMIN_HIERARCHY =
|
||||||
|
REPOSITORY_ADMIN + IMPLIES + SpPermission.READ_REPOSITORY + LINE_BREAK +
|
||||||
|
REPOSITORY_ADMIN + IMPLIES + SpPermission.UPDATE_REPOSITORY + LINE_BREAK +
|
||||||
|
REPOSITORY_ADMIN + IMPLIES + SpPermission.CREATE_REPOSITORY + LINE_BREAK +
|
||||||
|
REPOSITORY_ADMIN + IMPLIES + SpPermission.DELETE_REPOSITORY + LINE_BREAK +
|
||||||
|
REPOSITORY_ADMIN + IMPLIES + SpPermission.DOWNLOAD_REPOSITORY_ARTIFACT + LINE_BREAK;
|
||||||
|
|
||||||
|
public static final String ROLLOUT_ADMIN = "ROLE_ROLLOUT_ADMIN";
|
||||||
|
public static final String ROLLOUT_ADMIN_HIERARCHY =
|
||||||
|
ROLLOUT_ADMIN + IMPLIES + SpPermission.READ_ROLLOUT + LINE_BREAK +
|
||||||
|
ROLLOUT_ADMIN + IMPLIES + SpPermission.CREATE_ROLLOUT + LINE_BREAK +
|
||||||
|
ROLLOUT_ADMIN + IMPLIES + SpPermission.UPDATE_ROLLOUT + LINE_BREAK +
|
||||||
|
ROLLOUT_ADMIN + IMPLIES + SpPermission.DELETE_ROLLOUT + LINE_BREAK +
|
||||||
|
ROLLOUT_ADMIN + IMPLIES + SpPermission.HANDLE_ROLLOUT + LINE_BREAK +
|
||||||
|
ROLLOUT_ADMIN + IMPLIES + SpPermission.APPROVE_ROLLOUT + LINE_BREAK;
|
||||||
|
|
||||||
|
public static final String TENANT_ADMIN = "ROLE_TENANT_ADMIN";
|
||||||
|
public static final String TENANT_ADMIN_HIERARCHY =
|
||||||
|
TENANT_ADMIN + IMPLIES + TARGET_ADMIN + LINE_BREAK +
|
||||||
|
TENANT_ADMIN + IMPLIES + REPOSITORY_ADMIN + LINE_BREAK +
|
||||||
|
TENANT_ADMIN + IMPLIES + ROLLOUT_ADMIN + LINE_BREAK +
|
||||||
|
TENANT_ADMIN + IMPLIES + SpPermission.TENANT_CONFIGURATION + LINE_BREAK;
|
||||||
|
|
||||||
|
public static final String SYSTEM_ADMIN_HIERARCHY =
|
||||||
|
SpPermission.SYSTEM_ADMIN + IMPLIES + TENANT_ADMIN + LINE_BREAK;
|
||||||
|
|
||||||
|
public static String DEFAULT_ROLE_HIERARCHY =
|
||||||
|
TARGET_ADMIN_HIERARCHY +
|
||||||
|
REPOSITORY_ADMIN_HIERARCHY +
|
||||||
|
ROLLOUT_ADMIN_HIERARCHY + TENANT_ADMIN_HIERARCHY +
|
||||||
|
SYSTEM_ADMIN_HIERARCHY;
|
||||||
|
}
|
||||||
@@ -102,13 +102,8 @@ public class StaticAuthenticationProvider extends DaoAuthenticationProvider {
|
|||||||
grantedAuthorityList.add(new SimpleGrantedAuthority("ROLE_" + role));
|
grantedAuthorityList.add(new SimpleGrantedAuthority("ROLE_" + role));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Allows ALL as a shorthand for all permissions
|
for (final String permission : userPermissions) {
|
||||||
if (userPermissions.size() == 1 && "ALL".equals(userPermissions.get(0))) {
|
grantedAuthorityList.add(new SimpleGrantedAuthority(permission));
|
||||||
grantedAuthorityList.addAll(PermissionUtils.createAllAuthorityList());
|
|
||||||
} else {
|
|
||||||
for (final String permission : userPermissions) {
|
|
||||||
grantedAuthorityList.add(new SimpleGrantedAuthority(permission));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return grantedAuthorityList;
|
return grantedAuthorityList;
|
||||||
|
|||||||
Reference in New Issue
Block a user