Skip to content

Instantly share code, notes, and snippets.

@thomasdarimont
Last active June 14, 2023 21:59
Show Gist options
  • Save thomasdarimont/ee9fffdef1adb9243b12ad247478aad4 to your computer and use it in GitHub Desktop.
Save thomasdarimont/ee9fffdef1adb9243b12ad247478aad4 to your computer and use it in GitHub Desktop.
Simple example for configuring Spring Security's RoleHierarchy via YAML in Spring Boot, compatible with Java 7
package demo;
import static java.util.Arrays.asList;
import static org.springframework.security.core.authority.AuthorityUtils.createAuthorityList;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.security.access.hierarchicalroles.RoleHierarchy;
import org.springframework.security.access.hierarchicalroles.RoleHierarchyImpl;
import lombok.Getter;
import lombok.Setter;
@SpringBootApplication
@EnableConfigurationProperties(SecurityPropertiesExtension.class)
public class App {
public static void main(String[] args) {
RoleHierarchy roleHierarchy = SpringApplication.run(App.class, args).getBean(RoleHierarchy.class);
for (String role : asList("ROLE_ALL", "ROLE_A", "ROLE_C")) {
System.out.printf("Role: %s implies: %s%n", role,
roleHierarchy.getReachableGrantedAuthorities(createAuthorityList(role)));
}
}
@Bean
RoleHierarchy roleHierarchy(SecurityPropertiesExtension spe) {
return RoleHierarchyUtils.roleHierarchyFromMap(spe.getHierarchy());
}
}
@Getter
@Setter
@ConfigurationProperties("security.roles")
class SecurityPropertiesExtension {
Map<String, List<String>> hierarchy = new LinkedHashMap<>();
}
class RoleHierarchyUtils {
public static RoleHierarchy roleHierarchyFromMap(Map<String, List<String>> roleHierarchyMapping) {
StringWriter roleHierachyDescriptionBuffer = new StringWriter();
PrintWriter roleHierarchyDescriptionWriter = new PrintWriter(roleHierachyDescriptionBuffer);
for (Map.Entry<String, List<String>> entry : roleHierarchyMapping.entrySet()) {
String currentRole = entry.getKey();
List<String> impliedRoles = entry.getValue();
for (String impliedRole : impliedRoles) {
String roleMapping = currentRole + " > " + impliedRole;
roleHierarchyDescriptionWriter.println(roleMapping);
}
}
RoleHierarchyImpl roleHierarchy = new RoleHierarchyImpl();
roleHierarchy.setHierarchy(roleHierachyDescriptionBuffer.toString());
return roleHierarchy;
}
}
security:
roles:
hierarchy:
ROLE_ALL: ROLE_A, ROLE_C
ROLE_A: ROLE_B
ROLE_B: ROLE_AUTHENTICATED
ROLE_C: ROLE_AUTHENTICATED
ROLE_AUTHENTICATED: ROLE_UNAUTHENTICATED
Role: ROLE_ALL implies: [ROLE_C, ROLE_A, ROLE_B, ROLE_UNAUTHENTICATED, ROLE_AUTHENTICATED, ROLE_ALL]
Role: ROLE_A implies: [ROLE_A, ROLE_B, ROLE_UNAUTHENTICATED, ROLE_AUTHENTICATED]
Role: ROLE_C implies: [ROLE_C, ROLE_UNAUTHENTICATED, ROLE_AUTHENTICATED]
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.tdlabs.training</groupId>
<artifactId>spring-boot-security-role-hierarchy-from-yaml-example</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>spring-boot-security-role-hierarchy-from-yaml-example</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.6.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.8</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment