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

Spring Boot中Fetch提交/policy-holder端点重定向登录页问题排查

问题分析与解决方案

一、/policy-holder端点permitAll仍重定向到登录页的问题

原因

Spring Security默认开启CSRF保护,对于POST、PUT等非GET请求,即便配置了permitAll(),也需要携带有效的CSRF Token才能通过校验。你的前端Fetch请求未携带CSRF Token,导致请求被拦截,触发重定向到登录页的默认行为。

另外需确认端点路径匹配:Controller是@PostMapping("/policy-holder"),Security配置里的requestMatchers("/policy-holder")匹配所有HTTP方法,路径匹配无问题,核心问题仍为CSRF拦截。

解决步骤

  1. 前端请求添加CSRF Token
    从页面Cookie中获取Spring Security默认存储的XSRF-TOKEN,在Fetch请求headers中添加X-XSRF-TOKEN字段:

    // 从Cookie提取CSRF Token
    function getCsrfToken() {
        const value = `; ${document.cookie}`;
        const parts = value.split(`; XSRF-TOKEN=`);
        if (parts.length === 2) return parts.pop().split(';').shift();
    }
    
    fetch('/policy-holder', {
        method: 'POST',
        credentials: 'include',
        headers: {
            'Content-Type': 'application/json',
            'X-XSRF-TOKEN': getCsrfToken()
        },
        body: JSON.stringify(extractedData),
    })
    .then(response => response.json())
    .then(data => console.log('POST请求响应:', data))
    .catch(error => console.error('请求出错:', error));
    
  2. (可选)忽略该端点的CSRF检查
    若该端点为公开API且无需CSRF保护,可在Security配置中添加忽略规则:

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
                .csrf(csrf -> csrf
                        .ignoringRequestMatchers("/policy-holder")
                )
                .authorizeHttpRequests((authorize) ->
                        authorize.requestMatchers("/register/**","/css/**","/js/**", "/images/**").permitAll()
                                .requestMatchers("/", "/index", "/policy-holder").permitAll()
                                .requestMatchers("/users","/send").hasRole("ADMIN")
                                .anyRequest().authenticated()
                )
                .formLogin(form -> form
                        .loginPage("/login")
                        .loginProcessingUrl("/login")
                        .defaultSuccessUrl("/users")
                        .permitAll()
                )
                .logout(logout -> logout
                        .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                        .permitAll()
                );
    
        return http.build();
    }
    

二、Basic Auth与Cookie Auth(Form Login)共存的问题

原因

Spring Security默认不会同时启用Form Login和Basic Auth,需显式配置两者,并处理认证过滤器优先级,避免逻辑冲突。

解决步骤

在Security配置中同时启用formLogin()和httpBasic(),可按需设置Basic Auth的Realm信息:

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http
            .csrf(csrf -> csrf
                    .ignoringRequestMatchers("/policy-holder")
            )
            .authorizeHttpRequests((authorize) ->
                    authorize.requestMatchers("/register/**","/css/**","/js/**", "/images/**").permitAll()
                            .requestMatchers("/", "/index", "/policy-holder").permitAll()
                            .requestMatchers("/users","/send").hasRole("ADMIN")
                            .anyRequest().authenticated()
            )
            .formLogin(form -> form
                    .loginPage("/login")
                    .loginProcessingUrl("/login")
                    .defaultSuccessUrl("/users")
                    .permitAll()
            )
            .httpBasic(basic -> basic
                    .realmName("ApplicationRealm")
            )
            .logout(logout -> logout
                    .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
                    .permitAll()
            );

    return http.build();
}

注意事项

  • 两种认证方式可独立使用:
    • Cookie Auth:登录后携带Session Cookie,请求保持credentials: 'include'即可。
    • Basic Auth:在请求headers中添加Authorization: Basic <base64编码的用户名:密码>。
  • 若需细分端点认证方式,可通过requestMatchers()结合自定义过滤器或认证管理器实现。

内容的提问来源于stack exchange,提问作者uhexos

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 20:57:12