Spring Boot fails to boot up after add @EnableWebSecurity

147 Views Asked by At

I'm trying to add security headers to my Spring Boot application.

It already had a Java class with multiple filters extending from WebSecurityConfigurerAdapter. But whenever I try to add the annotation @EnableWebSecurity to this class or even with a new custom one I always receive NullPointerException for the bean springSecurityFilterChain.

Changing the order to add some filters seems to solve this problem but whenever I try to enter the app I can't because it seems the HTTP Authorization header field is null (which I recover inside one of my custom filters).

Do any have a clue of what is happening?

EDIT: After some days of cheking this I noted that the Authorization header was not the problem as the code is built to let that call enter without it and before any change it was already sent without header. Still with the same call and the changes I'm receiving a 403 FORBIDDEN (before any change this call was receiving 302 FOUND). This happens before even reaching the controller and I can only get debugging until the filter. As there were no other changes in the code except the @EnableWebSecurity and the way to add one filter I suspect the problem is around here but i can't find what is causing it exactly.

EDIT: I'm adding the code in case anyone need to see it. This is the class that has the multiple filters:

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableWebSecurity //ADDED THIS ONE 
public class MultipleEntryPointsSecurityConfig {
        
    @Configuration
    @Order(1)
    public class OauthSecurityAdapter extends WebSecurityConfigurerAdapter {
        @Autowired
        private OAuth2RestTemplate restTemplate;

        @Bean
        public CustomFilterOneFilter customFilterOneFilter() {
            final CustomFilterOneFilter filter = new CustomFilterOneFilter ("/testLogin");
            filter.setRestTemplate(restTemplate);
            return filter;
        }
        
        @Bean
        public FilterRegistrationBean<OAuth2ClientContextFilter> oauth2ClientFilterRegistration(
            OAuth2ClientContextFilter filter) {
            FilterRegistrationBean<OAuth2ClientContextFilter> registration = new FilterRegistrationBean<OAuth2ClientContextFilter>();
            registration.setFilter(filter);
            registration.setOrder(-100);
            return registration;
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            // @formatter:off
            http
                .antMatcher("/login")
                .cors()
                    .and()
                .csrf().disable()
        //CHANGED THIS
//          .addFilterAfter(openIdConnectFilter(), OAuth2ClientContextFilter.class)
        //FOR THESE TWO
                .addFilterAfter(new OAuth2ClientContextFilter(), AbstractPreAuthenticatedProcessingFilter.class)
                .addFilterAfter(openIdConnectFilter(), OAuth2ClientContextFilter.class)         
                .httpBasic()
                    .authenticationEntryPoint(new LoginUrlAuthenticationEntryPoint("/testLogin"))
                    .and()
                .logout()
                    .logoutSuccessUrl("/logout")
                    .permitAll()
                    .and()
                .csrf().disable()
                .authorizeRequests()
                    .anyRequest().authenticated();

         // @formatter:on
        }
    }

    @Configuration
    @Order(2)
    public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

        @Bean
        public JwtSecurityFilter authenticationJwtTokenFilter() {
            return new JwtSecurityFilter();
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                .antMatcher("/api/**")
                .cors()
                    .and()
                .csrf().disable()
                .sessionManagement()
                    .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                    .and()
                .authorizeRequests()
                    .antMatchers("/api/**").authenticated();
            http
                .addFilterAfter(new UsernamePasswordAuthenticationFilter(), AbstractPreAuthenticatedProcessingFilter.class)
                .addFilterAfter(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
        //CHANGED THE BELOW ONE FOR THE TWO ABOVE
            //http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);
        }
    }
    
    @Configuration
    @Order(3)
    public static class PublicConfigurationAdapter extends WebSecurityConfigurerAdapter {

        protected void configure(HttpSecurity http) throws Exception {
            http
                .authorizeRequests()
                    .antMatchers(HttpMethod.GET, "/**").permitAll()
                    .antMatchers("/api/v1/login/**").permitAll();
        }
    }
}

And this is the custom filter where I try to recover the Authorization header:

@Component
public class JwtSecurityFilter extends OncePerRequestFilter{
    
    @Override
    public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        
        String authHeader = request.getHeader(HttpHeaders.AUTHORIZATION);
        
        //FAILS HERE!
        if(authHeader == null || !authHeader.startsWith("Bearer ")) {
            SecurityContextHolder.getContext().setAuthentication(null);
            chain.doFilter(request, response);
            return;
        }
        
        ...
    }
}
0

There are 0 best solutions below