http
.csrf(AbstractHttpConfigurer::disable)
.cors(AbstractHttpConfigurer::disable)
.addFilterAfter(CoustomAuthCheckFilter, UsernamePasswordAuthenticationFilter.class)
...
I used AuthenticationFilter.class
in the addFilterAfter method and encountered an error. After changing it to UsernamePasswordAuthenticationFilter.class
, it worked. Why does the compiler not throw an error when using AuthenticationFilter.class
even though it's not a concrete filter that is typically used directly?"
try
http
.csrf(AbstractHttpConfigurer::disable)
.cors(AbstractHttpConfigurer::disable)
.addFilterAfter(CoustomAuthCheckFilter, AuthenticationFilter.class)
I expecting server start. but
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration': Unsatisfied dependency expressed through method 'setFilterChains' parameter 0: Error creating bean with name 'filterChain' defined in class path resource [com/wincubemkt/mediagw/global/config/SecurityConfig.class]: Failed to instantiate [org.springframework.security.web.SecurityFilterChain]: Factory method 'filterChain' threw exception with message: The Filter class org.springframework.security.web.authentication.AuthenticationFilter does not have a registered order
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.resolveMethodArguments(AutowiredAnnotationBeanPostProcessor.java:895) ~[spring-beans-6.1.11.jar:6.1.11]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:848) ~[spring-beans-6.1.11.jar:6.1.11]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:145) ~[spring-beans-6.1.11.jar:6.1.11]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:508) ~[spring-beans-6.1.11.jar:6.1.11]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1439) ~[spring-beans-6.1.11.jar:6.1.11]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:599) ~[spring-beans-6.1.11.jar:6.1.11]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522) ~[spring-beans-6.1.11.jar:6.1.11]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337) ~[spring-beans-6.1.11.jar:6.1.11]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.1.11.jar:6.1.11]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335) ~[spring-beans-6.1.11.jar:6.1.11]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.1.11.jar:6.1.11]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:975) ~[spring-beans-6.1.11.jar:6.1.11]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:971) ~[spring-context-6.1.11.jar:6.1.11]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:625) ~[spring-context-6.1.11.jar:6.1.11]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.3.2.jar:3.3.2]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[spring-boot-3.3.2.jar:3.3.2]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456) ~[spring-boot-3.3.2.jar:3.3.2]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:335) ~[spring-boot-3.3.2.jar:3.3.2]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363) ~[spring-boot-3.3.2.jar:3.3.2]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1352) ~[spring-boot-3.3.2.jar:3.3.2]
at com.wincubemkt.mediagw.MEDIAGWApplication.main(MEDIAGWApplication.java:11) ~[main/:na]
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:580) ~[na:na]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:50) ~[spring-boot-devtools-3.3.2.jar:3.3.2]
I encountered the following error when using AuthenticationFilter.class
The error message says:
org.springframework.security.web.authentication.AuthenticationFilter does not have a registered order
which kind of tells you what the issue is. In Spring for you to use the methods:
addFilterBefore()
addFilterAfter()
the second parameter has to have an Order set by Spring inside of FilterOrderRegistration. Here is a snippet out of FilterOrderRegistration
:
//...
put(X509AuthenticationFilter.class, order.next());
put(AbstractPreAuthenticatedProcessingFilter.class, order.next());
this.filterToOrder.put("org.springframework.security.cas.web.CasAuthenticationFilter", order.next());
this.filterToOrder.put("org.springframework.security.oauth2.client.web.OAuth2LoginAuthenticationFilter", order.next());
this.filterToOrder.put("org.springframework.security.saml2.provider.service.web.authentication.Saml2WebSsoAuthenticationFilter", order.next());
put(UsernamePasswordAuthenticationFilter.class, order.next());
order.next(); // gh-8105
//...
as you can see among other classes it sets an order for UsernamePasswordAuthenticationFilter
. If you look at the complete code however, it doesn't register order for AuthenticationFilter
(for whatever reason).
When you call either addFilterBefore
or addFilterAfter
they both internally refer to the addFilterAtOffsetOf
method which then throws the exception you are facing:
@Override
public HttpSecurity addFilterAfter(Filter filter, Class<? extends Filter> afterFilter) {
return addFilterAtOffsetOf(filter, 1, afterFilter);
}
@Override
public HttpSecurity addFilterBefore(Filter filter, Class<? extends Filter> beforeFilter) {
return addFilterAtOffsetOf(filter, -1, beforeFilter);
}
private HttpSecurity addFilterAtOffsetOf(Filter filter, int offset, Class<? extends Filter> registeredFilter) {
Integer registeredFilterOrder = this.filterOrders.getOrder(registeredFilter);
if (registeredFilterOrder == null) {
throw new IllegalArgumentException(
"The Filter class " + registeredFilter.getName() + " does not have a registered order");
}
int order = registeredFilterOrder + offset;
this.filters.add(new OrderedFilter(filter, order));
this.filterOrders.put(filter.getClass(), order);
return this;
}
Which is why as of this writing (Spring Security 6.3.1) you are limited to the following Filters that you can reference in addFilterAfter
since these are the only ones that are registered in FilterOrderRegistration
:
- DisableEncodeUrlFilter.class
- ForceEagerSessionCreationFilter.class
- ChannelProcessingFilter.class
- WebAsyncManagerIntegrationFilter.class
- SecurityContextHolderFilter.class
- SecurityContextPersistenceFilter.class
- HeaderWriterFilter.class
- CorsFilter.class
- CsrfFilter.class
- LogoutFilter.class
- X509AuthenticationFilter.class
- AbstractPreAuthenticatedProcessingFilter.class
- UsernamePasswordAuthenticationFilter.class
- DefaultLoginPageGeneratingFilter.class
- DefaultLogoutPageGeneratingFilter.class
- ConcurrentSessionFilter.class
- DigestAuthenticationFilter.class
- BasicAuthenticationFilter.class
- RequestCacheAwareFilter.class
- SecurityContextHolderAwareRequestFilter.class
- JaasApiIntegrationFilter.class
- RememberMeAuthenticationFilter.class
- AnonymousAuthenticationFilter.class
- SessionManagementFilter.class
- ExceptionTranslationFilter.class
- FilterSecurityInterceptor.class
- AuthorizationFilter.class
- SwitchUserFilter.class