使用Postman访问接口时持续返回403 Forbidden问题排查求助
问题分析与解决办法
1. 权限字符串不匹配
你的User类中,getAuthorities()方法返回的权限是Role枚举的原始名称(比如USER),但在Security配置里,你用hasAuthority("ROLE_USER")做权限校验——两者前缀不一致,直接导致权限校验失败,返回403。
解决方法二选一:
- 方法一:修改
User类的权限生成逻辑,给权限手动添加ROLE_前缀:
@Override public Collection<? extends GrantedAuthority> getAuthorities() { return roles.stream() .map(e -> new SimpleGrantedAuthority("ROLE_" + e.getName().name())) .toList(); }
- 方法二:把
Security配置里的hasAuthority换成hasRole(hasRole会自动给角色名添加ROLE_前缀):
.requestMatchers( "/absence/**", "/barber/**", "/products/**", "/appointment/**", "/workday/**", "/workyear/**", "/workdefinition/**","/user/create") .hasRole("ADMIN") .requestMatchers("/absence/create", "/absence/get/barber").hasRole("PERSONNEL") .requestMatchers( "/user/delete/{id}", "/user/update", "/products/get", "/barber/get", "/appointment/**").hasRole("USER")
2. 用户密码未加密
创建用户时,你直接保存了明文密码,但Security配置里用BCryptPasswordEncoder做密码验证,导致登录时密码校验失败,根本无法完成认证,自然访问任何需要认证的接口都会返回403。
修改UserServiceImpl的createUser方法,新增密码加密步骤:
@Service @RequiredArgsConstructor public class UserServiceImpl implements UserService, UserDetailsService { // 新增注入BCryptPasswordEncoder private final BCryptPasswordEncoder bCryptPasswordEncoder; // ... 其他注入 @Override @Transactional public UserDto createUser(CreateUserDto createDto) { User user = userMapper.toNewEntity(createDto); if (userRepository.existsByEmail(user.getEmail())) { throw new UniqueValueException(ExceptionMessages.EMAIL_IS_ALREADY_EXIST.getMessage()); } else if (userRepository.existsByLogin(user.getLogin())) { throw new UniqueValueException(ExceptionMessages.LOGIN_IS_ALREADY_EXIST.getMessage()); } // 对密码进行BCrypt加密 user.setPassword(bCryptPasswordEncoder.encode(user.getPassword())); repositoryEventHandler.handleUserBeforeCreate(user); return userMapper.toDto(userRepository.save(user)); } }
3. 删除多余的认证配置代码
Security类中的configure(AuthenticationManager)方法完全多余,而且写法错误,会干扰Spring Security的认证流程,直接删掉这段代码:
// 删除这段无效代码 // protected void configure(AuthenticationManager authenticationManager) throws Exception { // authenticationManager.authenticate((Authentication) daoAuthenticationProvider()); // }
4. 确保Postman用对认证方式
当前配置同时启用了表单登录和HTTP Basic认证,根据你的需求选一种:
- 用HTTP Basic认证:在Postman请求头里加
Authorization: Basic [base64编码的login:明文密码],注意密码是加密前的明文。 - 用表单登录:发送POST请求到默认的
/login路径,表单参数带username(对应你的login字段)和password,登录成功后携带Cookie访问后续接口。
如果测试permitAll()时仍返回403,先清空Postman里的认证信息,再检查是否是前面的密码加密或权限匹配问题导致认证失败。
内容的提问来源于stack exchange,提问作者Ign
相关产品推荐
相关产品推荐

