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

Spring自定义登录页始终标记用户为匿名,提交后报403错误

排查Spring Security自定义JSP登录页提交后403 Forbidden问题

结合你描述的情况——用默认登录页能正常登录,换自定义页就出403,而且用户权限没问题,大概率是自定义登录页的表单配置或者Spring Security的CSRF防护没处理到位,咱们一步步来排查:

1. 优先检查CSRF令牌是否正确添加

Spring Security默认开启CSRF防护,自定义登录表单必须携带CSRF令牌,否则提交请求会被直接拦截返回403。这是最常见的原因!

你需要在JSP登录表单里添加这个隐藏字段:

<input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>

完整的表单示例大概是这样:

<form action="${pageContext.request.contextPath}/login" method="post">
    <div>
        <label>用户名:<input type="text" name="username"></label>
    </div>
    <div>
        <label>密码:<input type="password" name="password"></label>
    </div>
    <!-- 必须包含的CSRF令牌 -->
    <input type="hidden" name="${_csrf.parameterName}" value="${_csrf.token}"/>
    <button type="submit">登录</button>
</form>

2. 核对表单的关键配置

  • 提交方式:必须是POST,Spring Security的登录处理接口只接受POST请求,用GET会直接拦截。
  • action路径:要和Spring Security配置里的loginProcessingUrl完全一致。比如你配置的是/login,那表单action就得写${pageContext.request.contextPath}/login(带上项目上下文路径,避免路径错误)。
  • 字段名称:用户名和密码的input标签name属性,默认必须是username和password。如果你在Spring Security里自定义了参数名,要确保和配置里的usernameParameter、passwordParameter对应。

3. 检查Spring Security配置类

  • 确认登录页本身被放行:配置里要加上requestMatchers("/login").permitAll(),确保未登录用户能访问登录页(你能打开登录页的话这个大概率没问题,但还是确认下)。
  • 确认登录处理路径未被拦截:loginProcessingUrl对应的路径(比如/login)Spring Security会自动放行,但如果你的配置里有其他自定义拦截规则,要确保没有覆盖这个放行逻辑。

示例配置类(Java配置):

@Configuration
@EnableWebSecurity
public class SecurityConfig {

    @Autowired
    private UserDetailsService userDetailsService;

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/login", "/static/**").permitAll() // 放行登录页和静态资源
                .anyRequest().authenticated()
            )
            .formLogin(form -> form
                .loginPage("/login") // 指定自定义登录页的访问路径
                .loginProcessingUrl("/login") // 登录请求的处理路径,和表单action一致
                .defaultSuccessUrl("/home", true) // 登录成功后跳转的页面
                .failureUrl("/login?error") // 登录失败后跳转回登录页并携带错误标识
            );
        return http.build();
    }
}

4. 查看详细日志定位问题

你提供的日志片段不够完整,建议把org.springframework.security的日志级别改成DEBUG,这样能看到具体是哪个过滤器拦截了请求:

  • 如果是CsrfFilter拦截,那就是CSRF令牌的问题;
  • 如果是AuthorizationFilter拦截,那可能是权限配置的问题,但结合默认登录页能正常登录,这种情况概率很低。

按照上面的步骤排查,应该就能解决403的问题了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:18:16