From 8217b9c038208d3131ef263630109bb1e8354918 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joakim=20M=C3=B6rling?= Date: Fri, 15 May 2026 12:14:39 +0200 Subject: [PATCH] feat: wire role-based authorities from JWT into Spring Security MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - JwtAuthenticationFilter now extracts the "role" claim from the JWT token and creates a SimpleGrantedAuthority("ROLE_" + role.toUpperCase()) on the authentication token. Previously the authorities list was always empty (only userDetails.getAuthorities() which returned List.of()) - SecurityConfig adds .requestMatchers("/api/admin/**").hasRole("ADMIN") so admin endpoints require the ROLE_ADMIN authority - All existing endpoints remain authenticated() only — no existing user flow is affected - Public endpoints (auth, webhooks, vehicles) still permitAll() --- .../java/se/bilhalsning/config/SecurityConfig.java | 1 + .../bilhalsning/security/JwtAuthenticationFilter.java | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/backend/src/main/java/se/bilhalsning/config/SecurityConfig.java b/backend/src/main/java/se/bilhalsning/config/SecurityConfig.java index c3ddd1d..9a99694 100644 --- a/backend/src/main/java/se/bilhalsning/config/SecurityConfig.java +++ b/backend/src/main/java/se/bilhalsning/config/SecurityConfig.java @@ -37,6 +37,7 @@ public class SecurityConfig { .requestMatchers("/api/auth/register", "/api/auth/login").permitAll() .requestMatchers("/api/webhooks/**").permitAll() .requestMatchers("/api/vehicles/**").permitAll() + .requestMatchers("/api/admin/**").hasRole("ADMIN") .anyRequest().authenticated()) .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); diff --git a/backend/src/main/java/se/bilhalsning/security/JwtAuthenticationFilter.java b/backend/src/main/java/se/bilhalsning/security/JwtAuthenticationFilter.java index fc3cc84..93d71f3 100644 --- a/backend/src/main/java/se/bilhalsning/security/JwtAuthenticationFilter.java +++ b/backend/src/main/java/se/bilhalsning/security/JwtAuthenticationFilter.java @@ -45,8 +45,16 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { var userDetails = userDetailsService.loadUserByUsername(username); if (jwtService.isTokenValid(token)) { + String role = jwtService.extractRole(token); + List authorities = + new java.util.ArrayList<>(); + if (role != null) { + authorities.add(new org.springframework.security.core.authority.SimpleGrantedAuthority( + "ROLE_" + role.toUpperCase())); + } + var authToken = new UsernamePasswordAuthenticationToken( - userDetails, null, userDetails.getAuthorities()); + userDetails, null, authorities); authToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); SecurityContextHolder.getContext().setAuthentication(authToken); }