2014-10-20 189 views
1

我尝试在RESTful应用程序中通过令牌授权配置Spring Security。Spring Security:AuthenticationProcessingFilter被调用两次

我AuthenticationFilter样子:

@Configurable 

public class CustomTokenAuthenticationFilter extends AbstractAuthenticationProcessingFilter { 

    private static final Logger logger = LoggerFactory.getLogger(CustomTokenAuthenticationFilter.class); 

    private final static String SECRET_KEY = "ThisIsASecretKey"; 
    public final String HEADER_SECURITY_TOKEN = "X-Token"; 

    @Inject 
    private Users usres; 

    public CustomTokenAuthenticationFilter(String defaultFilterProcessesUrl) { 
     super(defaultFilterProcessesUrl); 
     super.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher(defaultFilterProcessesUrl)); 
     setAuthenticationManager(new NoOpAuthenticationManager()); 
    } 

    @Override 
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws IOException, 
      ServletException { 
     String token = request.getHeader(HEADER_SECURITY_TOKEN); 

     logger.info("token found:" + token); 
     TokenInfo tokenInfo = new TokenInfo(token, SECRET_KEY); 

     AbstractAuthenticationToken userAuthenticationToken; 
     try { 
      userAuthenticationToken = authUserByToken(tokenInfo); 
      if (userAuthenticationToken == null) 
       throw new AuthenticationServiceException(MessageFormat.format("Error | {0}", "Bad Token")); 

      return userAuthenticationToken; 
     } catch (ParseException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     return null; 
    } 

    private AbstractAuthenticationToken authUserByToken(TokenInfo token) throws ParseException { 
     if (token == null) { 
      return null; 
     } 
     UserInfo userInfo = usres.findUser(token.getUsername()); 
     ModelMapper mapper = new ModelMapper(); 
     mapper.getConfiguration().setProvider(new UserProvider()); 

     User userDetails = mapper.map(userInfo, User.class); 
     AbstractAuthenticationToken authToken = new AuthenticationToken(userDetails); 

     try { 
      return authToken; 
     } catch (Exception e) { 
      logger.error("Authenticate user by token error: ", e); 
     } 
     return authToken; 
    } 

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

     setAuthenticationSuccessHandler(new SimpleUrlAuthenticationSuccessHandler() { 
      @Override 
      public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) 
        throws IOException, ServletException { 
       chain.doFilter(request, response); 
      } 
     }); 
     super.doFilter(req, res, chain); 
    } 

} 

和春季安全配置:

@Configuration 
@EnableWebSecurity 
public class SecurityConfig extends WebSecurityConfigurerAdapter { 

    @Inject 
    AuthenticationManager authenticationManager; 

    @Bean 
    protected AbstractAuthenticationProcessingFilter getTokenAuthFilter() throws Exception { 
     CustomTokenAuthenticationFilter tapf = new CustomTokenAuthenticationFilter("/api/secure-module/admin/**"); 
     tapf.setAuthenticationManager(authenticationManager); 
     return tapf; 
    } 

    @Override 
    protected void configure(HttpSecurity http) throws Exception { 
     super.configure(http); 

     http.csrf().disable().addFilterBefore(getTokenAuthFilter(), AnonymousAuthenticationFilter.class).exceptionHandling() 
       .authenticationEntryPoint(new RestAuthenticationEntryPoint()); 

    } 

} 

它工作正常,但CustomTokenAuthenticationFilter被称为两次,我不知道为什么。有任何想法吗?

回答

2

我发现问题,它是getTokenAuthFilter方法中的@Bean注释。然后我有2注册过滤器链(additionalFilters,originalChain)。