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 ;
1315import org .springframework .security .config .annotation .web .builders .HttpSecurity ;
1416import org .springframework .security .config .annotation .web .configuration .EnableWebSecurity ;
1517import org .springframework .security .config .http .SessionCreationPolicy ;
18+ import org .springframework .security .config .annotation .web .configurers .AbstractHttpConfigurer ;
1619import org .springframework .security .provisioning .InMemoryUserDetailsManager ;
1720import org .springframework .security .web .SecurityFilterChain ;
21+ import org .springframework .security .web .context .NullSecurityContextRepository ;
1822
1923@ Configuration
2024@ EnableWebSecurity
2125public class SecurityConfig {
2226
27+ private static final String RANDOM_USERS_PATH = "/random-users/**" ;
28+ private static final String RANDOM_USERS_PREFIX = "/random-users" ;
29+ private static final String ADMIN_ROLE = "ADMIN" ;
30+
2331 @ Value ("${app.security.admin.username}" )
2432 private String adminUsername ;
2533
@@ -39,35 +47,47 @@ public class SecurityConfig {
3947 private String testPassword ;
4048
4149 @ 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 ();
50+ public SecurityFilterChain securityFilterChain (HttpSecurity http ) {
51+ try {
52+ return http
53+ .csrf (csrf -> csrf .ignoringRequestMatchers (this ::isBasicAuthRequest ))
54+ .securityContext (context -> context .securityContextRepository (new NullSecurityContextRepository ()))
55+ .sessionManagement (session -> session .sessionCreationPolicy (SessionCreationPolicy .STATELESS ))
56+ .httpBasic (Customizer .withDefaults ())
57+ .authorizeHttpRequests (auth -> auth
58+ .requestMatchers (getPublicEndpoints ()).permitAll ()
59+ .requestMatchers (HttpMethod .GET , RANDOM_USERS_PATH ).hasAnyRole (ADMIN_ROLE , "USER" , "TEST" )
60+ .anyRequest ().authenticated ()
61+ )
62+ .build ();
63+ } catch (Exception e ) {
64+ throw new SecurityConfigurationException ("Failed to build Spring Security filter chain" , e );
65+ }
66+ }
67+
68+
69+ private boolean isBasicAuthRequest (HttpServletRequest request ) {
70+ String authHeader = request .getHeader (HttpHeaders .AUTHORIZATION );
71+ String servletPath = request .getServletPath ();
72+ boolean isRandomUsersPath = servletPath != null && servletPath .startsWith (RANDOM_USERS_PREFIX );
73+ return isRandomUsersPath && authHeader != null && authHeader .startsWith ("Basic " );
74+ }
75+
76+ private String [] getPublicEndpoints () {
77+ return new String []{
78+ "/api/**" ,
79+ "/swagger-ui/**" ,
80+ "/swagger-ui.html" ,
81+ "/v3/api-docs/**" ,
82+ "/actuator/health"
83+ };
6484 }
6585
6686 @ Bean
6787 UserDetailsService userDetailsService (PasswordEncoder passwordEncoder ) {
6888 UserDetails admin = User .withUsername (adminUsername )
6989 .password (passwordEncoder .encode (adminPassword ))
70- .roles ("ADMIN" )
90+ .roles (ADMIN_ROLE )
7191 .build ();
7292
7393 UserDetails user = User .withUsername (userUsername )
0 commit comments