Spring Boot集成Spring Security提交登录返回403错误如何解决
问题解决方案
核心原因1:角色权限前缀不匹配
Spring Security的hasRole()校验规则会自动给传入的角色名拼接ROLE_前缀,你当前的配置和权限构造逻辑不符:
- 配置类中
.antMatchers("/user/**").hasRole("User")实际校验的权限值为ROLE_User CustomUserDetails类的getAuthorities()方法中直接构造SimpleGrantedAuthority(user.getRole()),返回的权限值是User,无ROLE_前缀,导致权限校验失败返回403。
解决方案(三选一即可):
- 方案1:注册用户时添加角色前缀,修改
HomeController的注册逻辑:
user.setRole("ROLE_User");
管理员角色同理设置为ROLE_Admin
- 方案2:修改权限构造逻辑,给权限值自动加前缀,修改
CustomUserDetails的getAuthorities()方法:
SimpleGrantedAuthority simpleGrantedAuthority =new SimpleGrantedAuthority("ROLE_"+user.getRole());
- 方案3:修改安全配置类的校验规则,用不自动加前缀的
hasAuthority()方法替换hasRole():
.antMatchers("/admin/**").hasAuthority("Admin") .antMatchers("/user/**").hasAuthority("User")
核心原因2:账号查询逻辑冲突
你在CustomUserDetails的getUsername()方法返回的是用户邮箱user.getEmail(),但UserDetailsServiceImpl中是调用repo.getUserByUsername(username)根据登录传入的账号查询用户表的username字段:
- 如果你的登录逻辑是让用户填邮箱登录,会导致查询不到用户,校验失败返回403
解决方案:
如果用邮箱作为登录账号,将UserDetailsServiceImpl的查询逻辑修改为根据邮箱查询:
User user=repo.getUserByEmail(username);
核心原因3:表单登录配置缺失
你当前用的是Spring Security默认表单登录配置,如果你使用自定义登录页面,需要补充登录相关配置,修改MyConfig类的configure(HttpSecurity http)方法:
@Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/admin/**").hasRole("Admin") .antMatchers("/user/**").hasRole("User") .antMatchers("/**").permitAll() .and().formLogin() .loginPage("/login") // 替换为你的自定义登录页地址 .loginProcessingUrl("/doLogin") // 替换为你的登录表单提交地址 .usernameParameter("email") // 替换为你登录页用户名输入框的name属性,邮箱登录就填email .passwordParameter("password") // 替换为你登录页密码输入框的name属性 .defaultSuccessUrl("/user/dashboard", true) // 替换为登录成功后的跳转地址 .permitAll() .and().csrf().disable(); }
额外校验点
确认数据库中存储的用户密码是BCrypt加密后的密文,不要存储明文密码,否则密码校验不通过也会返回403。
内容的提问来源于stack exchange,提问作者Sharman Jeurkar
相关产品推荐
相关产品推荐

