【问题标题】:Spring Security: AuthenticationProcessingFilter is called twiceSpring Security:AuthenticationProcessingFilter 被调用两次
【发布时间】:2014-12-15 03:41:41
【问题描述】:

我尝试在 RESTful 应用程序中通过令牌授权配置 Spring Security。

我的 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);
    }

}

和 Spring Security 配置:

@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 被调用了两次,我不知道为什么。有什么想法吗?

【问题讨论】:

    标签: java spring spring-security restful-authentication


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      当过滤器生成异常导致重定向到 /error 并再次触发过滤器时,我也有类似的经历。我必须指定

      @Override
      public void configure(WebSecurity web) throws Exception {
          // ignoring security for /error
          web.ignoring().antMatchers("/error");
      }
      

      【讨论】:

        猜你喜欢
        • 2013-12-31
        • 2014-09-02
        • 2011-12-15
        • 1970-01-01
        • 2017-02-15
        • 1970-01-01
        • 2016-04-01
        • 2012-05-05
        • 2017-01-19
        相关资源
        最近更新 更多