Mastering RBAC with Spring Security and JWT: A Hands‑On Guide
This article walks through the fundamentals of role‑based access control (RBAC), explains RBAC model variants, demonstrates how to configure Spring Security with in‑memory, database, and JWT authentication, and shows JSON‑based login and password encryption techniques for secure backend development.
RBAC Permission Analysis
RBAC (Role‑Based Access Control) is introduced, covering its definition, model classifications (RBAC0‑RBAC3), the concept of permissions, and the use of user groups with practical examples.
What is RBAC
RBAC links users to roles and roles to permissions, allowing efficient permission management by modifying roles instead of individual users.
Model Classification
Four RBAC models are described:
RBAC0
The simplest model, supporting many‑to‑one and many‑to‑many relationships between users and roles.
RBAC1
Introduces role hierarchies (sub‑roles) and inheritance.
RBAC2
Extends RBAC1 with constraints such as role mutual exclusion, cardinality constraints, prerequisites, and runtime mutual exclusion.
RBAC3
Combines RBAC1 and RBAC2 into a unified model.
What is Permission
Permissions are collections of resources, covering page access, operation rights, and CRUD actions on data.
User Group Usage
User groups enable batch role assignment, reducing workload and improving manageability.
Spring Security Simple Usage
Add the Spring Boot starter security dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>Create a test controller:
@RestController
@RequestMapping("/test")
public class Test {
@RequestMapping("/test")
public String test() {
return "test";
}
}Configure username and password in application.yml (or application.properties) and run the application to see the login page.
Spring Security Integration with JWT
Add JWT and Spring Security dependencies, then implement a JwtUser class that implements UserDetails:
public class JwtUser implements UserDetails {
private String username;
private String password;
private Integer state;
private Collection<? extends GrantedAuthority> authorities;
// getters, setters, and overridden methods
}Create a JwtTokenUtil utility to generate, parse, refresh, and validate tokens.
public class JwtTokenUtil implements Serializable {
private String secret;
private Long expiration;
private String header;
// methods: generateToken, getClaimsFromToken, getUsernameFromToken, isTokenExpired, refreshToken, validateToken
}Implement a filter JwtAuthenticationTokenFilter extending OncePerRequestFilter to validate JWT on each request.
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
@Autowired private UserDetailsService userDetailsService;
@Autowired private JwtTokenUtil jwtTokenUtil;
@Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
// extract token, validate, set authentication
chain.doFilter(request, response);
}
}Provide a JwtUserDetailsServiceImpl that loads user details from the database and a UserServiceImpl that authenticates users and returns a JWT.
Final Security Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {
@Autowired private UserDetailsService userDetailsService;
@Autowired private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
@Bean(name = BeanIds.AUTHENTICATION_MANAGER)
@Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); }
@Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }
@Override protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and().authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
.antMatchers("/auth/**").permitAll()
.anyRequest().authenticated()
.and().addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
// CORS configuration omitted for brevity
}
}Spring Security JSON Login
Rewrite UsernamePasswordAuthenticationFilter as CustomAuthenticationFilter to accept JSON payloads.
public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
@Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
if (MediaType.APPLICATION_JSON_VALUE.equals(request.getContentType())) {
// parse JSON to obtain username and password
} else {
return super.attemptAuthentication(request, response);
}
}
}Register the custom filter in the security configuration and set its processing URL.
Spring Security Password Encryption
Define a BCryptPasswordEncoder bean and use it to encode passwords before storing them in the database.
@Bean public BCryptPasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }In the service layer, encode the password when creating a user and verify it during login using matches.
Database Authentication
Configure a WebSecurityConfig that injects a custom UserService for authentication, set role‑based access rules, and enable form login.
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired private UserService userService;
@Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); }
@Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userService); }
@Override protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").hasRole("admin")
.anyRequest().authenticated()
.and().formLogin().loginProcessingUrl("/login").permitAll()
.and().csrf().disable();
}
}Conclusion
The article explains RBAC concepts, demonstrates simple Spring Security usage, shows how to integrate JWT for stateless authentication, covers JSON‑based login, password encryption with BCrypt, and database‑backed authentication, providing a comprehensive guide for secure backend development.
Author: 小小 – Source: segmentfault.com/a/1190000023052493
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
macrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
