here is the filter class. Using @Component
annotation because I want to read the value auth.key
from application.yml
file.
@Component
public class StaticKeyAuthFilter implements Filter {
@Value("${auth.key}")
private String authKey;
@Override
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
String authorization = request.getHeader("Authorization");
System.out.println("StaticKeyAuthFilter:" + request.getRequestURI() );
if (authorization == null || !authorization.equals(authKey)) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return;
}
filterChain.doFilter(request, response);
}
}
Next, I am registering it in the config class.
@Configuration
public class ProjectConfig {
@Autowired
private StaticKeyAuthFilter staticKeyAuthFilter;
@Bean
SecurityFilterChain configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeHttpRequests(c -> {
c.anyRequest().permitAll();
});
httpSecurity.addFilterAt(staticKeyAuthFilter, BasicAuthenticationFilter.class);
return httpSecurity.build();
}
}
Now, when I visit any controller I get the following output:
StaticKeyAuthFilter:/category/bb
StaticKeyAuthFilter:/category/bb
As you can see, it is executing twice. what am I doing wrong?
here is the filter class. Using @Component
annotation because I want to read the value auth.key
from application.yml
file.
@Component
public class StaticKeyAuthFilter implements Filter {
@Value("${auth.key}")
private String authKey;
@Override
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
String authorization = request.getHeader("Authorization");
System.out.println("StaticKeyAuthFilter:" + request.getRequestURI() );
if (authorization == null || !authorization.equals(authKey)) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
return;
}
filterChain.doFilter(request, response);
}
}
Next, I am registering it in the config class.
@Configuration
public class ProjectConfig {
@Autowired
private StaticKeyAuthFilter staticKeyAuthFilter;
@Bean
SecurityFilterChain configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.authorizeHttpRequests(c -> {
c.anyRequest().permitAll();
});
httpSecurity.addFilterAt(staticKeyAuthFilter, BasicAuthenticationFilter.class);
return httpSecurity.build();
}
}
Now, when I visit any controller I get the following output:
StaticKeyAuthFilter:/category/bb
StaticKeyAuthFilter:/category/bb
As you can see, it is executing twice. what am I doing wrong?
Share Improve this question edited Mar 25 at 9:22 asgarov1 4,2262 gold badges10 silver badges25 bronze badges asked Mar 25 at 8:52 CodyCody 2,6516 gold badges33 silver badges65 bronze badges 3 |1 Answer
Reset to default 4As soon as you register a Filter
bean as a component, it's already added to the regular filter chain. In addition, you manually added it to the SecurityFilterChain
as well, which causes it to be registered and called twice.
Potential solutions:
You can extend from
OncePerRequestFilter
which guarantees that the filter is only invoked once no matter how many times it's registered within the filter chain. The downside is that it might run it as part of your regular filter chain and not your security filter chain.You can remove the
@Component
annotation and manually create the filter, e.g:@Bean SecurityFilterChain configure(HttpSecurity httpSecurity, @Value("${auth.key}") String authKey) throws Exception { httpSecurity.authorizeHttpRequests(c -> { c.anyRequest().permitAll(); }); httpSecurity.addFilterAt(new StaticKeyAuthFilter(authKey), BasicAuthenticationFilter.class); return httpSecurity.build(); }
You can define a
FilterRegistrationBean
to disable the filter from being automatically added to the filter chain (as suggested by M. Deinum) and so that it's only present in the security filter chain:@Bean public FilterRegistrationBean staticKeyAuth(StaticKeyAuthFilter filter) { FilterRegistrationBean registration = new FilterRegistrationBean(filter); registration.setEnabled(false); return registration; }
OncePerRequestFilter
its now executing only once. Can you please explain the reason behind this behaviour? – Cody Commented Mar 25 at 9:06