I have configuration like so
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfiguration {
private final JwtTokenFilter jwtTokenFilter;
private final AuthenticationProvider authenticationProvider;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.cors().and()
.csrf().disable()
.authorizeHttpRequests(auth -> {
auth.requestMatchers("/api/v1/auth/**").permitAll();
auth.requestMatchers("/api/v1/admin/**").hasAuthority(Role.ADMIN.name());
auth.requestMatchers("/socket").hasAuthority(Role.MODEM_PROVIDER.name());
auth.requestMatchers("/api/v1/payment/coinRemitter/notify").permitAll();
auth.requestMatchers("/api/v1/auth/verify/**").permitAll();
auth.requestMatchers("/api/v1/auth/restorePassword/**").permitAll();
auth.anyRequest().authenticated();
})
.sessionManagement(policy -> {
policy.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
})
.authenticationProvider(authenticationProvider)
.addFilterBefore(jwtTokenFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*")); // Set allowed origins
configuration.setAllowedMethods(Arrays.asList("*")); // Set allowed HTTP methods
configuration.setAllowedHeaders(Arrays.asList("*")); // Set allowed headers
configuration.setExposedHeaders(Arrays.asList("*")); // Set exposed headers
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
filter looks like this
@Component
@Slf4j
@RequiredArgsConstructor
public class JwtTokenFilter extends GenericFilterBean {
private final UserDetailsService userDetailsService;
private final JwtTokenProvider tokenProvider;
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws ServletException, IOException {
String token = tokenProvider.resolveToken((HttpServletRequest) servletRequest);
try {
tokenProvider.validateAuthToken(token);
} catch (WrongTokenException e) {
System.out.println("whatever");
}
if (token != null) {
Authentication authentication = tokenProvider.getAuthentication(token);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
filterChain.doFilter(servletRequest, servletResponse);
}
}
i'm 100% sure that if filter will be used once it will access db once. But when i'm trying to access endpoints for example "http://localhost:8081/api/v1/auth/authenticate" i see that for some reason it:
- trying to validate user despite this endpoint having permitAll configuration;
- accessing db twice;
- if i'm passing valid token it's printing out that first filterChain was "org.springframework.security.web.FilterChainProxy$VirtualFilterChain@28663665" and second "org.apache.catalina.core.ApplicationFilterChain@464d424c"
why it's trying to validate user on permitAll, why it using filter twice on every request and how can i fix that?