Implementing Role-based Authorization in Spring Applications with Spring Security
In modern applications, ensuring secure access based on user roles is crucial. Role-based Access Control (RBAC) is a common pattern for restricting access to users based on their role within an organization. In this blog, we’ll explore how to implement RBAC in a Spring application using Spring Security.

What is Role-based Access Control (RBAC)?
RBAC is an access control mechanism that assigns permissions to users based on their roles rather than individual identities. It simplifies managing permissions by categorizing users into predefined roles, such as Admin, User, or Guest.
In a Spring application, Spring Security provides robust tools to set up and manage RBAC, helping developers secure endpoints based on user roles efficiently.
Setting Up Spring Security
To get started, create a Spring Boot project with the necessary dependencies:
Dependencies (build.gradle)
Add these dependencies to your build.gradle file:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'com.h2database:h2'
}Configure the Role-based Access Control in Spring Security
Let’s begin by configuring Spring Security to enable role-based access control.
1. Defining User Roles and Permissions
Create a simple enum Role to define our application's roles.
public enum Role {
ROLE_ADMIN, ROLE_USER
}2. Creating User and Role Entities
Define the User entity with roles, and configure relationships between users and roles.
import javax.persistence.*;
import java.util.Set;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String username;
private String password;
@ElementCollection(fetch = FetchType.EAGER)
@Enumerated(EnumType.STRING)
private Set<Role> roles;
// Getters and Setters
}3. Setting Up UserRepository and UserDetailsService
To load users from the database, create a UserRepository and implement UserDetailsService.
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
Optional<User> findByUsername(String username);
}import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
@Service
public class CustomUserDetailsService implements UserDetailsService {
@Autowired
private UserRepository userRepository;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username)
.orElseThrow(() -> new UsernameNotFoundException("User not found"));
return new org.springframework.security.core.userdetails.User(
user.getUsername(),
user.getPassword(),
user.getRoles().stream()
.map(role -> new SimpleGrantedAuthority(role.name()))
.collect(Collectors.toList())
);
}
}4. Configuring Security with Roles in SecurityConfig
Now, configure the SecurityConfig class to manage access control for different roles.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/admin/**").hasRole("ADMIN")
.antMatchers("/user/**").hasAnyRole("USER", "ADMIN")
.antMatchers("/").permitAll()
.and()
.formLogin()
.and()
.logout();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder());
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}In this configuration:
- Only users with the ADMIN role can access routes under
/admin/**. - Both USER and ADMIN roles can access routes under
/user/**. - Routes under
/are accessible to everyone.
Testing the RBAC Configuration
With this configuration, let’s add controllers for testing role-based access.
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HomeController {
@GetMapping("/")
public String home() {
return "Welcome to the public page!";
}
@GetMapping("/user/dashboard")
public String userDashboard() {
return "Welcome to the User Dashboard!";
}
@GetMapping("/admin/dashboard")
public String adminDashboard() {
return "Welcome to the Admin Dashboard!";
}
}Now, run the application. Try accessing /user/dashboard and /admin/dashboard as users with different roles to test the access control.
Conclusion
Role-based access control is essential for securing your application’s resources. By leveraging Spring Security, you can implement a flexible, maintainable access control model that scales with your application.
This Post covers the basics, but Spring Security offers many more features to extend RBAC, such as custom permissions, dynamic role management, and more.




