Spring Security Rest令牌认证 - 过滤器不运行

时间:2016-09-15 10:48:23

标签: java rest spring-mvc spring-security filter

我使用Spring 4和java配置(没有任何xml文件)构建REST应用程序。

这里有一些实际的代码:

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;
    }
}

除了我使用令牌认证保护WebService之外,我有一个过滤器来处理令牌并通过他的令牌正确地获取用户并将用户对象放入SecuriryContext。以下是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);
}

}

我使用的是Spring Security,这是我的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);
  }

}

我的问题是过滤器doFilter()无法运行。有什么帮助吗?

PS:使用SpringBoot不是一种选择。我想在不使用弹簧启动自动配置的情况下这样做。

1 个答案:

答案 0 :(得分:2)

你正在添加过滤器而不是一个组件,你就像一个简单的对象,它是由ServletContext中的某个地方的反射创建的,它对Spring一无所知。 如果使用Spring Security

,可以在安全配置中向SpringSecurityFilterChain添加过滤器
@EnableWebSecurity
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private YourFilter yourFilter;

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