Renato Lochetti
Renato Lochetti

Reputation: 4568

Spring Security Rest Token Authentication - Filter does not run

I'm building a REST application using Spring 4 and java configs (without any xml file).

Here some actual code:

public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[] {ApplicationConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return null;
    }
}

Besides that I'm securing the WebService with Token Authentication, so I have a Filter to deal with the token and properly get the user by his token and put the user object into the SecuriryContext. Here is some code of the Filter:

@Component
public class AuthenticationTokenFilter extends UsernamePasswordAuthenticationFilter {

private String tokenHeader = "X-Auth-Token";

@Autowired
private TokenUtils tokenUtils;

@Autowired
private UserDetailsService userDetailsService;

@Override
@Autowired
public void setAuthenticationManager(AuthenticationManager authenticationManager) {
    super.setAuthenticationManager(authenticationManager);
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

    HttpServletRequest httpRequest = (HttpServletRequest) request;
    String authToken = httpRequest.getHeader(this.tokenHeader);
    String username = this.tokenUtils.getUsernameFromToken(authToken);

    if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
        UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
        if (this.tokenUtils.validateToken(authToken, userDetails)) {
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
            authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(httpRequest));
            SecurityContextHolder.getContext().setAuthentication(authentication);
        }
    }

    chain.doFilter(request, response);
}

}

I'm using Spring Security, and here is my WebSecurityConfigurerAdapter

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

  @Autowired
  private EntryPointUnauthorizedHandler unauthorizedHandler;

  @Autowired
  private AuthenticationTokenFilter authTokenFilter;


  @Bean
  public PasswordEncoder passwordEncoder() {
    return new BCryptPasswordEncoder();
  }

  @Bean
  @Override
  public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
  }


  @Override
  protected void configure(HttpSecurity httpSecurity) throws Exception {
    httpSecurity
      .csrf()
        .disable()
      .exceptionHandling()
        .authenticationEntryPoint(this.unauthorizedHandler)
        .and()
      .sessionManagement()
        .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
      .authorizeRequests()
        .antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
        .antMatchers("/auth/**").permitAll()    
        .anyRequest().authenticated();

        httpSecurity
      .addFilterBefore(authTokenFilter, UsernamePasswordAuthenticationFilter.class);
  }

}

My problem is that the Filter's doFilter() does not run. Any help?

PS: Using SpringBoot is not an option. I want to do that without using the spring boot auto configurations.

Upvotes: 0

Views: 1508

Answers (1)

Yuri Plevako
Yuri Plevako

Reputation: 321

You are adding filter not as a component, you do it like a simple object, which is created by reflection somewhere in ServletContext which knows nothing about Spring. You can add you filter to SpringSecurityFilterChain in security configurations if you use Spring Security

@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private YourFilter yourFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
           .addFilterBefore(yourFilter, UsernamePasswordAuthenticationFilter.class);
    }
}

Upvotes: 3

Related Questions