什么时候使用 UsernamePasswordAuthenticationFilter?

When is UsernamePasswordAuthenticationFilter used?

这是我正在协作编写的一些代码的简化示例。 UsernamePasswordAuthenticationFilter.classMyCustomFilter到运行已设置过滤器。

如果我 运行 服务器发出请求,只是对任何端点(即使不存在的端点)的普通 GET 请求,MyCustomFilter 内的 "this filter is being hit" 打印(两次)。

我在 UsernamePasswordAuthenticationFilter.java 中的每个方法上都设置了断点,包括构造函数,它永远不会被命中。

我的 after 过滤器如何被调用?

DemoApplication.java

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

}

AuthConfig.java

@Configuration
@EnableWebSecurity
public class AuthConfig extends WebSecurityConfigurerAdapter {

  protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable()
        .addFilterAfter(new MyCustomFilter(), UsernamePasswordAuthenticationFilter.class);
  }

}

MyCustomFilter.java

public class MyCustomFilter implements Filter {
    
  @Override
  public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
      throws IOException, ServletException {
    System.out.println("this filter is being hit");
    chain.doFilter(request, response);
  }
     // other overrides...
}

根据文档,过滤器将在您的请求路由到控制器之前被调用。这就是为什么即使您没有方法端点也会看到它的原因。

public interface Filter

A filter is an object that performs filtering tasks on either the request to a resource (a servlet or static content), or on the response from a resource, or both.

Filters perform filtering in the doFilter method. Every Filter has access to a FilterConfig object from which it can obtain its initialization parameters, a reference to the ServletContext which it can use, for example, to load resources needed for filtering tasks.


  void  doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
  

The doFilter method of the Filter is called by the container each time a request/response pair is passed through the chain due to a client request for a resource at the end of the chain.

您还有 2 个其他方法(init() 和 destroy())可用于查看过滤器的生命周期。

https://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/Filter.html

-- 已编辑 ---

我相信您缺少 authorizeRequests(),这就是未触发 UsernameAndPasswordAuthenticationFilter 的原因。

        http.csrf()
        .disable()
        .authorizeRequests()
        .anyRequest().authenticated()
        .and()
        .addFilterAfter(new CustomFilter()), UsernamePasswordAuthenticationFilter.class)

-- 已编辑 --

您似乎没有 Username/Password 的表格?因此,未按需要调用 UsernamePasswordAuthenticationFilter。

过滤器有特定的顺序,并且是链接的:如果给定的过滤器不适用,链将跳过它并继续顺序中的下一个过滤器。

默认订单为:

ChannelProcessingFilter
ConcurrentSessionFilter
SecurityContextPersistenceFilter
LogoutFilter
X509AuthenticationFilter
AbstractPreAuthenticatedProcessingFilter
CasAuthenticationFilter
UsernamePasswordAuthenticationFilter
<---- Your CustomFilter Here --->
ConcurrentSessionFilter
OpenIDAuthenticationFilter
DefaultLoginPageGeneratingFilter
ConcurrentSessionFilter
DigestAuthenticationFilter
BasicAuthenticationFilter
RequestCacheAwareFilter
SecurityContextHolderAwareRequestFilter
JaasApiIntegrationFilter
RememberMeAuthenticationFilter
AnonymousAuthenticationFilter
SessionManagementFilter
ExceptionTranslationFilter
FilterSecurityInterceptor
SwitchUserFilter

public class UsernamePasswordAuthenticationFilter
extends AbstractAuthenticationProcessingFilter

Processes an authentication form submission. Called AuthenticationProcessingFilter prior to Spring Security 3.0.

Login forms must present two parameters to this filter: a username and password. The default parameter names to use are contained in the

static fields SPRING_SECURITY_FORM_USERNAME_KEY and SPRING_SECURITY_FORM_PASSWORD_KEY. The parameter names can also be changed by setting the usernameParameter and passwordParameter properties.

This filter by default responds to the URL /login.

默认情况下,UsernamePasswordAuthenticationFilter 仅在访问 /login 时触发。