Spring Boot+Gradle集成Waffle SSO时首页无法加载、认证信息缺失及Filter未注册问题排查
我刚仔细看了你碰到的问题——Spring Boot+Gradle集成Waffle做Windows身份认证时,首页跳Whitelabel错误页、请求里没有Session和Principal信息,对比示例项目差了关键的认证上下文。核心问题其实出在Waffle Filter的注册方式不对,导致身份认证流程根本没触发,咱们一步步来解决:
一、核心问题定位
你现在是通过FilterRegistrationBean直接把NegotiateSecurityFilter注册成Servlet容器的Filter,这种方式会让Filter脱离Spring Security的过滤器链管理。Windows身份认证的逻辑没和Spring Security的上下文绑定,自然无法生成Principal、创建Session,请求到了控制器也拿不到认证信息,甚至可能因为认证没通过,请求没正确映射到你的/控制器方法,最终返回Whitelabel错误。
另外你排除了Spring Security的自动配置,但没手动构建安全过滤链,导致认证逻辑完全缺失。
二、具体修改方案
1. 重构Waffle Security配置(纳入Spring Security过滤器链)
把原来的WaffleSecurityConfig改成下面这样,让Waffle的Filter完全纳入Spring Security的管理:
@Configuration @EnableWebSecurity public class WaffleSecurityConfig { // 构建Spring Security过滤链,加入Waffle的认证Filter @Bean public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { http // 所有请求都需要经过身份认证 .authorizeHttpRequests(auth -> auth.anyRequest().authenticated()) // 将Waffle的NegotiateFilter加到Spring Security过滤器链的合适位置 .addFilterBefore(negotiateSecurityFilter(), UsernamePasswordAuthenticationFilter.class) // 禁用CSRF(如果你的业务场景不需要,比如内部系统) .csrf(csrf -> csrf.disable()); return http.build(); } // 定义Waffle的Negotiate认证Filter @Bean public NegotiateSecurityFilter negotiateSecurityFilter() { NegotiateSecurityFilter filter = new NegotiateSecurityFilter(); filter.setProvider(securityFilterProviderCollection()); return filter; } // 配置Waffle的身份认证提供者 @Bean public WindowsAuthProviderImpl windowsAuthProvider() { return new WindowsAuthProviderImpl(); } @Bean public NegotiateSecurityFilterProvider negotiateProvider(WindowsAuthProviderImpl authProvider) { NegotiateSecurityFilterProvider negotiateProvider = new NegotiateSecurityFilterProvider(authProvider); // 禁止访客登录,确保只有域账号能认证 negotiateProvider.setAllowGuestLogin(false); return negotiateProvider; } @Bean public SecurityFilterProviderCollection securityFilterProviderCollection(NegotiateSecurityFilterProvider negotiateProvider) { return new SecurityFilterProviderCollection(negotiateProvider); } }
为什么要这么改?
原来的FilterRegistrationBean是把Filter塞给Servlet容器,和Spring Security的过滤器链完全脱节。现在通过addFilterBefore把Waffle Filter加到Spring Security的认证流程里,认证成功后,Spring Security会自动把Principal存入安全上下文,你在控制器里就能拿到Principal,Session也会自动创建。
2. 删掉无效的Filter注册代码
把原来的waffleFilter()方法(用FilterRegistrationBean注册的那个)完全删掉,现在用Spring Security的过滤器链来管理Waffle Filter了。
3. 检查依赖完整性
确保Gradle里有Spring Security的starter(Waffle的starter可能依赖它,但手动加更保险):
// 加入Spring Security starter implementation 'org.springframework.boot:spring-boot-starter-security' // 保留Waffle的starter implementation 'com.github.waffle:waffle-spring-boot-starter:3.0.0'
另外确认tomcat-embed-jasper依赖存在,它是JSP解析必须的,你的Gradle里已经有了,没问题。
4. 验证JSP路径和配置
确认index.jsp确实放在src/main/webapp/WEB-INF/jsp/目录下,你的application.properties里的视图前缀后缀配置是对的:
spring.mvc.view.prefix=/WEB-INF/jsp/ spring.mvc.view.suffix=.jsp
5. 调试验证
启动项目后访问http://localhost:8080/,域环境下会自动触发Windows认证(非域环境会弹出登录框),然后你的home方法会打印出Remote User和Principal的信息,成功返回index.jsp,不再跳Whitelabel错误页。此时再看请求上下文,会和示例项目一样包含Session、Principal等完整信息。
额外说明
如果你用的是Waffle 3.x的spring-boot-starter,其实也可以用@EnableWaffleSecurity注解简化配置,但手动构建SecurityFilterChain能更灵活地控制认证规则和Filter顺序,适合你现在的场景。
内容来源于stack exchange

