RBAC Permission Analysis and Spring Security Implementation Guide
This article provides a comprehensive tutorial on role‑based access control (RBAC) concepts, model classifications, permission definitions, user‑group usage, and step‑by‑step implementations of Spring Security, JWT integration, JSON login, password encryption, and database authentication with extensive code examples.
RBAC (Role‑Based Access Control) is introduced as a permission model that links users to roles and roles to permissions, simplifying permission management by assigning rights to roles rather than individual users.
The article outlines the four RBAC models (RBAC0‑RBAC3), describing RBAC0 as the simplest model with many‑to‑one and many‑to‑many user‑role relationships, RBAC1 adding role hierarchies, RBAC2 introducing constraints such as role mutual exclusion, cardinality, and prerequisites, and RBAC3 combining all previous features into a unified model.
It explains the concept of permissions as collections of resources (e.g., page access, CRUD operations) and demonstrates how user groups can batch‑assign roles to large numbers of users, reducing administrative effort.
Spring Security Simple Usage
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>A basic controller is shown:
package com.example.demo.web;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/test")
public class Test {
@RequestMapping("/test")
public String test(){
return "test";
}
}Configuration of in‑memory users:
@Configuration
public class MyWebSecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
PasswordEncoder passwordEncoder(){
return NoOpPasswordEncoder.getInstance();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("admin").password("123").roles("admin");
}
}JWT Integration
package com.example.demo;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.security.core.userdetails.UserDetails;
public class JwtTokenUtil implements Serializable {
private String secret;
private Long expiration;
private String header;
private String generateToken(Map<String, Object> claims){
Date expirationDate = new Date(System.currentTimeMillis() + expiration);
return Jwts.builder().setClaims(claims).setExpiration(expirationDate)
.signWith(SignatureAlgorithm.HS512, secret).compact();
}
// methods to get claims, username, validate token, refresh token, etc.
}A JWT authentication filter is provided to extract the token from the request header and set the security context:
@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 {
String authHeader = request.getHeader(jwtTokenUtil.getHeader());
if (authHeader != null && StringUtils.isNotEmpty(authHeader)) {
String username = jwtTokenUtil.getUsernameFromToken(authHeader);
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
if (jwtTokenUtil.validateToken(authHeader, userDetails)) {
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(authentication);
}
}
}
chain.doFilter(request, response);
}
}Configuration class combines JWT filter, disables CSRF, sets stateless session management, and permits unauthenticated access to the authentication endpoints:
@EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
@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);
}
@Bean
public PasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
}For JSON‑based login, a custom UsernamePasswordAuthenticationFilter is implemented to read username and password from a JSON payload, and the security configuration replaces the default filter with this custom one.
public class CustomAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
@Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
if (MediaType.APPLICATION_JSON_VALUE.equals(request.getContentType())) {
ObjectMapper mapper = new ObjectMapper();
try (InputStream is = request.getInputStream()) {
AuthenticationBean bean = mapper.readValue(is, AuthenticationBean.class);
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(bean.getUsername(), bean.getPassword());
setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
} catch (IOException e) {
return super.attemptAuthentication(request, response);
}
}
return super.attemptAuthentication(request, response);
}
}Password encryption is demonstrated using BCryptPasswordEncoder both for storing passwords and for validating login attempts.
@Bean
public BCryptPasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
public User add(User user){
user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
return userRepository.save(user);
}
if (!bCryptPasswordEncoder.matches(inputPassword, storedUser.getPassword())) {
// handle incorrect password
}Finally, the article shows how to configure Spring Security to use a database‑backed UserDetailsService, define role‑based URL restrictions, and integrate all the pieces into a complete authentication solution.
Overall, the guide combines theoretical RBAC analysis with practical Spring Security and JWT implementations, providing developers with a full‑stack reference for building secure Java backend applications.
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.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
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.
