franDayz
franDayz

Reputation: 943

Spring security not calling my custom authentication filter when running JUnit tests

I'm trying to implement custom stateless authentication with Spring Security by following this article

The problem I'm facing is that my custom filter is not being called by the framework, even when my SecurityConfig looks almost the same as in the previous link (a bit simpler):

@Configuration
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    @Qualifier("appAuthenticationProvider")
    private AuthenticationProvider authenticationProvider;

    @Autowired
    @Qualifier("appAuthenticationFilter")
    private AppAuthenticationFilter appAuthenticationFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        .csrf().disable().
        sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .authorizeRequests().anyRequest().authenticated()
        .and()
        .anonymous().disable()
        .exceptionHandling().authenticationEntryPoint(unauthorizedEntryPoint());

        http.addFilterBefore(appAuthenticationFilter, BasicAuthenticationFilter.class);
    }

    @Bean
    public AuthenticationEntryPoint unauthorizedEntryPoint() {
        return (request, response, authException) -> response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
    }
}

I don't post the code for authenticationProvider and appAuthenticationFilter as the former is working fine (I can log in using /login endpoint) and the latter just implements GenericFilterBean and is not being even called.

Any help would be much appreciated!

Upvotes: 9

Views: 6636

Answers (2)

Hleb
Hleb

Reputation: 295

To not autowire and set up your filter by hands as in the previous answer, you can use SecurityMockMvcConfigurers.springSecurity():

MockMvcBuilders
.webAppContextSetup(context)
.apply(SecurityMockMvcConfigurers.springSecurity())
.build();

Upvotes: 2

franDayz
franDayz

Reputation: 943

Ok, I found the solution after I noticed that the filters were being executed when deploying the Spring Boot app, and they were not being called only when running tests. Then I found this post:

https://spring.io/blog/2014/05/23/preview-spring-security-test-web-security

I forgot to configure my mock MVC to use filters. So finally my test class for the authentication looks as follows:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = GasApplication.class)
@WebAppConfiguration
public class LoginControllerTest {

    @Autowired
    private WebApplicationContext context;

    @Autowired
    @Qualifier("appAuthenticationFilter")
    private Filter appAuthenticationFilter;

    private MockMvc mockMvc;

    @Before  
    public void init() throws Exception {
        this.mockMvc = MockMvcBuilders.webAppContextSetup(context)
                .addFilter(appAuthenticationFilter, "/resource")
                .build();
    }

    // Tests here...
}

Upvotes: 8

Related Questions