spring-projects / spring-projects/spring-security

Couldn't find FilterChainProxy when using JDK Proxy Beans, but works with CGLIB Proxy Beans

Open
#19,207 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

status: waiting-for-triage type: bug
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.

https://github.com/spring-projects/spring-security/blob/0c54a55ae831c691449d4750abf5bc48cdbb6d96/config/src/main/java/org/springframework/security/config/annotation/web/configuration/WebMvcSecurityConfiguration.java#L305-L321

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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.