请求返回401 Unauthorized,Spring Security用户权限配置求助
首次搭建用户权限逻辑,所有请求均返回401 Unauthorized,此前遇到过403错误,现已完全修改代码,卡在此问题多日,请求排查原因。
相关代码
1. SecurityConfig 安全配置类
@EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter{ @Override protected void configure(HttpSecurity http) throws Exception { http .csrf().disable() .authorizeRequests() .antMatchers("/users/create", "/users/create/**").permitAll() .and() .httpBasic(); } }
2. CreateUserRoleDTO 数据传输对象
@Data @Component public class CreateUserRoleDTO { private Integer idUser; private List<Integer> idsRoles; public CreateUserRoleDTO() { super(); } public CreateUserRoleDTO(Integer idUser, List<Integer> idsRoles) { super(); this.idUser = idUser; this.idsRoles = idsRoles; } public Integer getIdUser() { return idUser; } public void setIdUser(Integer idUser) { this.idUser = idUser; } public List<Integer> getIdsRoles() { return idsRoles; } public void setIdsRoles(List<Integer> idsRoles) { this.idsRoles = idsRoles; } }
3. CreateRoleUserService 业务服务类
@Service public class CreateRoleUserService { @Autowired private UserRepository repo; @Autowired private CreateUserRoleDTO createUserRoleDTO; public Users execute(CreateUserRoleDTO createUserRoleDTO) { Optional<Users> userExists=repo.findById(createUserRoleDTO.getIdUser()); List<Roles> roles=new ArrayList<>(); if (userExists.isEmpty()) { throw new Error("User does not exist"); } roles=createUserRoleDTO.getIdsRoles().stream().map(role -> { return new Roles(role); }).collect(Collectors.toList()); Users user=userExists.get(); user.setRole(roles); repo.save(user); return user; }
4. Users 实体类
@Entity @Table(name="users_table") public class Users implements Serializable{ private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private Integer id; @Column(unique=true) private String login; @Column(unique=true) private String email; private String password; @ManyToMany private List<Roles> role; // 包含对应的getter、setter及构造方法 }
5. data.sql 数据库初始化脚本
INSERT INTO `ROLES`(`ID`, `NAME`) VALUES(1, 'USER'); INSERT INTO `ROLES`(`ID`,`NAME`) VALUES(2, 'ADMIN');
核心排查点
缺失用户认证核心逻辑
当前配置仅开启了HttpBasic认证和部分接口放行,但未配置Spring Security如何从数据库加载用户信息(账号、加密密码、权限角色)。必须实现UserDetailsService接口,或者通过AuthenticationManagerBuilder配置用户来源,让框架能验证请求携带的身份信息。密码未加密处理
Spring Security默认强制密码加密存储,若数据库中存储的是明文密码,会直接导致认证失败返回401。需要配置PasswordEncoder(比如BCryptPasswordEncoder),并且在创建用户时对密码进行加密后再存入数据库。权限规则不完整
当前配置仅指定了/users/create相关接口允许匿名访问,但未明确其他请求需要认证。建议在authorizeRequests()中添加anyRequest().authenticated(),确保非放行接口都需经过认证,同时避免规则歧义。角色关联逻辑错误
在给用户绑定角色时,直接通过new Roles(role)创建对象,该对象未被JPA持久化上下文管理,会导致用户与角色的关联无法正确存入数据库,最终框架无法读取用户权限信息,引发认证/授权失败。正确做法是通过RoleRepository查询已存在的角色实体,再关联给用户。DTO类错误注入
CreateUserRoleDTO被标记为@Component并在服务类中注入,这是错误的——DTO是数据传输对象,不应被Spring管理为Bean,仅需作为方法参数传入即可,虽不直接导致401,但属于代码规范问题。
内容的提问来源于stack exchange,提问作者vitoriac

