Spring Security所有受保护路由返回403问题排查求助
以下是针对你遇到的认证后访问/protected接口返回403的常见排查方向和解决方法:
1. 检查UserDetails的权限集合是否为空
你的UsernamePasswordAuthenticationToken构造时传入了userDetails.getAuthorities(),如果这个方法返回空集合,Spring Security会判定当前用户无任何权限,即便认证通过也会返回403。
- 解决方法:
确保自定义UserDetails实现类中,getAuthorities()方法返回非空权限集合,哪怕是基础权限(例如List.of(new SimpleGrantedAuthority("ROLE_USER")))。
2. 确认CSRF是否完全禁用
你的SecurityFilterChain配置中,csrf()仅做链式调用但未禁用。Spring Security默认开启CSRF保护,对于无状态的JWT请求无需CSRF,未禁用会导致请求被拦截返回403。
- 修改SecurityFilterChain配置:
httpSecurity .csrf(csrf -> csrf.disable()) // 明确禁用CSRF .authorizeHttpRequests() .requestMatchers("/api/v1/auth/**", "/api/v1/test-controller") .permitAll() .anyRequest() .authenticated() .and() .sessionManagement() .sessionCreationPolicy(SessionCreationPolicy.STATELESS) .and() .authenticationProvider(authentificationProvider) .addFilterBefore(tokenAuthentificationFilter, UsernamePasswordAuthenticationFilter.class);
3. 验证JWT令牌的有效性逻辑
检查jwtService.isTokenValid(authToken, userDetails)方法是否存在逻辑错误,比如:
未正确验证令牌的签名或过期时间
未对比令牌中的用户信息与数据库中用户信息是否一致
令牌已被标记为无效(如黑名单机制未正确处理)
解决方法:
打印日志或调试该方法,确认其在令牌有效时返回true,确保Authentication对象能被正确设置到SecurityContextHolder中。
4. 确认请求路径匹配规则
检查/protected接口的路径是否被正确覆盖到.anyRequest().authenticated()规则中。如果/protected的路径前缀不在规则范围内,会出现权限判断异常。
- 解决方法:
可临时添加显式路径匹配规则测试:
将其放在.requestMatchers("/protected").authenticated().anyRequest().authenticated()之前,确认是否能正常访问。
5. 检查AuthenticationProvider的实现
如果你的authentificationProvider是自定义实现,需确认其authenticate()方法返回的Authentication对象包含正确的权限信息,无逻辑错误导致认证后权限丢失。
- 解决方法:
调试AuthenticationProvider的authenticate方法,确认返回的Authentication对象的getAuthorities()非空且正确。
调试技巧
在TokenAuthentificationFilter的doFilterInternal方法中添加日志,打印以下信息确认每一步执行情况:
System.out.println("提取到的用户邮箱: " + userEmail); System.out.println("令牌是否有效: " + jwtService.isTokenValid(authToken, userDetails)); System.out.println("Authentication是否设置成功: " + SecurityContextHolder.getContext().getAuthentication());
内容的提问来源于stack exchange,提问作者Louisnot

