This is a simplified example of some code that I'm collaborating on. The filter has been set up with MyCustomFilter
to run after UsernamePasswordAuthenticationFilter.class
.
If I run the server and make a request, just a plain GET request to any endpoint (even one that doesn't exist), the "this filter is being hit"
within MyCustomFilter
prints (twice).
I have put breakpoints on every method within UsernamePasswordAuthenticationFilter.java
, including the constructor, and it is never hit.
How then is my after
filter being called?
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...
}
CodePudding user response:
According to the documentation, the Filter will be called before your requested is routed to the Controller. That is why you see it even when you dont have a method endpoint.
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.
You have 2 other methods (init() and destroy() that you could use to see the life cycle of the filter.
https://tomcat.apache.org/tomcat-5.5-doc/servletapi/javax/servlet/Filter.html
-- Edited ---
I believe you are missing authorizeRequests() and that is why the UsernameAndPasswordAuthenticationFilter is not being triggered.
http.csrf()
.disable()
.authorizeRequests()
.anyRequest().authenticated()
.and()
.addFilterAfter(new CustomFilter()), UsernamePasswordAuthenticationFilter.class)
-- Edited --
It seems you probably dont have a form for Username/Password? and as such the UsernamePasswordAuthenticationFilter is not being called as you need.
The Filters have specific orders, and are chained: If a given Filter does not apply, the chain will skip it and continue to the next filter in the order.
The default orders are:
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.
By default UsernamePasswordAuthenticationFilter is triggered only by accessing /login.