11package com .xpeho .spring_boot_java_random_user .config ;
22
3+ import jakarta .servlet .http .HttpServletRequest ;
34import org .springframework .context .annotation .Bean ;
45import org .springframework .context .annotation .Configuration ;
56import org .springframework .beans .factory .annotation .Value ;
7+ import org .springframework .http .HttpHeaders ;
68import org .springframework .http .HttpMethod ;
79import org .springframework .security .core .userdetails .User ;
810import org .springframework .security .core .userdetails .UserDetails ;
1517import org .springframework .security .config .http .SessionCreationPolicy ;
1618import org .springframework .security .provisioning .InMemoryUserDetailsManager ;
1719import org .springframework .security .web .SecurityFilterChain ;
20+ import org .springframework .security .web .context .NullSecurityContextRepository ;
1821
1922@ Configuration
2023@ EnableWebSecurity
2124public class SecurityConfig {
2225
26+ private static final String RANDOM_USERS_PATH = "/random-users/**" ;
27+ private static final String RANDOM_USERS_PREFIX = "/random-users" ;
28+ private static final String ADMIN_ROLE = "ADMIN" ;
29+
2330 @ Value ("${app.security.admin.username}" )
2431 private String adminUsername ;
2532
@@ -39,35 +46,50 @@ public class SecurityConfig {
3946 private String testPassword ;
4047
4148 @ Bean
42- SecurityFilterChain securityFilterChain (HttpSecurity http ) throws Exception {
43- http
44- .csrf (csrf -> csrf .ignoringRequestMatchers ("/random-users/**" ))
45- .sessionManagement (session -> session .sessionCreationPolicy (SessionCreationPolicy .STATELESS ))
46- .httpBasic (Customizer .withDefaults ())
47- .authorizeHttpRequests (auth -> auth
48- .requestMatchers (
49- "/api/**" ,
50- "/swagger-ui/**" ,
51- "/swagger-ui.html" ,
52- "/v3/api-docs/**" ,
53- "/actuator/health"
54- ).permitAll ()
55- .requestMatchers (HttpMethod .OPTIONS , "/**" ).permitAll ()
56- .requestMatchers (HttpMethod .GET , "/random-users/**" ).hasAnyRole ("ADMIN" , "USER" , "TEST" )
57- .requestMatchers (HttpMethod .POST , "/random-users/**" ).hasRole ("ADMIN" )
58- .requestMatchers (HttpMethod .PUT , "/random-users/**" ).hasRole ("ADMIN" )
59- .requestMatchers (HttpMethod .DELETE , "/random-users/**" ).hasRole ("ADMIN" )
60- .anyRequest ().authenticated ()
61- );
62-
63- return http .build ();
49+ public SecurityFilterChain securityFilterChain (HttpSecurity http ) {
50+ try {
51+ return http
52+ .csrf (csrf -> csrf .ignoringRequestMatchers (this ::isBasicAuthRequest ))
53+ .securityContext (context -> context .securityContextRepository (new NullSecurityContextRepository ()))
54+ .sessionManagement (session -> session .sessionCreationPolicy (SessionCreationPolicy .STATELESS ))
55+ .httpBasic (Customizer .withDefaults ())
56+ .authorizeHttpRequests (auth -> auth
57+ .requestMatchers (getPublicEndpoints ()).permitAll ()
58+ .requestMatchers (HttpMethod .GET , RANDOM_USERS_PATH ).hasAnyRole (ADMIN_ROLE , "USER" , "TEST" )
59+ .requestMatchers (HttpMethod .POST , RANDOM_USERS_PATH ).hasRole (ADMIN_ROLE )
60+ .requestMatchers (HttpMethod .PUT , RANDOM_USERS_PATH ).hasRole (ADMIN_ROLE )
61+ .requestMatchers (HttpMethod .DELETE , RANDOM_USERS_PATH ).hasRole (ADMIN_ROLE )
62+ .anyRequest ().authenticated ()
63+ )
64+ .build ();
65+ } catch (Exception e ) {
66+ throw new SecurityConfigurationException ("Failed to build Spring Security filter chain" , e );
67+ }
68+ }
69+
70+
71+ private boolean isBasicAuthRequest (HttpServletRequest request ) {
72+ String authHeader = request .getHeader (HttpHeaders .AUTHORIZATION );
73+ String servletPath = request .getServletPath ();
74+ boolean isRandomUsersPath = servletPath != null && servletPath .startsWith (RANDOM_USERS_PREFIX );
75+ return isRandomUsersPath && authHeader != null && authHeader .startsWith ("Basic " );
76+ }
77+
78+ private String [] getPublicEndpoints () {
79+ return new String []{
80+ "/api/**" ,
81+ "/swagger-ui/**" ,
82+ "/swagger-ui.html" ,
83+ "/v3/api-docs/**" ,
84+ "/actuator/health"
85+ };
6486 }
6587
6688 @ Bean
6789 UserDetailsService userDetailsService (PasswordEncoder passwordEncoder ) {
6890 UserDetails admin = User .withUsername (adminUsername )
6991 .password (passwordEncoder .encode (adminPassword ))
70- .roles ("ADMIN" )
92+ .roles (ADMIN_ROLE )
7193 .build ();
7294
7395 UserDetails user = User .withUsername (userUsername )
0 commit comments