Spring Security遇403 Forbidden且未调用loadUserByUsername()问题
问题诊断与解决方案
核心问题分析
- 认证机制缺失:你的
MyWebSecurityConfig仅定义了授权规则,但未配置任何认证方式(如HTTP Basic、表单登录)。Spring Security无法从请求中提取用户凭证,直接返回403,因此不会触发loadUserByUsername方法。 getAuthorities逻辑错误:该方法创建了包含用户角色的列表,但最终返回空集合——即使认证成功,授权环节也会失败。- 密码加密不一致:
UserEntity中密码通过PasswordService.codePassword加密,但配置的PasswordEncoder是BCryptPasswordEncoder,需确保两者加密逻辑一致。
分步解决方案
1. 修复UserEntity的权限返回逻辑
修改getAuthorities方法,返回包含用户角色的列表:
@Override public Collection<? extends GrantedAuthority> getAuthorities() { List<SimpleGrantedAuthority> list = new ArrayList<>(); list.add(new SimpleGrantedAuthority(role)); return list; // 返回已添加角色的列表,而非空集合 }
2. 添加认证方式配置
根据业务场景选择以下任意一种认证配置:
方式一:HTTP Basic认证(适合API测试)
在configure(HttpSecurity http)中启用HTTP Basic认证:
@Override public void configure(HttpSecurity http) throws Exception { http .cors().and().csrf().disable() .authorizeRequests() .antMatchers("/users", "/users/**").permitAll() .anyRequest().hasAuthority("USER") .and() .httpBasic(); // 启用HTTP Basic认证 }
方式二:表单登录(适合Web应用)
配置表单登录流程:
@Override public void configure(HttpSecurity http) throws Exception { http .cors().and().csrf().disable() .authorizeRequests() .antMatchers("/users", "/users/**").permitAll() .anyRequest().hasAuthority("USER") .and() .formLogin() // 启用表单登录 .loginProcessingUrl("/login") // 指定登录接口路径 .permitAll(); // 允许所有用户访问登录入口 }
3. 统一密码加密逻辑
修改PasswordService,使用配置的BCryptPasswordEncoder加密密码:
@Service public class PasswordService { private final PasswordEncoder passwordEncoder; public PasswordService(PasswordEncoder passwordEncoder) { this.passwordEncoder = passwordEncoder; } public String codePassword(String rawPassword) { return passwordEncoder.encode(rawPassword); } }
4. 调整请求验证配置
- 若使用HTTP Basic认证:在Postman的Authorization选项卡选择
Basic Auth,输入用户的login和密码。 - 若使用表单登录:先发送POST请求到
/login,携带login和password参数获取会话,再访问受保护端点。
验证步骤
- 重启应用确保修改生效。
- 用Postman访问
/shapes的POST端点,携带正确认证凭证。 - 查看控制台输出,确认
loadUserByUsername方法被调用且返回正确的UserEntity。 - 检查响应状态码,应为业务逻辑对应的正常状态(如200)。
内容的提问来源于stack exchange,提问作者Lulex97
相关产品推荐
相关产品推荐

