AbstractAuthenticationProcessingFilter:doFilter被命中,但`attemptAuthentication`没有

时间:2017-05-18 09:07:49

标签: java spring

我有以下filter定义:

@Component
public class JWTAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

    @Autowired
    private UserDetailsService customUserDetailsService;
    @Autowired
    private AuthenticationManager authenticationManager;

    private static Logger logger = LoggerFactory.getLogger(JWTAuthenticationFilter.class);
    private final static UrlPathHelper urlPathHelper = new UrlPathHelper();


    public JWTAuthenticationFilter() {
        super("/**"); // what should I pass here ? 
        setAuthenticationManager(new NoOpAuthenticationManager());
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
        Authentication authentication = AuthenticationService.getAuthentication((HttpServletRequest) request, customUserDetailsService);
        return authentication;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        filterChain.doFilter(request, response);
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,FilterChain chain, Authentication authentication) throws IOException, ServletException {
        super.successfulAuthentication(request, response, chain, authentication);
        logger.debug("successful authentication while attempting to access " + urlPathHelper.getPathWithinApplication((HttpServletRequest) request));
    }

    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request,
            HttpServletResponse response, AuthenticationException failed)
            throws IOException, ServletException {
        logger.debug("failed authentication while attempting to access " + urlPathHelper.getPathWithinApplication((HttpServletRequest) request));
    }
}
我的Spring安全性的Web配置中的

和以下两个configure方法:

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
        .and()
        .csrf().disable()
        .authorizeRequests()
            .anyRequest().authenticated()
        .and()
        .addFilterBefore(jwtAuthenticationFilter,
            UsernamePasswordAuthenticationFilter.class);
}

@Override
public void configure(WebSecurity web) throws Exception {
    web.ignoring()                
            .antMatchers("/login**", "/signup**");
}

此代码存在以下几个问题:

  1. 在向/login/signup端点发出呼叫时,我不希望过滤器出现,但即使拨打这两个端点,doFilter仍会被点击端点。
  2. attemptAuthenticationsuccessfulAuthenticationunsuccessfulAuthentication没有被点击,但doFilter会被点击。为什么?为什么不调用这些方法?
  3. 这里发生了什么?为什么?

2 个答案:

答案 0 :(得分:0)

试试这个(但未经过测试!):

angular.module('myapp').directive('exportMenuClass',
['$document',
function($document) {
  return {
    restrict: 'A',
    link: function($scope, $element) {
      function removeActiveClass() {
        $element.find('.export-main.active').removeClass('active');
        $element.find('.export-main li.active').removeClass('active');
      }
      $document.on('click', function() {
        removeActiveClass();
      });
      $element.on('click', '.export-main,.export-main li', function(event) {            
        event.stopPropagation();
        event.preventDefault();
        removeActiveClass();
        angular.element(event.currentTarget).addClass('active');
      });
      $element.bind('mouseleave', function() {
        removeActiveClass();
      });
    },
  };
}]
);

在您的配置文件中:

public class JWTAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

    @Autowired
    private UserDetailsService customUserDetailsService;
    @Autowired
    private AuthenticationManager authenticationManager;

    private static Logger logger = LoggerFactory.getLogger(JWTAuthenticationFilter.class);
    private final static UrlPathHelper urlPathHelper = new UrlPathHelper();


    public JWTAuthenticationFilter() {
        super("/**"); // what should I pass here ? 
        setAuthenticationManager(new NoOpAuthenticationManager());
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
        Authentication authentication = AuthenticationService.getAuthentication((HttpServletRequest) request, customUserDetailsService);
        return authentication;
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,FilterChain chain, Authentication authentication) throws IOException, ServletException {
        super.successfulAuthentication(request, response, chain, authentication);
        logger.debug("successful authentication while attempting to access " + urlPathHelper.getPathWithinApplication((HttpServletRequest) request));
    }

    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request,
            HttpServletResponse response, AuthenticationException failed)
            throws IOException, ServletException {
        logger.debug("failed authentication while attempting to access " + urlPathHelper.getPathWithinApplication((HttpServletRequest) request));
    }
}

并添加此内容

@Bean("jwtAuthenticationFilter")
    public LoginRequestFilter jwtAuthenticationFilter(){
        LoginRequestFilter filter = new LoginRequestFilter();
        filter.setAuthenticationManager(authenticationManager);
        filter.setAuthenticationSuccessHandler(successHandler);
        filter.setAuthenticationFailureHandler(failureHandler);
        //filter.setAuthenticationFailureHandler(failureHandler);
        return filter;
    }

答案 1 :(得分:0)

<块引用>
  1. 我不希望过滤器在对 /login 和 /signup 端点进行调用时执行,但即使对这两个端点进行调用,doFilter 仍然会被命中。

虽然我无法解释您编写的两个 configure() 方法之间的关系,但您可以删除 configure(WebSecurity) 并在 configure(HttpSecurity) 中包含所有路径表达式,如下所示:

    .authorizeRequests()
        .antMatchers("/login", "/signup")
        .permitAll()
        .and()
    .authorizeRequests()
        .antMatchers("/**")
        .authenticated();
<块引用>
  1. attemptAuthentication、successfulAuthentication 和 unsuccessfulAuthentication 不会被命中,但 doFilter 会。为什么?为什么不调用这些方法?

AbstractAuthenticationProcessingFilter.doFilter() 通常会调用您覆盖的 attemptAuthentication()(以及其他适当的方法)。通过无条件地将请求传递给过滤器链的其余部分,您的覆盖实现有效地将此过滤器变为“无操作”。