spring-projects / spring-projects/spring-security
Couldn't find FilterChainProxy when using JDK Proxy Beans, but works with CGLIB Proxy Beans
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 9.6k
- Forks
- 6.3k
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 52
Description
Describe the bug
Long story short, we are using Spring Security on a Wildfly server, and when upgrading to Spring Security 6.5.9 (from Spring Security 5), we started getting errors along the lines of this one.
Caused by: java.lang.IllegalStateException: Couldn't find FilterChainProxy in [org.springframework.web.servlet.handler.HandlerMappingIntrospector$$Lambda/0x000001968bf54468@3d6a189b, FilterChainProxy[Filter Chains: null]]
at deployment.MY_WAR_FILE.war//org.springframework.security.config.annotation.web.configuration.WebMvcSecurityConfiguration$CompositeFilterChainProxy.findFilterChainProxy(WebMvcSecurityConfiguration.java:320)
at deployment.MY_WAR_FILE.war//org.springframework.security.config.annotation.web.configuration.WebMvcSecurityConfiguration$CompositeFilterChainProxy.<init>(WebMvcSecurityConfiguration.java:229)
at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:62)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:502)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)
at deployment.MY_WAR_FILE.war//org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:210)
... 43 more
Here is the method in Spring Security that is throwing the exception -- Lines 305-321 in WebMvcSecurityConfiguration.java.
Notice that it is using instanceof to check if the provided bean is a FilterChainProxy?
After attaching a debugger to our server, we found that it failed because our FilterChainProxy bean was a JDK Proxy, as opposed to a CGLIB Proxy!
JDK Dynamic Proxies can only be used with instanceof when comparing against an interface, not a class! And since FilterChainProxy is a class, then calling instanceof on our JDK Proxy fails every time!
Workaround
We managed to workaround this by simply turning our JDK Proxy beans into CGLIB Proxy Beans.
We did this by adding proxyTargetClass to our @EnableMethodSecurity annotation, like so.
OLD WAY -- @EnableMethodSecurity
NEW WAY -- @EnableMethodSecurity(proxyTargetClass = true)
Obviously, doing this has SWEEPING RAMIFICATIONS, as you have turned ALL OF YOUR BEANS to CGLIB style. That's not nothing lol. But for us, with a looming deadline and a not-too-complex codebase and security setup, it served us as a workaround.
To Reproduce
Special thanks to @udaykt for helping to create a reproducer!
git clone https://github.com/udaykt/spring-security-jdk-proxy-reproducer
cd spring-security-jdk-proxy-reproducer
mvn spring-boot:run
Expected behavior
Application should start successfully regardless of proxy strategy used for FilterChainProxy. At the very least, I would expect to be warned in the logs and/or the documentation for using JDK proxies.
Sample
https://github.com/udaykt/spring-security-jdk-proxy-reproducer
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Run the linked spring-security-jdk-proxy-reproducer with mvn spring-boot:run to reproduce the startup failure. Then inspect WebMvcSecurityConfiguration.java lines 305-321 and how FilterChainProxy is discovered when JDK proxies are used. Done means the application starts successfully with the JDK proxy strategy, without requiring the broad CGLIB workaround.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring
- Domain
- backend, security
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100