You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot+Gradle集成Waffle SSO时首页无法加载、认证信息缺失及Filter未注册问题排查

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 11:18:03