Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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!

like image 608
franDayz Avatar asked May 27 '15 09:05

franDayz


2 Answers

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...
}
like image 125
franDayz Avatar answered Oct 27 '22 16:10

franDayz


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();
like image 38
Hleb Avatar answered Oct 27 '22 17:10

Hleb