Spring MVC项目中登录后访问/user/index出现403 Forbidden错误求助
解决Spring Security登录后访问/user/index出现403 Forbidden的问题
嘿,我一眼就瞅出问题所在了——这是Spring Security的角色前缀默认行为搞的鬼!
问题根源
Spring Security的hasRole()方法有个默认特性:它会自动给你传入的角色名称前面加上ROLE_前缀。比如你配置里写的.antMatchers("/user/**").hasRole("USER"),实际它校验的是用户是否拥有ROLE_USER这个权限;但你的CustomUserDetail类里返回的是从数据库直接拿的角色(比如数据库里存的是USER),两者不匹配,自然就触发了403权限拦截。
两种解决方案
方案一:给权限添加ROLE_前缀(推荐,符合Spring Security默认规范)
修改CustomUserDetail的getAuthorities()方法,手动给角色加上前缀:
@Override public Collection<? extends GrantedAuthority> getAuthorities() { // 给数据库中的角色添加ROLE_前缀 SimpleGrantedAuthority authority = new SimpleGrantedAuthority("ROLE_" + user.getRole()); return List.of(authority); }
方案二:改用hasAuthority()替代hasRole()(不修改权限值)
如果你不想改动角色存储的格式,可以把配置里的hasRole()换成hasAuthority()——这个方法不会自动添加前缀,会直接匹配你传入的角色字符串:
@Override protected void configure(HttpSecurity http) throws Exception { http .csrf().disable() .authorizeRequests() // 用hasAuthority替代hasRole .antMatchers("/admin/**").hasAuthority("ADMIN") .antMatchers("/user/**").hasAuthority("USER") .antMatchers("/**").permitAll() .and() .formLogin() .loginPage("/login") .loginProcessingUrl("/login") .defaultSuccessUrl("/user/index"); }
额外验证步骤(可选)
为了确认权限是否正确加载,可以在UserController的index方法里打印用户的权限信息:
@RequestMapping(value = "/index") public String login(Model mdl, Principal principal) { // 打印用户权限,验证是否和预期一致 Authentication authentication = (Authentication) principal; Collection<? extends GrantedAuthority> authorities = authentication.getAuthorities(); authorities.forEach(auth -> System.out.println("当前用户权限:" + auth.getAuthority())); User user = userRepo.getUserByUserName(principal.getName()); mdl.addAttribute("user", user); return "user/user-dashboard"; }
这样你就能直观看到用户实际拥有的权限,确认是否和配置的校验规则匹配。
内容的提问来源于stack exchange,提问作者Faheem azaz Bhanej
相关产品推荐
相关产品推荐

