Spring Boot/SEC/JDK11升17:ChannelProcessingFilter替换问题求助
将Spring Boot、Spring Security和JDK从11版本升级至17版本,已完成javax.servlet.http.*到jakarta.servlet.http.*的替换,但编译代码行http.addFilterBefore(new MySecurityFilter(), ChannelProcessingFilter.class);时出现如下错误:
WebSecurityConfig.java:[47,85] incompatible types: java.lang.Class<org.springframework.security.web.access.channel.ChannelProcessingFilter> cannot be converted to java.lang.Class<? extends jakarta.servlet.Filter>
移除该行代码后,内置安全机制会处理所有携带Bearer令牌的/api/**请求,需求是使用自定义的MySecurityFilter自行完成认证,询问Jakarta生态中是否有可替代ChannelProcessingFilter的类,以及具体解决方法。
核心原因
适配JDK17的Spring Security 6.x(对应Spring Boot 3.x)中,ChannelProcessingFilter已被标记为废弃,且它继承的是旧版javax.servlet.Filter,与当前使用的Jakarta EE规范下的jakarta.servlet.Filter存在类型不兼容问题。
具体解决步骤
1. 替换Filter的定位基准类
无需寻找ChannelProcessingFilter的直接替代类,改用Spring Security中兼容Jakarta规范的内置过滤器作为addFilterBefore的基准即可,推荐选择过滤器链中靠前的核心过滤器,确保自定义认证逻辑优先执行:
// 替换原有的ChannelProcessingFilter.class import org.springframework.security.web.context.SecurityContextPersistenceFilter; http.addFilterBefore(new MySecurityFilter(), SecurityContextPersistenceFilter.class);
2. 调整Keycloak配置,确保自定义Filter优先处理Bearer请求
从新旧代码对比来看,需保证IgnoreKeycloakProcessingFilterRequestMatcher的逻辑正确生效:只让Keycloak处理非Bearer请求,携带Bearer令牌的请求完全交由MySecurityFilter处理。结合上述addFilterBefore的配置,可确保自定义Filter的执行顺序在Keycloak相关过滤器之前。
3. 简化自定义Filter实现
新代码中MySecurityFilter继承HttpFilter同时实现Filter属于冗余操作,HttpFilter已实现jakarta.servlet.Filter接口,可简化为:
import jakarta.servlet.http.HttpFilter; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.FilterChain; import java.io.IOException; public class MySecurityFilter extends HttpFilter { @Override protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, jakarta.servlet.ServletException { // 自定义认证逻辑:解析Bearer令牌、验证合法性、设置SecurityContext等 // ... chain.doFilter(request, response); } }
4. 确认依赖版本匹配
确保Spring Boot 3.x、Spring Security 6.x、Keycloak Spring Security Adapter的版本完全适配Jakarta EE规范(例如使用Keycloak 21及以上版本的适配器),避免因依赖版本冲突导致的类型兼容问题。
内容的提问来源于stack exchange,提问作者Jared

