How to configure Spring security white list in filter chain properly?

132 Views Asked by At

I'm trying to build a security filter chain and allow for some white lists to pass without security

This is my dependency

implementation 'org.springframework.boot:spring-boot-starter-security:3.1.5'

My filter

private static final String[] WHITE_LIST_URL = {"/ping/getEnvironment"};

    public SecurityFilterChain securityFilterChain(HttpSecurity http) {
        try {
            http.csrf(AbstractHttpConfigurer::disable)
                    .authorizeHttpRequests(req -> req.requestMatchers(WHITE_LIST_URL)
                            .permitAll()
                            .anyRequest()
                            .authenticated())
                    .sessionManagement(session -> session.sessionCreationPolicy(STATELESS))
                    .authenticationProvider(authenticationProvider)
                    .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
            return http.build();
        } catch (Exception e) {
            throw new IllegalStateException("Not able to build security filter chain", e);
        }
    }

And my test

@Test
    void getEnvironmentTest() throws Exception {
        String rawResponse = mockMvc.perform(MockMvcRequestBuilders.get("/ping/getEnvironment"))
                .andExpect(MockMvcResultMatchers.status()
                        .isOk())
                .andReturn()
                .getResponse()
                .getContentAsString();

        ObjectMapper objectMapper = new ObjectMapper();

        PingResponse pingResponse = objectMapper.readValue(rawResponse, PingResponse.class);
        Assertions.assertNotNull(pingResponse);
    }

But this thest fails


MockHttpServletResponse:
           Status = 401
    Error message = Unauthorized
          Headers = [Vary:"Origin", "Access-Control-Request-Method", "Access-Control-Request-Headers", WWW-Authenticate:"Basic realm="Realm"", X-Content-Type-Options:"nosniff", X-XSS-Protection:"0", Cache-Control:"no-cache, no-store, max-age=0, must-revalidate", Pragma:"no-cache", Expires:"0", X-Frame-Options:"DENY"]
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

Status
Expected :200
Actual   :401

As you can see I'm getting 401 instead of 200

1

There are 1 best solutions below

0
Bogdan Oloeriu On

I figured it out. I was missing the @Bean annotation. After adding the @Bean my test passed as expected

This is how my security filter chahin looks like including the filter anotation.

package eu.vxbank.api.config;

import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import static org.springframework.security.config.http.SessionCreationPolicy.STATELESS;

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
@EnableMethodSecurity
public class SecurityConfiguration {


    private final AuthenticationProvider authenticationProvider; // from spring
    private final JwtAuthenticationFilter jwtAuthFilter; // my filter

    private static final String[] WHITE_LIST_URL = {"/ping/getEnvironment"};

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) {
        try {
            http.csrf(AbstractHttpConfigurer::disable)
                    .authorizeHttpRequests(req -> req.requestMatchers(WHITE_LIST_URL)
                            .permitAll()
                            .anyRequest()
                            .authenticated())
                    .sessionManagement(session -> session.sessionCreationPolicy(STATELESS))
                    .authenticationProvider(authenticationProvider)
                    .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
            return http.build();
        } catch (Exception e) {
            throw new IllegalStateException("Not able to build security filter chain", e);
        }
    }
}