Skip to main content

Chapter 4: Supplementary Course

🎯 Objectives​

  • Deepen concepts with supplementary courses
  • Explore modules 22 to 28 on security
  • Master advanced aspects of the project

πŸ“š Main Resource​

Supplementary Course

All supplementary courses are available in the repository:

πŸ“– Course Folder

Particular focus on modules 22 to 28 for the security section.


πŸ—‚οΈ Course Structure​

The cours/ folder contains a series of progressive modules:

Overview​

ModuleSubjectDescription
01-10FundamentalsProject basics, setup, architecture
11-18Detailed SecuritySpring Security step by step (see Chapter 5)
19-21Advanced APIComplex endpoints, validation
22-28Advanced SecurityJWT, roles, route protection

πŸ” Focus: Modules 22 to 28 (Security)​

These modules cover advanced aspects of security:

Module 22: Introduction to Spring Security​

  • Basic configuration
  • Security filters
  • AuthenticationManager

Module 23: Form Authentication​

  • UserDetailsService
  • PasswordEncoder
  • User storage

Module 24: JWT (JSON Web Tokens)​

  • Token generation
  • Token validation
  • Structure of a JWT
// Structure of a JWT
{
"header": {
"alg": "HS256",
"typ": "JWT"
},
"payload": {
"sub": "user@example.com",
"iat": 1609459200,
"exp": 1609545600,
"roles": ["USER", "ADMIN"]
},
"signature": "..."
}

Module 25: Authentication Filters​

  • JwtAuthenticationFilter
  • Spring Security filter chain
  • OncePerRequestFilter
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {

@Override
protected void doFilterInternal(
HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {

String authHeader = request.getHeader("Authorization");

if (authHeader != null && authHeader.startsWith("Bearer ")) {
String token = authHeader.substring(7);
// Validate the token and authenticate
}

filterChain.doFilter(request, response);
}
}

Module 26: Role-Based Authorization​

  • @PreAuthorize
  • @Secured
  • hasRole() and hasAuthority()
@RestController
@RequestMapping("/api/admin")
public class AdminController {

@GetMapping("/leads")
@PreAuthorize("hasRole('ADMIN')")
public List<LeadDto> getAllLeads() {
return leadService.getAllLeads();
}

@DeleteMapping("/leads/{id}")
@PreAuthorize("hasRole('ADMIN')")
public void deleteLead(@PathVariable Long id) {
leadService.deleteLead(id);
}
}

Module 27: Route Protection​

  • SecurityFilterChain configuration
  • Public vs protected endpoints
  • CORS and CSRF
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
return http
.csrf(csrf -> csrf.disable())
.cors(cors -> cors.configurationSource(corsConfigurationSource()))
.authorizeHttpRequests(auth -> auth
// Public endpoints
.requestMatchers("/api/contact").permitAll()
.requestMatchers("/api/auth/**").permitAll()
// Protected endpoints
.requestMatchers("/api/admin/**").hasRole("ADMIN")
// Everything else requires authentication
.anyRequest().authenticated()
)
.sessionManagement(session ->
session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
)
.addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class)
.build();
}

Module 28: Security Testing​

  • @WithMockUser
  • Authorization tests
  • Authentication tests
@SpringBootTest
@AutoConfigureMockMvc
class SecurityTests {

@Autowired
private MockMvc mockMvc;

@Test
void adminEndpoint_withoutAuth_returns401() throws Exception {
mockMvc.perform(get("/api/admin/leads"))
.andExpect(status().isUnauthorized());
}

@Test
@WithMockUser(roles = "ADMIN")
void adminEndpoint_withAdmin_returns200() throws Exception {
mockMvc.perform(get("/api/admin/leads"))
.andExpect(status().isOk());
}

@Test
void publicEndpoint_withoutAuth_returns200() throws Exception {
mockMvc.perform(post("/api/contact")
.contentType(MediaType.APPLICATION_JSON)
.content("{...}"))
.andExpect(status().isOk());
}
}

πŸ“‹ Key Concepts Covered​

Security Architecture​

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ HTTP Request β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Security Filter Chain β”‚
β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ β”‚ 1. CorsFilter β”‚ β”‚
β”‚ β”‚ 2. CsrfFilter (disabled for API) β”‚ β”‚
β”‚ β”‚ 3. JwtAuthenticationFilter ◄─── Validates token β”‚ β”‚
β”‚ β”‚ 4. UsernamePasswordAuthenticationFilter β”‚ β”‚
β”‚ β”‚ 5. AuthorizationFilter ◄─── Checks roles β”‚ β”‚
β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
β”‚
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Controller β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

JWT Authentication Flow​


πŸ› οΈ Practical Exercises​

Exercise 1: Add a New Role​

Add a MANAGER role that can view leads but not delete them.

Exercise 2: Token with Custom Expiration​

Modify the validity duration of the JWT token (e.g., 1 hour instead of 24).

Exercise 3: Endpoint with Multiple Roles​

Create an endpoint accessible by both ADMIN AND MANAGER.

@PreAuthorize("hasAnyRole('ADMIN', 'MANAGER')")
public List<LeadDto> getLeadsForManagers() {
// ...
}

πŸ“– Access the Courses​

Direct Link

πŸ“š Access the complete course folder

Consult modules 22 to 28 for an in-depth understanding of Spring Boot security.


⏭️ Next Step​

The next chapter covers security in even more detail with modules 11 to 18 from the appendices:

Chapter 5: Advanced Security (Modules 11-18) β†’


Back to module index