Information Security 18 min read

Understanding RBAC and Implementing Spring Security with JWT in Java

This article explains the concepts and models of Role‑Based Access Control (RBAC), demonstrates how to configure Spring Security for in‑memory and JWT‑based authentication, and provides complete Java code examples for permissions, user groups, password encryption, and custom login filters.

Top Architect
Top Architect
Top Architect
Understanding RBAC and Implementing Spring Security with JWT in Java

The article begins with an overview of RBAC (Role‑Based Access Control), describing its purpose, the four RBAC models (RBAC0‑RBAC3), and how roles, users, and permissions relate. It illustrates typical scenarios such as assigning multiple roles to a user and the benefits of using role groups to simplify permission management.

Next, the article shows how to set up Spring Security for a simple in‑memory authentication example. It adds the required Maven dependency:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
    <version>2.3.1.RELEASE</version>
</dependency>

A basic controller is created:

package com.example.demo;

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 for in‑memory users is provided using WebSecurityConfigurerAdapter :

@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");
    }
}

To protect all endpoints, an HttpSecurity configuration is added that permits all requests for demonstration purposes while showing how to restrict access:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http.authorizeRequests()
        .anyRequest().permitAll()
        .and()
        .formLogin().permitAll()
        .and()
        .logout().permitAll();
}

The article then moves to JWT integration. It adds the JWT library dependency:

<dependency>
    <groupId>io.jsonwebtoken</groupId>
    <artifactId>jjwt</artifactId>
    <version>0.9.1</version>
</dependency>

A JwtTokenUtil class is provided to generate, parse, refresh, and validate tokens:

public class JwtTokenUtil implements Serializable {
    private String secret;
    private Long expiration;
    private String header;
    // generateToken, getClaimsFromToken, getUsernameFromToken, isTokenExpired, refreshToken, validateToken methods ...
}

A filter JwtAuthenticationTokenFilter extracts the token from the request header, validates it, and sets the authentication in the security context:

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 = 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);
    }
}

The final security configuration registers the JWT filter, disables CSRF, sets the session policy to stateless, and permits the authentication endpoints:

@EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;

    @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);
    }
}

Additionally, the article covers password encryption using BCryptPasswordEncoder , custom JSON login by extending UsernamePasswordAuthenticationFilter , and database‑backed authentication with role‑based access control. It concludes with a summary that the reader now understands RBAC concepts, Spring Security configuration, JWT integration, and secure password handling.

JavaAccess ControlauthenticationJWTRBACSpring Security
Top Architect
Written by

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.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.