Dynamic Role Management allows administrators to update permissions and assign roles at runtime without restarting the app. Let’s build it using Firebird and Spring Boot.
1. Add Dependencies
Include the following dependencies in
pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.firebirdsql.jdbc</groupId>
<artifactId>jaybird</artifactId>
<version>5.0.3</version>
</dependency>
2. Configure Firebird Connection
spring.datasource.url=jdbc:firebirdsql://localhost:3050/D:/data/firebird_roles.fdb
spring.datasource.username=sysdba
spring.datasource.password=masterkey
spring.jpa.hibernate.ddl-auto=update
3. Define Entities
@Entity
public class Role {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String description;
}
@Entity
public class User {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
@ManyToMany(fetch = FetchType.EAGER)
private Set<Role> roles;
}
4. Create Role Management APIs
@RestController
@RequestMapping("/roles")
public class RoleController {
@Autowired
private RoleRepository roleRepo;
@Autowired
private UserRepository userRepo;
@PostMapping("/add")
public Role addRole(@RequestBody Role role) {
return roleRepo.save(role);
}
@PostMapping("/assign/{userId}/{roleId}")
public String assignRole(@PathVariable Long userId, @PathVariable Long roleId) {
User user = userRepo.findById(userId).orElseThrow();
Role role = roleRepo.findById(roleId).orElseThrow();
user.getRoles().add(role);
userRepo.save(user);
return "Role assigned successfully";
}
}
5. Load Roles Dynamically in Security
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired private UserRepository userRepo;
@Override
public UserDetails loadUserByUsername(String username) {
User user = userRepo.findByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException("User not found"));
var authorities = user.getRoles()
.stream()
.map(r -> new SimpleGrantedAuthority("ROLE_" + r.getName()))
.toList();
return new org.springframework.security.core.userdetails.User(
user.getUsername(), user.getPassword(), authorities);
}
}
6. Security Configuration
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.csrf().disable()
.authorizeHttpRequests()
.requestMatchers("/admin/**").hasRole("ADMIN")
.requestMatchers("/roles/**").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.httpBasic()
.and()
.build();
}
}
7. Testing Dynamic Role Updates
- Create roles via
/roles/add (e.g., ADMIN, USER).
- Assign a role to a user via
/roles/assign/{userId}/{roleId}.
- The user can access new endpoints without restarting the server — roles are loaded dynamically from Firebird.
image quote pre code